feat(patch): waze integration patch

This commit is contained in:
Se7en-dev
2026-07-02 15:49:18 +02:00
parent cbf04d9fa7
commit 523f0a342b
9 changed files with 461 additions and 1 deletions
@@ -6,6 +6,7 @@ import com.meowarex.rlmobile.patcher.steps.StepGroup
import com.meowarex.rlmobile.patcher.steps.base.Step
import com.meowarex.rlmobile.patcher.steps.download.CopyDependenciesStep
import com.meowarex.rlmobile.patcher.util.ManifestPatcher
import com.meowarex.rlmobile.ui.screens.patchopts.KnownPatch
import com.meowarex.rlmobile.ui.screens.patchopts.PatchOptions
import com.github.diamondminer88.zip.ZipReader
import com.github.diamondminer88.zip.ZipWriter
@@ -26,11 +27,15 @@ class PatchManifestStep(private val options: PatchOptions) : Step() {
?: throw IllegalArgumentException("No manifest found in APK")
container.log("Patching manifest")
val enableWazeIntegration =
options.patchStates[KnownPatch.WazeIntegration.name] ?: KnownPatch.WazeIntegration.default.isEnabled
val patchedManifest = ManifestPatcher.patchManifest(
manifestBytes = manifest,
packageName = options.packageName,
appName = options.appName,
debuggable = options.debuggable,
enableWazeIntegration = enableWazeIntegration,
)
container.log("Repacking apk with patched manifest")
@@ -18,12 +18,16 @@ object ManifestPatcher {
private const val IS_SPLIT_REQUIRED = "isSplitRequired"
private const val REQUIRED_SPLIT_TYPES = "requiredSplitTypes"
private const val SPLIT_TYPES = "splitTypes"
private const val WAZE_PACKAGE = "com.waze"
private const val WAZE_INIT_RECEIVER = "radiant.WazeInitReceiver"
private const val WAZE_ACTION_INIT = "com.waze.sdk.audio.ACTION_INIT"
fun patchManifest(
manifestBytes: ByteArray,
packageName: String,
appName: String,
debuggable: Boolean,
enableWazeIntegration: Boolean,
): ByteArray {
// Extract original package name to rewrite every reference to it
// (permissions, provider authorities) to the new packageName.
@@ -84,6 +88,49 @@ object ManifestPatcher {
}
return when (name) {
"queries" -> object : NodeVisitor(nv) {
private var hasWazePackage = false
override fun child(ns: String?, name: String): NodeVisitor {
val visitor = super.child(ns, name)
return if (enableWazeIntegration && name == "package") {
object : NodeVisitor(visitor) {
override fun attr(
ns: String?,
name: String?,
resourceId: Int,
type: Int,
value: Any?,
) {
if (name == "name" && value == WAZE_PACKAGE) {
hasWazePackage = true
}
super.attr(ns, name, resourceId, type, value)
}
}
} else {
visitor
}
}
override fun end() {
if (enableWazeIntegration && !hasWazePackage) {
super.child(null, "package").apply {
attr(
ANDROID_NAMESPACE,
"name",
android.R.attr.name,
TYPE_STRING,
WAZE_PACKAGE,
)
end()
}
}
super.end()
}
}
"uses-permission" -> object : NodeVisitor(nv) {
override fun attr(ns: String?, name: String?, resourceId: Int, type: Int, value: Any?) {
if (name != "maxSdkVersion") {
@@ -132,6 +179,7 @@ object ManifestPatcher {
private var addUseEmbeddedDex = true
private var addExtractNativeLibs = true
private var addMetadata = true
private var hasWazeInitReceiver = false
override fun attr(ns: String?, name: String, resourceId: Int, type: Int, value: Any?) {
if (name == REQUEST_LEGACY_EXTERNAL_STORAGE) addLegacyStorage = false
@@ -161,6 +209,22 @@ object ManifestPatcher {
return when (name) {
"activity" -> ReplaceAttrsVisitor(visitor, mapOf("label" to appName))
"receiver" -> object : NodeVisitor(visitor) {
override fun attr(
ns: String?,
name: String,
resourceId: Int,
type: Int,
value: Any?
) {
if (name == "name" && value == WAZE_INIT_RECEIVER) {
hasWazeInitReceiver = true
}
super.attr(ns, name, resourceId, type, value)
}
}
"provider" -> object : NodeVisitor(visitor) {
override fun attr(
ns: String?,
@@ -219,6 +283,39 @@ object ManifestPatcher {
0
)
if (enableWazeIntegration && !hasWazeInitReceiver) {
super.child(null, "receiver").apply {
attr(
ANDROID_NAMESPACE,
"name",
android.R.attr.name,
TYPE_STRING,
WAZE_INIT_RECEIVER,
)
attr(
ANDROID_NAMESPACE,
"exported",
android.R.attr.exported,
TYPE_INT_BOOLEAN,
1,
)
child(null, "intent-filter").apply {
child(null, "action").apply {
attr(
ANDROID_NAMESPACE,
"name",
android.R.attr.name,
TYPE_STRING,
WAZE_ACTION_INIT,
)
end()
}
end()
}
end()
}
}
super.end()
}
}
@@ -130,6 +130,17 @@ enum class KnownPatch(
descRes = R.string.patch_debug_menu_unlock_desc,
default = Disabled,
),
WazeIntegration(
order = 90,
fileNames = listOf("waze-media-browser.patch"),
extensionFiles = listOf(
"radiant/WazeInitReceiver.smali",
"radiant/WazeServiceConnection.smali",
),
titleRes = R.string.patch_waze_integration_title,
descRes = R.string.patch_waze_integration_desc,
default = Disabled,
),
LyricsProgressPill(
order = 40,
fileNames = listOf(
@@ -286,6 +286,8 @@
<string
name="patch_debug_menu_unlock_desc"
>Reveals TIDAL\'s hidden Debug Menu in Settings. (Unlocks Feature Flags &amp; the legacy Debug Options)</string>
<string name="patch_waze_integration_title">Waze Integration</string>
<string name="patch_waze_integration_desc">Control TIDAL playback from the Waze app</string>
<string name="patch_enable_legacy_ui_title">Enable Legacy UI</string>
<string
name="patch_enable_legacy_ui_desc"