feat(YouTube): add Hook YouTube Music actions patch

This commit is contained in:
inotia00
2024-09-23 22:24:13 +09:00
parent 9bd51f7df8
commit ce5561732e
8 changed files with 199 additions and 16 deletions

View File

@ -176,7 +176,7 @@ object DownloadActionsPatch : BaseBytecodePatch(
SettingsPatch.addPreference(
arrayOf(
"PREFERENCE_SCREEN: GENERAL",
"PREFERENCE_CATEGORY: GENERAL_EXPERIMENTAL_FLAGS",
"SETTINGS: HOOK_BUTTONS",
"SETTINGS: HOOK_DOWNLOAD_ACTIONS"
)
)

View File

@ -0,0 +1,108 @@
package app.revanced.patches.youtube.general.music
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
import app.revanced.patches.youtube.general.music.fingerprints.AppDeepLinkFingerprint
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.gms.GmsCoreSupportResourcePatch.PackageNameYouTubeMusic
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_PATH
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addEntryValues
import app.revanced.patches.youtube.utils.settings.SettingsBytecodePatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.patch.BaseBytecodePatch
import app.revanced.util.resultOrThrow
import app.revanced.util.valueOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
import java.io.Closeable
@Suppress("unused")
object YouTubeMusicActionsPatch : BaseBytecodePatch(
name = "Hook YouTube Music actions",
description = "Adds support for opening music in RVX Music using the in-app YouTube Music button.",
dependencies = setOf(SettingsPatch::class),
compatiblePackages = COMPATIBLE_PACKAGE,
fingerprints = setOf(AppDeepLinkFingerprint)
), Closeable {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"$GENERAL_PATH/YouTubeMusicActionsPatch;"
override fun execute(context: BytecodeContext) {
AppDeepLinkFingerprint.resultOrThrow().let {
it.mutableMethod.apply {
val packageNameIndex = it.scanResult.patternScanResult!!.startIndex
val packageNameField = getInstruction<ReferenceInstruction>(packageNameIndex).reference.toString()
implementation!!.instructions
.withIndex()
.filter { (_, instruction) ->
instruction.opcode == Opcode.IGET_OBJECT &&
instruction.getReference<FieldReference>()?.toString() == packageNameField
}
.map { (index, _) -> index }
.reversed()
.forEach { index ->
val register = getInstruction<TwoRegisterInstruction>(index).registerA
addInstructions(
index + 1, """
invoke-static {v$register}, $INTEGRATIONS_CLASS_DESCRIPTOR->overridePackageName(Ljava/lang/String;)Ljava/lang/String;
move-result-object v$register
"""
)
}
}
}
/**
* Add settings
*/
SettingsPatch.addPreference(
arrayOf(
"PREFERENCE_SCREEN: GENERAL",
"SETTINGS: HOOK_BUTTONS",
"SETTINGS: HOOK_YOUTUBE_MUSIC_ACTIONS"
)
)
SettingsPatch.updatePatchStatus(this)
}
override fun close() {
if (SettingsPatch.containsPatch("GmsCore support")) {
SettingsPatch.contexts.addEntryValues(
"revanced_third_party_youtube_music_label",
"RVX Music"
)
SettingsPatch.contexts.addEntryValues(
"revanced_third_party_youtube_music_package_name",
PackageNameYouTubeMusic.valueOrThrow()
)
SettingsBytecodePatch.contexts
.findClass { classDef -> classDef.type == INTEGRATIONS_CLASS_DESCRIPTOR }
?.mutableClass
?.methods
?.first { method -> method.name == "getRVXMusicPackageName" }
?.apply {
val replaceIndex = indexOfFirstInstructionOrThrow(Opcode.CONST_STRING)
val replaceRegister =
getInstruction<OneRegisterInstruction>(replaceIndex).registerA
replaceInstruction(
replaceIndex,
"const-string v$replaceRegister, \"${PackageNameYouTubeMusic.valueOrThrow()}\""
)
}
}
}
}

View File

@ -0,0 +1,27 @@
package app.revanced.patches.youtube.general.music.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
internal object AppDeepLinkFingerprint : MethodFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L", "Ljava/util/Map;"),
opcodes = listOf(
Opcode.IGET_OBJECT,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.CONST_STRING,
),
strings = listOf("android.intent.action.VIEW"),
customFingerprint = { methodDef, _ ->
methodDef.indexOfFirstInstruction {
getReference<FieldReference>()?.name == "appDeepLinkEndpoint"
} >= 0
}
)

View File

@ -318,6 +318,7 @@ object VisualPreferencesIconsPatch : BaseResourcePatch(
"revanced_preference_screen_feed_flyout_menu",
"revanced_preference_screen_fullscreen",
"revanced_preference_screen_haptic_feedback",
"revanced_preference_screen_hook_buttons",
"revanced_preference_screen_import_export",
"revanced_preference_screen_miniplayer",
"revanced_preference_screen_navigation_buttons",
@ -430,6 +431,7 @@ object VisualPreferencesIconsPatch : BaseResourcePatch(
"revanced_preference_screen_comments" -> "revanced_hide_quick_actions_comment_button_icon"
"revanced_preference_screen_feed_flyout_menu" -> "revanced_preference_screen_player_flyout_menu_icon"
"revanced_preference_screen_haptic_feedback" -> "revanced_enable_swipe_haptic_feedback_icon"
"revanced_preference_screen_hook_buttons" -> "revanced_preference_screen_import_export_icon"
"revanced_preference_screen_miniplayer" -> "offline_key_icon"
"revanced_preference_screen_patch_information" -> "about_key_icon"
"revanced_preference_screen_shorts_player" -> "revanced_preference_screen_shorts_icon"

View File

@ -316,7 +316,13 @@ object SettingsPatch : BaseResourcePatch(
updatePatchStatus(patch.name!!)
}
private val patchList = ArrayList<String>()
internal fun updatePatchStatus(patchName: String) {
patchList.add(patchName)
contexts.updatePatchStatus(patchName)
}
internal fun containsPatch(patchName: String) =
patchList.contains(patchName)
}