From caf3d70c30bc440923c0e76e7331010905f6e729 Mon Sep 17 00:00:00 2001 From: johnconner122 <107796137+johnconner122@users.noreply.github.com> Date: Sun, 22 Jan 2023 19:43:55 +0500 Subject: [PATCH] feat(youtube): `open-links-externally` patch (#1524) Signed-off-by: oSumAtrIX Co-authored-by: oSumAtrIX --- .../OpenLinksExternallyCompatibility.kt | 13 ++++ .../BindSessionServiceFingerprint.kt | 17 +++++ .../GetCustomTabPackageNameFingerprint.kt | 18 +++++ .../InitializeCustomTabSupportFingerprint.kt | 18 +++++ .../open/patch/OpenLinksExternallyPatch.kt | 65 +++++++++++++++++++ 5 files changed, 131 insertions(+) create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/BindSessionServiceFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/GetCustomTabPackageNameFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/InitializeCustomTabSupportFingerprint.kt create mode 100644 src/main/kotlin/app/revanced/patches/youtube/misc/links/open/patch/OpenLinksExternallyPatch.kt diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt new file mode 100644 index 00000000..6818f9e8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/annotations/OpenLinksExternallyCompatibility.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.misc.links.open.annotations + +import app.revanced.patcher.annotation.Compatibility +import app.revanced.patcher.annotation.Package + +@Compatibility( + [Package( + "com.google.android.youtube", arrayOf("17.49.37") + )] +) +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.RUNTIME) +internal annotation class OpenLinksExternallyCompatibility diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/BindSessionServiceFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/BindSessionServiceFingerprint.kt new file mode 100644 index 00000000..f7b41a24 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/BindSessionServiceFingerprint.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.youtube.misc.links.open.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +object BindSessionServiceFingerprint : MethodFingerprint( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.FINAL, + opcodes = listOf( + Opcode.IPUT_OBJECT, + Opcode.NEW_INSTANCE, + Opcode.CONST_STRING + ), + strings = listOf("android.support.customtabs.action.CustomTabsService") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/GetCustomTabPackageNameFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/GetCustomTabPackageNameFingerprint.kt new file mode 100644 index 00000000..ffacf035 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/GetCustomTabPackageNameFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.youtube.misc.links.open.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +object GetCustomTabPackageNameFingerprint : MethodFingerprint( + returnType = "L", + access = AccessFlags.PUBLIC or AccessFlags.STATIC, + opcodes = listOf( + Opcode.CHECK_CAST, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.CONST_STRING + ), + strings = listOf("android.support.customtabs.action.CustomTabsService") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/InitializeCustomTabSupportFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/InitializeCustomTabSupportFingerprint.kt new file mode 100644 index 00000000..0901efbb --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/fingerprints/InitializeCustomTabSupportFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.youtube.misc.links.open.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint +import org.jf.dexlib2.AccessFlags +import org.jf.dexlib2.Opcode + +object InitializeCustomTabSupportFingerprint : MethodFingerprint( + returnType = "V", + access = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + opcodes = listOf( + Opcode.CHECK_CAST, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + Opcode.CONST_STRING + ), + strings = listOf("android.support.customtabs.action.CustomTabsService") +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/patch/OpenLinksExternallyPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/patch/OpenLinksExternallyPatch.kt new file mode 100644 index 00000000..ec2e2b5f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/open/patch/OpenLinksExternallyPatch.kt @@ -0,0 +1,65 @@ +package app.revanced.patches.youtube.misc.links.open.patch + +import app.revanced.extensions.toErrorResult +import app.revanced.patcher.annotation.Description +import app.revanced.patcher.annotation.Name +import app.revanced.patcher.annotation.Version +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.addInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchResult +import app.revanced.patcher.patch.PatchResultSuccess +import app.revanced.patcher.patch.annotations.Patch +import app.revanced.patches.shared.settings.preference.impl.StringResource +import app.revanced.patches.shared.settings.preference.impl.SwitchPreference +import app.revanced.patches.youtube.misc.links.open.annotations.OpenLinksExternallyCompatibility +import app.revanced.patches.youtube.misc.links.open.fingerprints.BindSessionServiceFingerprint +import app.revanced.patches.youtube.misc.links.open.fingerprints.GetCustomTabPackageNameFingerprint +import app.revanced.patches.youtube.misc.links.open.fingerprints.InitializeCustomTabSupportFingerprint +import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch +import org.jf.dexlib2.iface.instruction.formats.Instruction21c + +@Patch +@Name("open-links-externally") +@Description("Open links outside of the app directly in your browser.") +@OpenLinksExternallyCompatibility +@Version("0.0.1") +class OpenLinksExternallyPatch : BytecodePatch( + listOf( + GetCustomTabPackageNameFingerprint, + BindSessionServiceFingerprint, + InitializeCustomTabSupportFingerprint + ) +) { + override fun execute(context: BytecodeContext): PatchResult { + SettingsPatch.PreferenceScreen.MISC.addPreferences( + SwitchPreference( + "revanced_enable_external_browser", + StringResource("revanced_enable_external_browser_title", "Open links in browser"), + true, + StringResource("revanced_enable_external_browser_summary_on", "Opening links externally"), + StringResource("revanced_enable_external_browser_summary_off", "Opening links in app") + ) + ) + + arrayOf( + GetCustomTabPackageNameFingerprint, + BindSessionServiceFingerprint, + InitializeCustomTabSupportFingerprint + ).forEach { + val result = it.result ?: return it.toErrorResult() + val insertIndex = result.scanResult.patternScanResult!!.endIndex + 1 + with(result.mutableMethod) { + val register = (implementation!!.instructions[insertIndex - 1] as Instruction21c).registerA + addInstructions( + insertIndex, """ + invoke-static {v$register}, Lapp/revanced/integrations/patches/OpenLinksExternallyPatch;->enableExternalBrowser(Ljava/lang/String;)Ljava/lang/String; + move-result-object v$register + """ + ) + } + } + + return PatchResultSuccess() + } +} \ No newline at end of file