diff --git a/CHANGELOG.md b/CHANGELOG.md index fd23acdc..60d0fca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,121 @@ +# [4.4.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.14...v4.4.0-dev.15) (2024-03-27) + + +### Bug Fixes + +* **YouTube Music:** Fix compatibility with latest versions ([#2924](https://github.com/ReVanced/revanced-patches/issues/2924)) ([8378c84](https://github.com/ReVanced/revanced-patches/commit/8378c8481634a63a5568480475757e64b7ec466e)) + + +### Features + +* **YouTube - Hide Shorts components:** Selectively hide Shorts for home / subscription / search ([#2925](https://github.com/ReVanced/revanced-patches/issues/2925)) ([497c067](https://github.com/ReVanced/revanced-patches/commit/497c067e80e560eb125f5fc30eef9763929b4ee4)) + +# [4.4.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.13...v4.4.0-dev.14) (2024-03-27) + + +### Features + +* **YouTube - Hide layout components:** Filter home/search results by keywords ([#2853](https://github.com/ReVanced/revanced-patches/issues/2853)) ([5916204](https://github.com/ReVanced/revanced-patches/commit/59162042b0a68edf7f94a3c21f838dada3c3f9c3)) + +# [4.4.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.12...v4.4.0-dev.13) (2024-03-26) + + +### Bug Fixes + +* **YouTube:** Move setting to correct screen ([a16eda8](https://github.com/ReVanced/revanced-patches/commit/a16eda864515612d3a6b846082844df15eb49f56)) + + +### Features + +* **YouTube - Hide Shorts components:** Hide like and dislike buttons ([2df0892](https://github.com/ReVanced/revanced-patches/commit/2df0892682406e67283c4aeaacebf8f222029833)) +* **YouTube - Hide Shorts components:** Hide sound metadata label ([ea7d1e0](https://github.com/ReVanced/revanced-patches/commit/ea7d1e0d08cc245117ffe8ad0df3c31c5e87f739)) +* **YouTube - Hide Shorts components:** Hide title and full video link label ([e7b64e1](https://github.com/ReVanced/revanced-patches/commit/e7b64e154e7fb8edd0037f5e171f4aa3ed9017f8)) + +# [4.4.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.11...v4.4.0-dev.12) (2024-03-25) + + +### Bug Fixes + +* **YouTube:** Fix video playback by switching to ReVanced GmsCore vendor ([#2907](https://github.com/ReVanced/revanced-patches/issues/2907)) ([33ea122](https://github.com/ReVanced/revanced-patches/commit/33ea12228c2ae5dcadf3e7c7016d4bf6006d899a)) + +# [4.4.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.10...v4.4.0-dev.11) (2024-03-25) + + +### Features + +* **Mi Fitness:** Add `Force English locale` and `Fix login` patch ([#2734](https://github.com/ReVanced/revanced-patches/issues/2734)) ([7a25791](https://github.com/ReVanced/revanced-patches/commit/7a25791d53530b1236896b2c3d6275ee7556e8b7)) +* **Sync for Lemmy:** Add `Disable ads` patch ([#2872](https://github.com/ReVanced/revanced-patches/issues/2872)) ([0785819](https://github.com/ReVanced/revanced-patches/commit/0785819dd5ad487c778b5baf09004cdab3687184)) + +# [4.4.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.9...v4.4.0-dev.10) (2024-03-25) + + +### Bug Fixes + +* **YouTube - Hide ads:** Prevent app crash if hiding fullscreen ads is not possible ([#2910](https://github.com/ReVanced/revanced-patches/issues/2910)) ([9f50470](https://github.com/ReVanced/revanced-patches/commit/9f50470bf6582fe2f20a903a97bf66c41f296fb2)) + +# [4.4.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.8...v4.4.0-dev.9) (2024-03-18) + + +### Bug Fixes + +* **TikTok:** Hook application context earlier to prevent crash ([#2893](https://github.com/ReVanced/revanced-patches/issues/2893)) ([395ccda](https://github.com/ReVanced/revanced-patches/commit/395ccda7b9218c522c7ca0f99f75a12036d3e3f3)) + +# [4.4.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.7...v4.4.0-dev.8) (2024-03-15) + + +### Features + +* **YouTube - Downloads:** Use external downloader when selecting 'Download' in home feed flyout menu ([#2881](https://github.com/ReVanced/revanced-patches/issues/2881)) ([10afc8c](https://github.com/ReVanced/revanced-patches/commit/10afc8cc71ff29fea4937fb12fd3d1edf9c581f5)) + +# [4.4.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.6...v4.4.0-dev.7) (2024-03-14) + + +### Bug Fixes + +* **YouTube - Client spoof:** Spoof all user agents ([44a8a13](https://github.com/ReVanced/revanced-patches/commit/44a8a1399897caaff3ff45db8549ddedb2f01b68)) + +# [4.4.0-dev.6](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.5...v4.4.0-dev.6) (2024-03-12) + + +### Features + +* **Instagram - Hide timeline ads:** Make compatible with latest versions ([a212f29](https://github.com/ReVanced/revanced-patches/commit/a212f29bd33bb5e10f024e058d26e20ee926190b)) + +# [4.4.0-dev.5](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.4...v4.4.0-dev.5) (2024-03-11) + + +### Features + +* **YouTube:** Support version `19.05`, `19.06`, `19.07`, `19.08` and `19.09` ([#2862](https://github.com/ReVanced/revanced-patches/issues/2862)) ([f044dde](https://github.com/ReVanced/revanced-patches/commit/f044dde054861ff16846a6be6287f86fa3afb3d8)) + +# [4.4.0-dev.4](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.3...v4.4.0-dev.4) (2024-03-11) + + +### Features + +* **YouTube :** Remove `HDR auto brightness` patch ([#2863](https://github.com/ReVanced/revanced-patches/issues/2863)) ([b4c7bf4](https://github.com/ReVanced/revanced-patches/commit/b4c7bf48084184e5f031f7f5139a9a29341d8ebf)) + +# [4.4.0-dev.3](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.2...v4.4.0-dev.3) (2024-03-08) + + +### Bug Fixes + +* **YouTube - Downloads:** Use new task context ([#2841](https://github.com/ReVanced/revanced-patches/issues/2841)) ([6d88cb4](https://github.com/ReVanced/revanced-patches/commit/6d88cb49ec739700866290babcba5fb3032dbced)) + +# [4.4.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.4.0-dev.1...v4.4.0-dev.2) (2024-03-04) + + +### Features + +* **YouTube - External downloader:** Add ability to use in-app download button ([d900011](https://github.com/ReVanced/revanced-patches/commit/d9000113a905c14f8409aa75008f1ef6a1aecd0c)) + +# [4.4.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.3.0...v4.4.0-dev.1) (2024-03-04) + + +### Features + +* **YouTube Vanced:** Remove `Hide ads` patch ([87887e4](https://github.com/ReVanced/revanced-patches/commit/87887e4163dd9e242209f4d0fefb415f9bc7ca75)) + # [4.3.0](https://github.com/ReVanced/revanced-patches/compare/v4.2.0...v4.3.0) (2024-03-02) diff --git a/api/revanced-patches.api b/api/revanced-patches.api index f0d4cd1a..274be198 100644 --- a/api/revanced-patches.api +++ b/api/revanced-patches.api @@ -284,12 +284,30 @@ public final class app/revanced/patches/messenger/inputfield/patch/DisableTyping public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + +public final class app/revanced/patches/mifitness/misc/login/FixLoginPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/mifitness/misc/login/FixLoginPatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/moneymanager/UnlockProPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/moneymanager/UnlockProPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/music/ad/video/HideMusicVideoAds : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/music/ad/video/HideMusicVideoAds; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/music/ad/video/MusicVideoAdsPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/music/ad/video/MusicVideoAdsPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V @@ -302,6 +320,12 @@ public final class app/revanced/patches/music/audio/codecs/CodecsUnlockPatch : a public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/music/audio/exclusiveaudio/ExclusiveAudioPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/music/audio/exclusiveaudio/ExclusiveAudioPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V @@ -314,6 +338,12 @@ public final class app/revanced/patches/music/interaction/permanentrepeat/Perman public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/music/interaction/permanentshuffle/PermanentShuffleTogglePatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/music/interaction/permanentshuffle/PermanentShuffleTogglePatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V @@ -326,6 +356,12 @@ public final class app/revanced/patches/music/layout/compactheader/CompactHeader public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/music/layout/compactheader/HideCategoryBar : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/music/layout/compactheader/HideCategoryBar; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch : app/revanced/patcher/patch/BytecodePatch { public static final field INSTANCE Lapp/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V @@ -481,6 +517,13 @@ public final class app/revanced/patches/reddit/customclients/Constants { public static final field OAUTH_USER_AGENT Ljava/lang/String; } +public abstract class app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch : app/revanced/patcher/patch/BytecodePatch { + public fun (Ljava/util/Set;Ljava/util/Set;)V + public synthetic fun (Ljava/util/Set;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V +} + public final class app/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch : app/revanced/patches/reddit/customclients/BaseSpoofClientPatch { public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/baconreader/api/SpoofClientPatch; public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V @@ -536,10 +579,12 @@ public final class app/revanced/patches/reddit/customclients/slide/api/SpoofClie public fun patchClientId (Ljava/util/Set;Lapp/revanced/patcher/data/BytecodeContext;)V } -public final class app/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch : app/revanced/patcher/patch/BytecodePatch { +public final class app/revanced/patches/reddit/customclients/syncforlemmy/ads/DisableAdsPatch : app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch { + public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforlemmy/ads/DisableAdsPatch; +} + +public final class app/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch : app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch { public static final field INSTANCE Lapp/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch; - public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V - public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } public final class app/revanced/patches/reddit/customclients/syncforreddit/annoyances/startup/DisableSyncForLemmyBottomSheetPatch : app/revanced/patcher/patch/BytecodePatch { @@ -615,6 +660,7 @@ public abstract class app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportRes public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V protected final fun getGmsCoreVendor ()Ljava/lang/String; + protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String; } public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch { @@ -628,9 +674,19 @@ public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrat public fun ()V public fun (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)V public synthetic fun (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)V + public synthetic fun (Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun invoke (Ljava/lang/String;)V } +public abstract interface class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch$IntegrationsFingerprint$IHookInsertIndexResolver : kotlin/jvm/functions/Function1 { + public abstract fun invoke (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Integer; +} + +public final class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch$IntegrationsFingerprint$IHookInsertIndexResolver$DefaultImpls { + public static fun invoke (Lapp/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch$IntegrationsFingerprint$IHookInsertIndexResolver;Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Integer; +} + public abstract interface class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch$IntegrationsFingerprint$IRegisterResolver : kotlin/jvm/functions/Function1 { public abstract fun invoke (Lcom/android/tools/smali/dexlib2/iface/Method;)Ljava/lang/Integer; } @@ -1194,8 +1250,8 @@ public final class app/revanced/patches/youtube/interaction/dialog/RemoveViewerD public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } -public final class app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch : app/revanced/patcher/patch/BytecodePatch { - public static final field INSTANCE Lapp/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch; +public final class app/revanced/patches/youtube/interaction/downloads/DownloadsPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/youtube/interaction/downloads/DownloadsPatch; public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } @@ -1514,10 +1570,12 @@ public final class app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDevic public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } -public final class app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch : app/revanced/patcher/patch/BytecodePatch { +public final class app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch : app/revanced/patches/all/misc/transformation/BaseTransformInstructionsPatch { public static final field INSTANCE Lapp/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch; - public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V - public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V + public synthetic fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Ljava/lang/Object; + public fun filterMap (Lcom/android/tools/smali/dexlib2/iface/ClassDef;Lcom/android/tools/smali/dexlib2/iface/Method;Lcom/android/tools/smali/dexlib2/iface/instruction/Instruction;I)Lkotlin/Triple; + public synthetic fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Ljava/lang/Object;)V + public fun transform (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;Lkotlin/Triple;)V } public final class app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch : app/revanced/patcher/patch/BytecodePatch { @@ -1575,6 +1633,13 @@ public final class app/revanced/patches/youtube/misc/minimizedplayback/Minimized public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V } +public final class app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch : app/revanced/patcher/patch/BytecodePatch { + public static final field INSTANCE Lapp/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch; + public fun execute (Lapp/revanced/patcher/data/BytecodeContext;)V + public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V + public final fun getHookNavigationButtonCreated ()Lkotlin/jvm/functions/Function1; +} + public final class app/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch : app/revanced/patcher/patch/ResourcePatch, java/io/Closeable { public static final field INSTANCE Lapp/revanced/patches/youtube/misc/playercontrols/BottomControlsResourcePatch; public final fun addControls (Ljava/lang/String;)V @@ -1748,6 +1813,7 @@ public final class app/revanced/util/BytecodeUtilsKt { public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V + public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult; public static final fun returnEarly (Ljava/util/List;Z)V public static synthetic fun returnEarly$default (Ljava/util/List;ZILjava/lang/Object;)V public static final fun transformMethods (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V diff --git a/build.gradle.kts b/build.gradle.kts index 5942f58c..58308fbf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ import org.gradle.kotlin.dsl.support.listFilesOrdered +import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { alias(libs.plugins.kotlin) @@ -33,7 +34,13 @@ dependencies { } kotlin { - jvmToolchain(11) + compilerOptions { + jvmTarget.set(JvmTarget.JVM_11) + } +} + +java { + targetCompatibility = JavaVersion.VERSION_11 } tasks { diff --git a/gradle.properties b/gradle.properties index d9f0d412..eacce669 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ org.gradle.parallel = true org.gradle.caching = true kotlin.code.style = official -version = 4.3.0 +version = 4.4.0-dev.15 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7596f26a..a4c08e89 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] revanced-patcher = "19.3.1" -smali = "3.0.4" +smali = "3.0.5" guava = "33.0.0-jre" gson = "2.10.1" binary-compatibility-validator = "0.14.0" diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/HideTimelineAdsPatch.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/HideTimelineAdsPatch.kt index fdae0ddb..2cb98620 100644 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/HideTimelineAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/HideTimelineAdsPatch.kt @@ -1,102 +1,63 @@ package app.revanced.patches.instagram.patches.ads.timeline -import app.revanced.util.exception import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.smali.ExternalLabel -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.MediaFingerprint +import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.IsAdCheckOneFingerprint +import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.IsAdCheckTwoFingerprint import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ShowAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.GenericMediaAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.MediaAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.PaidPartnershipAdFingerprint -import app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads.ShoppingAdFingerprint +import app.revanced.util.exception import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @Patch( name = "Hide timeline ads", - description = "Removes ads from the timeline.", - compatiblePackages = [CompatiblePackage("com.instagram.android", ["275.0.0.27.98"])] + compatiblePackages = [CompatiblePackage("com.instagram.android")], ) @Suppress("unused") object HideTimelineAdsPatch : BytecodePatch( setOf( ShowAdFingerprint, - MediaFingerprint, - PaidPartnershipAdFingerprint // Unlike the other ads this one is resolved from all classes. - ) + IsAdCheckOneFingerprint, + IsAdCheckTwoFingerprint, + ), ) { override fun execute(context: BytecodeContext) { - // region Resolve required methods to check for ads. + // The exact function of the following methods is unknown. + // They are used to check if a post is an ad. + val isAdCheckOneMethod = IsAdCheckOneFingerprint.result?.method ?: throw IsAdCheckOneFingerprint.exception + val isAdCheckTwoMethod = IsAdCheckTwoFingerprint.result?.method ?: throw IsAdCheckTwoFingerprint.exception - ShowAdFingerprint.result ?: throw ShowAdFingerprint.exception + ShowAdFingerprint.result?.let { + it.mutableMethod.apply { + // The register that holds the post object. + val postRegister = getInstruction(1).registerC - PaidPartnershipAdFingerprint.result ?: throw PaidPartnershipAdFingerprint.exception + // At this index the check for an ad can be performed. + val checkIndex = it.scanResult.patternScanResult!!.endIndex - MediaFingerprint.result?.let { - GenericMediaAdFingerprint.resolve(context, it.classDef) - ShoppingAdFingerprint.resolve(context, it.classDef) - - return@let - } ?: throw MediaFingerprint.exception - - // endregion - - ShowAdFingerprint.result!!.apply { - // region Create instructions. - - val scanStart = scanResult.patternScanResult!!.startIndex - val jumpIndex = scanStart - 1 - - val mediaInstanceRegister = mutableMethod.getInstruction(scanStart).registerC - val freeRegister = mutableMethod.getInstruction(jumpIndex).registerA - - val returnFalseLabel = "an_ad" - - val checkForAdInstructions = - listOf(GenericMediaAdFingerprint, PaidPartnershipAdFingerprint, ShoppingAdFingerprint) - .map(MediaAdFingerprint::toString) - .joinToString("\n") { - """ - invoke-virtual {v$mediaInstanceRegister}, $it - move-result v$freeRegister - if-nez v$freeRegister, :$returnFalseLabel - """.trimIndent() - }.let { "$it\nconst/4 v0, 0x1\nreturn v0" } - - // endregion - - // region Patch. - - val insertIndex = scanStart + 3 - - mutableMethod.addInstructionsWithLabels( - insertIndex, - checkForAdInstructions, - ExternalLabel( - returnFalseLabel, - mutableMethod.getInstruction(mutableMethod.implementation!!.instructions.size - 2 /* return false = ad */) - ) - ) - - // endregion - - // region Jump to checks for ads from previous patch. - - mutableMethod.apply { + // If either check returns true, the post is an ad and is hidden by returning false. addInstructionsWithLabels( - jumpIndex + 1, - "if-nez v$freeRegister, :start_check", - ExternalLabel("start_check", getInstruction(insertIndex)) + checkIndex, + """ + invoke-virtual { v$postRegister }, $isAdCheckOneMethod + move-result v0 + if-nez v0, :hide_ad + + invoke-static { v$postRegister }, $isAdCheckTwoMethod + move-result v0 + if-eqz v0, :not_an_ad + + :hide_ad + const/4 v0, 0x0 # Returning false to hide the ad. + return v0 + """, + ExternalLabel("not_an_ad", getInstruction(checkIndex)), ) - }.removeInstruction(jumpIndex) - - // endregion - } + } + } ?: throw ShowAdFingerprint.exception } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckOneFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckOneFingerprint.kt new file mode 100644 index 00000000..58380feb --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckOneFingerprint.kt @@ -0,0 +1,18 @@ +package app.revanced.patches.instagram.patches.ads.timeline.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object IsAdCheckOneFingerprint : MethodFingerprint( + returnType = "Z", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf(), + opcodes = listOf( + Opcode.XOR_INT_LIT8, + Opcode.IF_NE, + Opcode.RETURN, + Opcode.INVOKE_VIRTUAL, + ), +) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/GenericMediaAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckTwoFingerprint.kt similarity index 51% rename from src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/GenericMediaAdFingerprint.kt rename to src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckTwoFingerprint.kt index 8a2d75b4..aa826abf 100644 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/GenericMediaAdFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/IsAdCheckTwoFingerprint.kt @@ -1,8 +1,14 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads +package app.revanced.patches.instagram.patches.ads.timeline.fingerprints +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object GenericMediaAdFingerprint : MediaAdFingerprint( +internal object IsAdCheckTwoFingerprint : MethodFingerprint( + returnType = "Z", + accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, + parameters = listOf("L"), opcodes = listOf( Opcode.INVOKE_INTERFACE, Opcode.MOVE_RESULT_OBJECT, @@ -12,7 +18,5 @@ internal object GenericMediaAdFingerprint : MediaAdFingerprint( Opcode.IF_EQZ, Opcode.CONST_4, Opcode.RETURN, - ) -) { - override fun toString() = result!!.method.toString() -} \ No newline at end of file + ), +) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/MediaFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/MediaFingerprint.kt deleted file mode 100644 index 9959811d..00000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/MediaFingerprint.kt +++ /dev/null @@ -1,7 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint - -internal object MediaFingerprint : MethodFingerprint( - strings = listOf("force_overlay", "Media#updateFields", "live_reels_metadata") -) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt index 53ab5ee9..70eda9ab 100644 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ShowAdFingerprint.kt @@ -10,16 +10,12 @@ internal object ShowAdFingerprint : MethodFingerprint( AccessFlags.PUBLIC or AccessFlags.STATIC or AccessFlags.FINAL, listOf("L", "L", "Z", "Z"), opcodes = listOf( + Opcode.SGET_OBJECT, + Opcode.IF_NE, + Opcode.IF_NEZ, Opcode.INVOKE_STATIC, Opcode.MOVE_RESULT, Opcode.IF_NEZ, Opcode.RETURN, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.GOTO, - Opcode.CONST_4, ), ) diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/MediaAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/MediaAdFingerprint.kt deleted file mode 100644 index 11f21b3f..00000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/MediaAdFingerprint.kt +++ /dev/null @@ -1,24 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.ClassDef -import com.android.tools.smali.dexlib2.iface.Method - -internal abstract class MediaAdFingerprint( - returnType: String? = "Z", - accessFlags: Int? = AccessFlags.PUBLIC or AccessFlags.FINAL, - parameters: Iterable? = listOf(), - opcodes: Iterable?, - customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null -) : MethodFingerprint( - returnType, - accessFlags, - parameters, - opcodes, - customFingerprint = customFingerprint -) { - abstract override fun toString(): String -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/PaidPartnershipAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/PaidPartnershipAdFingerprint.kt deleted file mode 100644 index 2a390022..00000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/PaidPartnershipAdFingerprint.kt +++ /dev/null @@ -1,29 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction -import com.android.tools.smali.dexlib2.iface.reference.MethodReference - -internal object PaidPartnershipAdFingerprint : MediaAdFingerprint( - "V", - null, - listOf("L", "L"), - listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.IPUT_BOOLEAN, - Opcode.IPUT_BOOLEAN - ), - customFingerprint = { methodDef, _ -> - methodDef.definingClass.endsWith("ClipsEditMetadataController;") - } -) { - override fun toString() = result!!.let { - val adCheckIndex = it.scanResult.patternScanResult!!.startIndex - val adCheckInstruction = it.method.implementation!!.instructions.elementAt(adCheckIndex) - - val adCheckMethod = (adCheckInstruction as ReferenceInstruction).reference as MethodReference - - adCheckMethod.toString() - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/ShoppingAdFingerprint.kt b/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/ShoppingAdFingerprint.kt deleted file mode 100644 index 9dd1232c..00000000 --- a/src/main/kotlin/app/revanced/patches/instagram/patches/ads/timeline/fingerprints/ads/ShoppingAdFingerprint.kt +++ /dev/null @@ -1,21 +0,0 @@ -package app.revanced.patches.instagram.patches.ads.timeline.fingerprints.ads - -import com.android.tools.smali.dexlib2.Opcode - -internal object ShoppingAdFingerprint : MediaAdFingerprint( - opcodes = listOf( - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - Opcode.XOR_INT_LIT8, - Opcode.IF_EQZ, - ) -) { - override fun toString() = result!!.method.toString() -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt b/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt new file mode 100644 index 00000000..c71b0c62 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/ForceEnglishLocalePatch.kt @@ -0,0 +1,39 @@ +package app.revanced.patches.mifitness.misc.locale + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.mifitness.misc.locale.fingerprints.SyncBluetoothLanguageFingerprint +import app.revanced.patches.mifitness.misc.login.FixLoginPatch +import app.revanced.util.exception +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch( + name = "Force English locale", + description = "Forces wearable devices to use the English locale.", + compatiblePackages = [CompatiblePackage("com.xiaomi.wearable")], + dependencies = [FixLoginPatch::class], +) +@Suppress("unused") +object ForceEnglishLocalePatch : BytecodePatch( + setOf(SyncBluetoothLanguageFingerprint), +) { + override fun execute(context: BytecodeContext) { + SyncBluetoothLanguageFingerprint.result?.let { + val resolvePhoneLocaleInstruction = it.scanResult.patternScanResult!!.startIndex + + it.mutableMethod.apply { + val registerIndexToUpdate = + getInstruction(resolvePhoneLocaleInstruction).registerA + + replaceInstruction( + resolvePhoneLocaleInstruction, + "const-string v$registerIndexToUpdate, \"en_gb\"", + ) + } + } ?: throw SyncBluetoothLanguageFingerprint.exception + } +} diff --git a/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/fingerprints/SyncBluetoothLanguageFingerprint.kt b/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/fingerprints/SyncBluetoothLanguageFingerprint.kt new file mode 100644 index 00000000..95c9a43f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/mifitness/misc/locale/fingerprints/SyncBluetoothLanguageFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.mifitness.misc.locale.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +internal object SyncBluetoothLanguageFingerprint : MethodFingerprint( + customFingerprint = { methodDef, _ -> + methodDef.definingClass == "Lcom/xiaomi/fitness/devicesettings/DeviceSettingsSyncer;" && + methodDef.name == "syncBluetoothLanguage" + }, + opcodes = listOf(Opcode.MOVE_RESULT_OBJECT), +) diff --git a/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt b/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt new file mode 100644 index 00000000..cf67c893 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/mifitness/misc/login/FixLoginPatch.kt @@ -0,0 +1,35 @@ +package app.revanced.patches.mifitness.misc.login + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.mifitness.misc.login.fingerprints.XiaomiAccountManagerConstructorFingerprint +import app.revanced.util.exception +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch( + name = "Fix login", + description = "Fixes login for uncertified Mi Fitness app", + compatiblePackages = [CompatiblePackage("com.xiaomi.wearable")], +) +@Suppress("unused") +object FixLoginPatch : BytecodePatch( + setOf(XiaomiAccountManagerConstructorFingerprint), +) { + override fun execute(context: BytecodeContext) { + XiaomiAccountManagerConstructorFingerprint.result?.let { + it.mutableMethod.apply { + val isCertifiedIndex = it.scanResult.patternScanResult!!.startIndex + val isCertifiedRegister = getInstruction(isCertifiedIndex).registerA + + addInstruction( + isCertifiedIndex, + "const/4 p$isCertifiedRegister, 0x0", + ) + } + } ?: throw XiaomiAccountManagerConstructorFingerprint.exception + } +} diff --git a/src/main/kotlin/app/revanced/patches/mifitness/misc/login/fingerprints/XiaomiAccountManagerConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/mifitness/misc/login/fingerprints/XiaomiAccountManagerConstructorFingerprint.kt new file mode 100644 index 00000000..e5d06ace --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/mifitness/misc/login/fingerprints/XiaomiAccountManagerConstructorFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.mifitness.misc.login.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object XiaomiAccountManagerConstructorFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PRIVATE or AccessFlags.CONSTRUCTOR, + customFingerprint = { methodDef, _ -> + methodDef.definingClass == "Lcom/xiaomi/passport/accountmanager/XiaomiAccountManager;" + }, + opcodes = listOf(Opcode.IF_NEZ), +) diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/HideMusicVideoAds.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/HideMusicVideoAds.kt new file mode 100644 index 00000000..6f533c2f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/ad/video/HideMusicVideoAds.kt @@ -0,0 +1,37 @@ +package app.revanced.patches.music.ad.video + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsParentFingerprint +import app.revanced.util.exception + +@Patch( + name = "Hide music video ads", + compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], +) +@Suppress("unused") +object HideMusicVideoAds : BytecodePatch( + setOf(ShowMusicVideoAdsParentFingerprint), +) { + override fun execute(context: BytecodeContext) { + ShowMusicVideoAdsParentFingerprint.result?.let { + val showMusicVideoAdsMethod = context + .toMethodWalker(it.mutableMethod) + .nextMethod(it.scanResult.patternScanResult!!.startIndex + 1, true).getMethod() as MutableMethod + + showMusicVideoAdsMethod.addInstruction(0, "const/4 p1, 0x0") + } ?: throw ShowMusicVideoAdsParentFingerprint.exception + } +} + +@Deprecated("This patch class has been renamed to HideMusicVideoAds.") +object MusicVideoAdsPatch : BytecodePatch( + dependencies = setOf(HideMusicVideoAds::class), +) { + override fun execute(context: BytecodeContext) { + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/MusicVideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/MusicVideoAdsPatch.kt deleted file mode 100644 index e2f1978e..00000000 --- a/src/main/kotlin/app/revanced/patches/music/ad/video/MusicVideoAdsPatch.kt +++ /dev/null @@ -1,32 +0,0 @@ -package app.revanced.patches.music.ad.video - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsConstructorFingerprint -import app.revanced.patches.music.ad.video.fingerprints.ShowMusicVideoAdsFingerprint - -@Patch( - name = "Music video ads", - description = "Removes ads in the music player.", - compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")] -) -@Suppress("unused") -object MusicVideoAdsPatch : BytecodePatch( - setOf(ShowMusicVideoAdsConstructorFingerprint) -) { - override fun execute(context: BytecodeContext) { - ShowMusicVideoAdsFingerprint.resolve(context, ShowMusicVideoAdsConstructorFingerprint.result!!.classDef) - - val result = ShowMusicVideoAdsFingerprint.result!! - - result.mutableMethod.addInstruction( - result.scanResult.patternScanResult!!.startIndex, - """ - const/4 p1, 0x0 - """ - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsConstructorFingerprint.kt deleted file mode 100644 index 1a1b9be8..00000000 --- a/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsConstructorFingerprint.kt +++ /dev/null @@ -1,27 +0,0 @@ -package app.revanced.patches.music.ad.video.fingerprints -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -internal object ShowMusicVideoAdsConstructorFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L"), listOf( - Opcode.INVOKE_DIRECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.CONST_4, - Opcode.IPUT_BOOLEAN, - Opcode.RETURN_VOID - ) -) diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsFingerprint.kt deleted file mode 100644 index 952b866d..00000000 --- a/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsFingerprint.kt +++ /dev/null @@ -1,14 +0,0 @@ -package app.revanced.patches.music.ad.video.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object ShowMusicVideoAdsFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("Z"), listOf( - Opcode.IPUT_BOOLEAN, - Opcode.INVOKE_VIRTUAL, - Opcode.RETURN_VOID - ) -) diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsParentFingerprint.kt new file mode 100644 index 00000000..5996ee98 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/ad/video/fingerprints/ShowMusicVideoAdsParentFingerprint.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.music.ad.video.fingerprints + +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.Opcode + +internal object ShowMusicVideoAdsParentFingerprint : MethodFingerprint( + opcodes = listOf( + Opcode.MOVE_RESULT_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.IGET_OBJECT, + ), + strings = listOf("maybeRegenerateCpnAndStatsClient called unexpectedly, but no error."), +) diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/CodecsUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/CodecsUnlockPatch.kt index 35fa977a..0c1cbebc 100644 --- a/src/main/kotlin/app/revanced/patches/music/audio/codecs/CodecsUnlockPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/audio/codecs/CodecsUnlockPatch.kt @@ -10,13 +10,12 @@ import app.revanced.patches.music.audio.codecs.fingerprints.CodecsLockFingerprin import com.android.tools.smali.dexlib2.Opcode @Patch( - name = "Codecs unlock", description = "Adds more audio codec options. The new audio codecs usually result in better audio quality.", - compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")] + compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], ) -@Suppress("unused") +@Deprecated("This patch is no longer needed as the feature is now enabled by default.") object CodecsUnlockPatch : BytecodePatch( - setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint) + setOf(CodecsLockFingerprint, AllCodecsReferenceFingerprint), ) { override fun execute(context: BytecodeContext) { val codecsLockResult = CodecsLockFingerprint.result!! @@ -25,13 +24,13 @@ object CodecsUnlockPatch : BytecodePatch( val scanResultStartIndex = codecsLockResult.scanResult.patternScanResult!!.startIndex val instructionIndex = scanResultStartIndex + - if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) { - // for 5.16.xx and lower - -3 - } else { - // since 5.17.xx - -2 - } + if (implementation.instructions[scanResultStartIndex - 1].opcode == Opcode.CHECK_CAST) { + // for 5.16.xx and lower + -3 + } else { + // since 5.17.xx + -2 + } val allCodecsResult = AllCodecsReferenceFingerprint.result!! val allCodecsMethod = @@ -41,7 +40,7 @@ object CodecsUnlockPatch : BytecodePatch( implementation.replaceInstruction( instructionIndex, - "invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction() + "invoke-static {}, ${allCodecsMethod.definingClass}->${allCodecsMethod.name}()Ljava/util/Set;".toInstruction(), ) } } diff --git a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/ExclusiveAudioPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt similarity index 68% rename from src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/ExclusiveAudioPatch.kt rename to src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt index 8955c77c..79f3fc0f 100644 --- a/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/ExclusiveAudioPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt @@ -1,31 +1,36 @@ package app.revanced.patches.music.audio.exclusiveaudio -import app.revanced.util.exception import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.music.audio.exclusiveaudio.fingerprints.AllowExclusiveAudioPlaybackFingerprint +import app.revanced.util.exception @Patch( - name = "Exclusive audio playback", + name = "Enable exclusive audio playback", description = "Enables the option to play audio without video.", - compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")] + compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], ) @Suppress("unused") -object ExclusiveAudioPatch : BytecodePatch( - setOf(AllowExclusiveAudioPlaybackFingerprint) +object EnableExclusiveAudioPlayback : BytecodePatch( + setOf(AllowExclusiveAudioPlaybackFingerprint), ) { override fun execute(context: BytecodeContext) { AllowExclusiveAudioPlaybackFingerprint.result?.mutableMethod?.apply { addInstructions( 0, - """ + """ const/4 v0, 0x1 return v0 - """ + """, ) } ?: throw AllowExclusiveAudioPlaybackFingerprint.exception } -} \ No newline at end of file +} + +@Deprecated("This patch class has been renamed to EnableExclusiveAudioPlayback.") +object ExclusiveAudioPatch : BytecodePatch(emptySet()) { + override fun execute(context: BytecodeContext) = EnableExclusiveAudioPlayback.execute(context) +} diff --git a/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt b/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt index 70eb16a6..88dff320 100644 --- a/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt @@ -1,25 +1,32 @@ package app.revanced.patches.music.interaction.permanentshuffle -import app.revanced.util.exception import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.music.interaction.permanentshuffle.fingerprints.DisableShuffleFingerprint - +import app.revanced.util.exception @Patch( name = "Permanent shuffle", description = "Permanently remember your shuffle preference " + - "even if the playlist ends or another track is played.", + "even if the playlist ends or another track is played.", compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], - use = false + use = false, ) @Suppress("unused") -object PermanentShuffleTogglePatch : BytecodePatch(setOf(DisableShuffleFingerprint)) { +object PermanentShufflePatch : BytecodePatch(setOf(DisableShuffleFingerprint)) { override fun execute(context: BytecodeContext) { DisableShuffleFingerprint.result?.mutableMethod?.addInstruction(0, "return-void") ?: throw DisableShuffleFingerprint.exception } } + +@Deprecated("This patch class has been renamed to PermanentShufflePatch.") +object PermanentShuffleTogglePatch : BytecodePatch( + dependencies = setOf(PermanentShufflePatch::class), +) { + override fun execute(context: BytecodeContext) { + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/CompactHeaderPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/CompactHeaderPatch.kt deleted file mode 100644 index ec67f2d6..00000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/CompactHeaderPatch.kt +++ /dev/null @@ -1,34 +0,0 @@ -package app.revanced.patches.music.layout.compactheader - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.music.layout.compactheader.fingerprints.CompactHeaderConstructorFingerprint -import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction11x - -@Patch( - name = "Compact header", - description = "Hides the music category bar at the top of the homepage.", - compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], - use = false -) -@Suppress("unused") -object CompactHeaderPatch : BytecodePatch( - setOf(CompactHeaderConstructorFingerprint) -) { - override fun execute(context: BytecodeContext) { - val result = CompactHeaderConstructorFingerprint.result!! - val method = result.mutableMethod - - val insertIndex = result.scanResult.patternScanResult!!.endIndex - val register = (method.implementation!!.instructions[insertIndex - 1] as BuilderInstruction11x).registerA - method.addInstructions( - insertIndex, """ - const/16 v2, 0x8 - invoke-virtual {v${register}, v2}, Landroid/view/View;->setVisibility(I)V - """ - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt new file mode 100644 index 00000000..0cc8e949 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt @@ -0,0 +1,47 @@ +package app.revanced.patches.music.layout.compactheader + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.music.layout.compactheader.fingerprints.ConstructCategoryBarFingerprint +import app.revanced.util.exception +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +@Patch( + name = "Hide category bar", + description = "Hides the category bar at the top of the homepage.", + compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], + use = false, +) +@Suppress("unused") +object HideCategoryBar : BytecodePatch( + setOf(ConstructCategoryBarFingerprint), +) { + override fun execute(context: BytecodeContext) { + ConstructCategoryBarFingerprint.result?.let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.startIndex + val register = getInstruction(insertIndex - 1).registerA + + addInstructions( + insertIndex, + """ + const/16 v2, 0x8 + invoke-virtual {v$register, v2}, Landroid/view/View;->setVisibility(I)V + """, + ) + } + } ?: throw ConstructCategoryBarFingerprint.exception + } +} + +@Deprecated("This patch class has been renamed to HideCategoryBar.") +object CompactHeaderPatch : BytecodePatch( + dependencies = setOf(HideCategoryBar::class), +) { + override fun execute(context: BytecodeContext) { + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/fingerprints/CompactHeaderConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/fingerprints/ConstructCategoryBarFingerprint.kt similarity index 56% rename from src/main/kotlin/app/revanced/patches/music/layout/compactheader/fingerprints/CompactHeaderConstructorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/layout/compactheader/fingerprints/ConstructCategoryBarFingerprint.kt index 98587cc9..903222c5 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/fingerprints/CompactHeaderConstructorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/fingerprints/ConstructCategoryBarFingerprint.kt @@ -5,19 +5,19 @@ import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object CompactHeaderConstructorFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "L", "L", "L", "L"), listOf( - Opcode.INVOKE_DIRECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, +internal object ConstructCategoryBarFingerprint : MethodFingerprint( + "V", + AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, + listOf("Landroid/content/Context;", "L", "L", "L"), + listOf( Opcode.IPUT_OBJECT, Opcode.CONST, - Opcode.CONST_4, - Opcode.INVOKE_STATIC, + Opcode.INVOKE_VIRTUAL, Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST - ) + Opcode.IPUT_OBJECT, + Opcode.CONST, + Opcode.INVOKE_VIRTUAL, + Opcode.NEW_INSTANCE, + Opcode.INVOKE_DIRECT, + ), ) diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch.kt index 2b692d26..f2ec3352 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/MinimizedPlaybackPatch.kt @@ -1,26 +1,39 @@ package app.revanced.patches.music.layout.minimizedplayback -import app.revanced.util.exception import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.music.layout.minimizedplayback.fingerprints.MinimizedPlaybackManagerFingerprint - +import app.revanced.patches.music.layout.minimizedplayback.fingerprints.BackgroundPlaybackDisableFingerprint +import app.revanced.patches.music.layout.minimizedplayback.fingerprints.KidsMinimizedPlaybackPolicyControllerFingerprint +import app.revanced.util.exception @Patch( - name = "Minimized playback music", - description = "Enables minimized playback on Kids music.", - compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")] + name = "Minimized playback", + description = "Unlocks options for picture-in-picture and background playback.", + compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], ) @Suppress("unused") -object MinimizedPlaybackPatch : BytecodePatch(setOf(MinimizedPlaybackManagerFingerprint)) { - override fun execute(context: BytecodeContext) = - MinimizedPlaybackManagerFingerprint.result?.mutableMethod?.addInstruction( +object MinimizedPlaybackPatch : BytecodePatch( + setOf( + KidsMinimizedPlaybackPolicyControllerFingerprint, + BackgroundPlaybackDisableFingerprint, + ), +) { + override fun execute(context: BytecodeContext) { + KidsMinimizedPlaybackPolicyControllerFingerprint.result?.mutableMethod?.addInstruction( + 0, + "return-void", + ) ?: throw KidsMinimizedPlaybackPolicyControllerFingerprint.exception + + BackgroundPlaybackDisableFingerprint.result?.mutableMethod?.addInstructions( 0, """ - return-void - """ - ) ?: throw MinimizedPlaybackManagerFingerprint.exception + const/4 v0, 0x1 + return v0 + """, + ) ?: throw BackgroundPlaybackDisableFingerprint.exception + } } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/BackgroundPlaybackDisableFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/BackgroundPlaybackDisableFingerprint.kt new file mode 100644 index 00000000..d1341028 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/BackgroundPlaybackDisableFingerprint.kt @@ -0,0 +1,23 @@ +package app.revanced.patches.music.layout.minimizedplayback.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags +import com.android.tools.smali.dexlib2.Opcode + +internal object BackgroundPlaybackDisableFingerprint : MethodFingerprint( + "Z", + AccessFlags.PUBLIC or AccessFlags.STATIC, + listOf("L"), + listOf( + Opcode.CONST_4, + Opcode.IF_EQZ, + Opcode.IGET, + Opcode.AND_INT_LIT16, + Opcode.IF_EQZ, + Opcode.IGET_OBJECT, + Opcode.IF_NEZ, + Opcode.SGET_OBJECT, + Opcode.IGET, + ), +) diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt similarity index 87% rename from src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt rename to src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt index bfa47932..da6823c8 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/MinimizedPlaybackManagerFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayback/fingerprints/KidsMinimizedPlaybackPolicyControllerFingerprint.kt @@ -5,7 +5,7 @@ import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode -internal object MinimizedPlaybackManagerFingerprint : MethodFingerprint( +internal object KidsMinimizedPlaybackPolicyControllerFingerprint : MethodFingerprint( "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf("I", "L", "Z"), @@ -22,5 +22,5 @@ internal object MinimizedPlaybackManagerFingerprint : MethodFingerprint( Opcode.CONST_4, Opcode.IF_NE, Opcode.IPUT_BOOLEAN, - ) + ), ) diff --git a/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt index ac7827ff..4be4470d 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt @@ -2,41 +2,44 @@ package app.revanced.patches.music.layout.premium import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint -import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumParentFingerprint +import app.revanced.util.exception +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction @Patch( - name = "Hide get premium", - description = "Removes all \"Get Premium\" evidences from the avatar menu.", - compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")] + name = "Hide 'Get Music Premium' label", + description = "Hides the red \"Get Music Premium\" label from the account menu.", + compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], ) @Suppress("unused") -object HideGetPremiumPatch : BytecodePatch(setOf(HideGetPremiumParentFingerprint)) { +object HideGetPremiumPatch : BytecodePatch( + setOf(HideGetPremiumFingerprint), +) { override fun execute(context: BytecodeContext) { - val parentResult = HideGetPremiumParentFingerprint.result!! - HideGetPremiumFingerprint.resolve(context, parentResult.classDef) + HideGetPremiumFingerprint.result?.let { + it.mutableMethod.apply { + val insertIndex = it.scanResult.patternScanResult!!.endIndex - val startIndex = parentResult.scanResult.patternScanResult!!.startIndex + val setVisibilityInstruction = getInstruction(insertIndex) + val getPremiumViewRegister = setVisibilityInstruction.registerC + val visibilityRegister = setVisibilityInstruction.registerD - val parentMethod = parentResult.mutableMethod - parentMethod.replaceInstruction( - startIndex, - """ - const/4 v1, 0x0 - """ - ) + replaceInstruction( + insertIndex, + "const/16 v$visibilityRegister, 0x8", + ) - val result = HideGetPremiumFingerprint.result!! - val method = result.mutableMethod - method.addInstruction( - startIndex, - """ - const/16 v0, 0x8 - """ - ) + addInstruction( + insertIndex + 1, + "invoke-virtual {v$getPremiumViewRegister, v$visibilityRegister}, " + + "Landroid/view/View;->setVisibility(I)V", + ) + } + } ?: throw HideGetPremiumFingerprint.exception } } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumFingerprint.kt index 6a29e7ad..e97251de 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumFingerprint.kt @@ -6,11 +6,13 @@ import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode internal object HideGetPremiumFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( + "V", + AccessFlags.PUBLIC or AccessFlags.FINAL, + listOf(), + listOf( Opcode.IF_NEZ, Opcode.CONST_16, - Opcode.GOTO, - Opcode.NOP, - Opcode.INVOKE_VIRTUAL - ) + Opcode.INVOKE_VIRTUAL, + ), + listOf("FEmusic_history", "FEmusic_offline"), ) diff --git a/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumParentFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumParentFingerprint.kt deleted file mode 100644 index 3463fcfc..00000000 --- a/src/main/kotlin/app/revanced/patches/music/layout/premium/fingerprints/HideGetPremiumParentFingerprint.kt +++ /dev/null @@ -1,19 +0,0 @@ -package app.revanced.patches.music.layout.premium.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - -internal object HideGetPremiumParentFingerprint : MethodFingerprint( - "V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf( - Opcode.IGET_BOOLEAN, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC - ), - listOf("FEmusic_history"), -) diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt index 7cd39e17..fed2cc6d 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/RemoveUpgradeButtonPatch.kt @@ -1,71 +1,84 @@ package app.revanced.patches.music.layout.upgradebutton import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction +import app.revanced.patcher.extensions.newLabel import app.revanced.patcher.patch.BytecodePatch import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.smali.toInstructions import app.revanced.patches.music.layout.upgradebutton.fingerprints.PivotBarConstructorFingerprint +import app.revanced.util.exception +import app.revanced.util.getReference import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t -import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction22c import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c - +import com.android.tools.smali.dexlib2.iface.reference.FieldReference @Patch( name = "Remove upgrade button", description = "Removes the upgrade tab from the pivot bar.", - compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")] + compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")], ) @Suppress("unused") object RemoveUpgradeButtonPatch : BytecodePatch( - setOf(PivotBarConstructorFingerprint) + setOf(PivotBarConstructorFingerprint), ) { override fun execute(context: BytecodeContext) { - val result = PivotBarConstructorFingerprint.result!! - val implementation = result.mutableMethod.implementation!! + PivotBarConstructorFingerprint.result?.let { + it.mutableMethod.apply { + val pivotBarElementFieldReference = getInstruction(it.scanResult.patternScanResult!!.endIndex - 1) + .getReference() - val pivotBarElementFieldRef = - (implementation.instructions[result.scanResult.patternScanResult!!.endIndex - 1] as Instruction22c).reference + val register = (getInstructions().first() as Instruction35c).registerC - val register = (implementation.instructions.first() as Instruction35c).registerC - // first compile all the needed instructions - val instructionList = """ - invoke-interface { v0 }, Ljava/util/List;->size()I - move-result v1 - const/4 v2, 0x4 - invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object; - iput-object v0, v$register, $pivotBarElementFieldRef - """.toInstructions().toMutableList() + // First compile all the needed instructions. + val instructionList = """ + invoke-interface { v0 }, Ljava/util/List;->size()I + move-result v1 + const/4 v2, 0x4 + invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object; + iput-object v0, v$register, $pivotBarElementFieldReference + """.toInstructions().toMutableList() + val endIndex = it.scanResult.patternScanResult!!.endIndex - val endIndex = result.scanResult.patternScanResult!!.endIndex + // Replace the instruction to retain the label at given index. + replaceInstruction( + endIndex - 1, + instructionList[0], // invoke-interface. + ) + // Do not forget to remove this instruction since we added it already. + instructionList.removeFirst() - // replace the instruction to retain the label at given index - implementation.replaceInstruction( - endIndex - 1, instructionList[0] // invoke-interface - ) - // do not forget to remove this instruction since we added it already - instructionList.removeFirst() + val exitInstruction = instructionList.last() // iput-object + addInstruction( + endIndex, + exitInstruction, + ) + // Do not forget to remove this instruction since we added it already. + instructionList.removeLast() - val exitInstruction = instructionList.last() // iput-object - implementation.addInstruction( - endIndex, exitInstruction - ) - // do not forget to remove this instruction since we added it already - instructionList.removeLast() + // Add the necessary if statement to remove the upgrade tab button in case it exists. + instructionList.add( + 2, // if-le. + BuilderInstruction22t( + Opcode.IF_LE, + 1, + 2, + newLabel(endIndex), + ), + ) - // add the necessary if statement to remove the upgrade tab button in case it exists - instructionList.add( - 2, // if-le - BuilderInstruction22t( - Opcode.IF_LE, 1, 2, implementation.newLabelForIndex(endIndex) - ) - ) - - implementation.addInstructions( - endIndex, instructionList - ) + addInstructions( + endIndex, + instructionList, + ) + } + } ?: throw PivotBarConstructorFingerprint.exception } } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt index 36ec43f5..ee7ffbcb 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/fingerprints/PivotBarConstructorFingerprint.kt @@ -1,62 +1,19 @@ package app.revanced.patches.music.layout.upgradebutton.fingerprints import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod import app.revanced.patcher.fingerprint.MethodFingerprint import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. internal object PivotBarConstructorFingerprint : MethodFingerprint( "V", AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, listOf("L", "Z"), listOf( - Opcode.INVOKE_DIRECT, - Opcode.CONST_4, - Opcode.IPUT_OBJECT, - Opcode.IPUT_OBJECT, - Opcode.IPUT_BOOLEAN, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.GOTO, - Opcode.NEW_INSTANCE, - Opcode.INVOKE_DIRECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.GOTO, - Opcode.SGET_OBJECT, - Opcode.IGET_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT, - Opcode.IF_EQZ, - Opcode.INVOKE_INTERFACE, - Opcode.MOVE_RESULT_OBJECT, - Opcode.CHECK_CAST, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, Opcode.CHECK_CAST, Opcode.INVOKE_INTERFACE, Opcode.GOTO, - Opcode.NOP, Opcode.IPUT_OBJECT, - Opcode.RETURN_VOID - ) -) \ No newline at end of file + Opcode.RETURN_VOID, + ), +) diff --git a/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt index 5bb8e2a4..65d90539 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt @@ -2,12 +2,12 @@ package app.revanced.patches.music.misc.gms import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME -import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorOption +import app.revanced.patches.music.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption import app.revanced.patches.music.misc.gms.fingerprints.* -import app.revanced.patches.music.misc.integrations.fingerprints.ApplicationInitFingerprint import app.revanced.patches.music.misc.integrations.IntegrationsPatch -import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch +import app.revanced.patches.music.misc.integrations.fingerprints.ApplicationInitFingerprint import app.revanced.patches.shared.fingerprints.CastContextFetchFingerprint +import app.revanced.patches.shared.misc.gms.BaseGmsCoreSupportPatch @Suppress("unused") object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( @@ -32,7 +32,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( CastDynamiteModuleV2Fingerprint, CastContextFetchFingerprint, PrimeMethodFingerprint, - ) + ), ) { - override val gmsCoreVendor by gmsCoreVendorOption + override val gmsCoreVendor by gmsCoreVendorGroupIdOption } diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch.kt index 5850528f..a17903a2 100644 --- a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/BackgroundPlayPatch.kt @@ -1,26 +1,12 @@ package app.revanced.patches.music.premium.backgroundplay -import app.revanced.util.exception import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.music.premium.backgroundplay.fingerprints.BackgroundPlaybackDisableFingerprint - - -@Patch( - name = "Background play", - description = "Enables playing music in the background.", - compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")] -) -@Suppress("unused") -object BackgroundPlayPatch : BytecodePatch(setOf(BackgroundPlaybackDisableFingerprint)) { - override fun execute(context: BytecodeContext) = - BackgroundPlaybackDisableFingerprint.result?.mutableMethod?.addInstructions( - 0, """ - const/4 v0, 0x1 - return v0 - """ - ) ?: throw BackgroundPlaybackDisableFingerprint.exception -} \ No newline at end of file +import app.revanced.patches.music.layout.minimizedplayback.MinimizedPlaybackPatch +@Deprecated("This patch has been merged into MinimizedPlaybackPatch.") +object BackgroundPlayPatch : BytecodePatch( + dependencies = setOf(MinimizedPlaybackPatch::class), +) { + override fun execute(context: BytecodeContext) { + } +} diff --git a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/fingerprints/BackgroundPlaybackDisableFingerprint.kt b/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/fingerprints/BackgroundPlaybackDisableFingerprint.kt deleted file mode 100644 index 68779590..00000000 --- a/src/main/kotlin/app/revanced/patches/music/premium/backgroundplay/fingerprints/BackgroundPlaybackDisableFingerprint.kt +++ /dev/null @@ -1,43 +0,0 @@ -package app.revanced.patches.music.premium.backgroundplay.fingerprints - -import app.revanced.patcher.extensions.or -import app.revanced.patcher.fingerprint.annotation.FuzzyPatternScanMethod -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.AccessFlags -import com.android.tools.smali.dexlib2.Opcode - - -@FuzzyPatternScanMethod(2) // FIXME: Test this threshold and find the best value. -internal object BackgroundPlaybackDisableFingerprint : MethodFingerprint( - "Z", AccessFlags.PUBLIC or AccessFlags.STATIC, listOf("L"), listOf( - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET, - Opcode.AND_INT_LIT16, - Opcode.IF_EQZ, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IGET, - Opcode.CONST, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.IF_NEZ, - Opcode.SGET_OBJECT, - Opcode.IGET, - Opcode.IF_NE, - Opcode.IGET_OBJECT, - Opcode.CHECK_CAST, - Opcode.GOTO, - Opcode.SGET_OBJECT, - Opcode.GOTO, - Opcode.CONST_4, - Opcode.IF_EQZ, - Opcode.IGET_BOOLEAN, - Opcode.IF_EQZ, - Opcode.CONST_4, - Opcode.RETURN, - Opcode.RETURN, - Opcode.RETURN - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch.kt new file mode 100644 index 00000000..c8697180 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/ads/BaseDisableAdsPatch.kt @@ -0,0 +1,19 @@ +package app.revanced.patches.reddit.customclients.ads + +import app.revanced.patcher.PatchClass +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patches.reddit.customclients.ads.fingerprints.IsAdsEnabledFingerprint +import app.revanced.util.returnEarly + +abstract class BaseDisableAdsPatch( + dependencies: Set = emptySet(), + compatiblePackages: Set, +) : BytecodePatch( + name = "Disable ads", + dependencies = dependencies, + compatiblePackages = compatiblePackages, + fingerprints = setOf(IsAdsEnabledFingerprint), +) { + override fun execute(context: BytecodeContext) = listOf(IsAdsEnabledFingerprint).returnEarly() +} diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/ads/fingerprints/IsAdsEnabledFingerprint.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/ads/fingerprints/IsAdsEnabledFingerprint.kt similarity index 71% rename from src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/ads/fingerprints/IsAdsEnabledFingerprint.kt rename to src/main/kotlin/app/revanced/patches/reddit/customclients/ads/fingerprints/IsAdsEnabledFingerprint.kt index 2c15da4e..a4c8b61d 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/ads/fingerprints/IsAdsEnabledFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/ads/fingerprints/IsAdsEnabledFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.reddit.customclients.syncforreddit.ads.fingerprints +package app.revanced.patches.reddit.customclients.ads.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint @@ -7,5 +7,5 @@ import com.android.tools.smali.dexlib2.AccessFlags internal object IsAdsEnabledFingerprint : MethodFingerprint( returnType = "Z", accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC, - strings = listOf("SyncIapHelper") -) \ No newline at end of file + strings = listOf("SyncIapHelper"), +) diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforlemmy/ads/DisableAdsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforlemmy/ads/DisableAdsPatch.kt new file mode 100644 index 00000000..2359a40d --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforlemmy/ads/DisableAdsPatch.kt @@ -0,0 +1,10 @@ +package app.revanced.patches.reddit.customclients.syncforlemmy.ads + +import app.revanced.patches.reddit.customclients.ads.BaseDisableAdsPatch +import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.DisablePiracyDetectionPatch + +@Suppress("unused") +object DisableAdsPatch : BaseDisableAdsPatch( + dependencies = setOf(DisablePiracyDetectionPatch::class), + compatiblePackages = setOf(CompatiblePackage("com.laurencedawson.reddit_sync")), +) diff --git a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch.kt b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch.kt index 75c57b64..c43f4d32 100644 --- a/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/reddit/customclients/syncforreddit/ads/DisableAdsPatch.kt @@ -1,30 +1,8 @@ package app.revanced.patches.reddit.customclients.syncforreddit.ads -import app.revanced.util.exception -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.reddit.customclients.syncforreddit.ads.fingerprints.IsAdsEnabledFingerprint -import app.revanced.patches.reddit.customclients.syncforreddit.detection.piracy.DisablePiracyDetectionPatch +import app.revanced.patches.reddit.customclients.ads.BaseDisableAdsPatch -@Patch( - name = "Disable ads", - dependencies = [DisablePiracyDetectionPatch::class], - compatiblePackages = [CompatiblePackage("com.laurencedawson.reddit_sync")] -) @Suppress("unused") -object DisableAdsPatch : BytecodePatch(setOf(IsAdsEnabledFingerprint)) { - override fun execute(context: BytecodeContext) { - IsAdsEnabledFingerprint.result?.mutableMethod?.apply { - addInstructions( - 0, - """ - const/4 v0, 0x0 - return v0 - """ - ) - } ?: throw IsAdsEnabledFingerprint.exception - } -} \ No newline at end of file +object DisableAdsPatch : BaseDisableAdsPatch( + compatiblePackages = setOf(CompatiblePackage("io.syncapps.lemmy_sync")), +) diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt index 5c118db6..f7bfcb6e 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportPatch.kt @@ -53,15 +53,15 @@ abstract class BaseGmsCoreSupportPatch( ) : BytecodePatch( name = "GmsCore support", description = "Allows patched Google apps to run without root and under a different package name " + - "by using GmsCore instead of Google Play Services.", + "by using GmsCore instead of Google Play Services.", dependencies = setOf( ChangePackageNamePatch::class, gmsCoreSupportResourcePatch::class, - integrationsPatchDependency + integrationsPatchDependency, ) + dependencies, compatiblePackages = compatiblePackages, fingerprints = setOf(GmsCoreSupportFingerprint, mainActivityOnCreateFingerprint) + fingerprints, - requiresIntegrations = true + requiresIntegrations = true, ) { init { // Manually register all options of the resource patch so that they are visible in the patch API. @@ -77,7 +77,7 @@ abstract class BaseGmsCoreSupportPatch( val transformations = arrayOf( ::commonTransform, ::contentUrisTransform, - packageNameTransform(fromPackageName, packageName) + packageNameTransform(fromPackageName, packageName), ) context.transformStringReferences transform@{ string -> transformations.forEach { transform -> @@ -96,7 +96,7 @@ abstract class BaseGmsCoreSupportPatch( // Check the availability of GmsCore. mainActivityOnCreateFingerprint.result?.mutableMethod?.addInstruction( 1, // Hack to not disturb other patches (such as the integrations patch). - "invoke-static {}, Lapp/revanced/integrations/youtube/patches/GmsCoreSupport;->checkAvailability()V" + "invoke-static {}, Lapp/revanced/integrations/shared/GmsCoreSupport;->checkAvailability()V", ) ?: throw mainActivityOnCreateFingerprint.exception // Change the vendor of GmsCore in ReVanced Integrations. @@ -130,8 +130,8 @@ abstract class BaseGmsCoreSupportPatch( BuilderInstruction21c( Opcode.CONST_STRING, instruction.registerA, - ImmutableStringReference(transformedString) - ) + ImmutableStringReference(transformedString), + ), ) } } @@ -145,7 +145,8 @@ abstract class BaseGmsCoreSupportPatch( "com.google.android.gms", in PERMISSIONS, in ACTIONS, - in AUTHORITIES -> referencedString.replace("com.google", gmsCoreVendor!!) + in AUTHORITIES, + -> referencedString.replace("com.google", gmsCoreVendor!!) // No vendor prefix for whatever reason... "subscribedfeeds" -> "$gmsCoreVendor.subscribedfeeds" @@ -161,7 +162,7 @@ abstract class BaseGmsCoreSupportPatch( if (str.startsWith(uriPrefix)) { return str.replace( uriPrefix, - "content://${authority.replace("com.google", gmsCoreVendor!!)}" + "content://${authority.replace("com.google", gmsCoreVendor!!)}", ) } } @@ -174,13 +175,13 @@ abstract class BaseGmsCoreSupportPatch( } return null - } private fun packageNameTransform(fromPackageName: String, toPackageName: String): (String) -> String? = { string -> when (string) { "$fromPackageName.SuggestionsProvider", - "$fromPackageName.fileprovider" -> string.replace(fromPackageName, toPackageName) + "$fromPackageName.fileprovider", + -> string.replace(fromPackageName, toPackageName) else -> null } @@ -273,6 +274,9 @@ abstract class BaseGmsCoreSupportPatch( // fido "com.google.android.gms.fido.fido2.privileged.START", + // gass + "com.google.android.gms.gass.START", + // games "com.google.android.gms.games.service.START", "com.google.android.gms.games.PLAY_GAMES_UPGRADE", @@ -292,8 +296,18 @@ abstract class BaseGmsCoreSupportPatch( // misc "com.google.android.gms.gmscompliance.service.START", "com.google.android.gms.oss.licenses.service.START", + "com.google.android.gms.tapandpay.service.BIND", + "com.google.android.gms.measurement.START", + "com.google.android.gms.languageprofile.service.START", + "com.google.android.gms.clearcut.service.START", + "com.google.android.gms.icing.LIGHTWEIGHT_INDEX_SERVICE", + + // potoken + "com.google.android.gms.potokens.service.START", + + // droidguard/ safetynet + "com.google.android.gms.droidguard.service.START", "com.google.android.gms.safetynet.service.START", - "com.google.android.gms.tapandpay.service.BIND" ) /** @@ -314,9 +328,9 @@ abstract class BaseGmsCoreSupportPatch( "com.google.android.gms.fonts", // phenotype - "com.google.android.gms.phenotype" + "com.google.android.gms.phenotype", ) } // endregion -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt index e42f3360..eef039f7 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportResourcePatch.kt @@ -24,21 +24,23 @@ abstract class BaseGmsCoreSupportResourcePatch( private val spoofedPackageSignature: String, dependencies: Set = setOf(), ) : ResourcePatch(dependencies = setOf(ChangePackageNamePatch::class, AddResourcesPatch::class) + dependencies) { - internal val gmsCoreVendorOption = + internal val gmsCoreVendorGroupIdOption = stringPatchOption( - key = "gmsCoreVendor", - default = "com.mgoogle", + key = "gmsCoreVendorGroupId", + default = "app.revanced", values = mapOf( - "Vanced" to "com.mgoogle", "ReVanced" to "app.revanced", ), - title = "GmsCore Vendor", - description = "The group id of the GmsCore vendor.", + title = "GmsCore vendor group ID", + description = "The vendor's group ID for GmsCore.", required = true, - ) { it!!.matches(Regex("^[a-z]\\w*(\\.[a-z]\\w*)+\$")) } + ) { it!!.matches(Regex(PACKAGE_NAME_REGEX_PATTERN)) } - protected val gmsCoreVendor by gmsCoreVendorOption + protected val gmsCoreVendorGroupId by gmsCoreVendorGroupIdOption + + @Deprecated("Use gmsCoreVendorGroupId instead.", ReplaceWith("gmsCoreVendorGroupId")) + protected val gmsCoreVendor by gmsCoreVendorGroupIdOption override fun execute(context: ResourceContext) { AddResourcesPatch(BaseGmsCoreSupportResourcePatch::class) @@ -70,12 +72,12 @@ abstract class BaseGmsCoreSupportResourcePatch( // Spoof package name and signature. applicationNode.adoptChild("meta-data") { - setAttribute("android:name", "$gmsCoreVendor.android.gms.SPOOFED_PACKAGE_NAME") + setAttribute("android:name", "$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_NAME") setAttribute("android:value", fromPackageName) } applicationNode.adoptChild("meta-data") { - setAttribute("android:name", "$gmsCoreVendor.android.gms.SPOOFED_PACKAGE_SIGNATURE") + setAttribute("android:name", "$gmsCoreVendorGroupId.android.gms.SPOOFED_PACKAGE_SIGNATURE") setAttribute("android:value", spoofedPackageSignature) } @@ -83,7 +85,7 @@ abstract class BaseGmsCoreSupportResourcePatch( applicationNode.adoptChild("meta-data") { // TODO: The name of this metadata should be dynamic. setAttribute("android:name", "app.revanced.MICROG_PACKAGE_NAME") - setAttribute("android:value", "$gmsCoreVendor.android.gms") + setAttribute("android:value", "$gmsCoreVendorGroupId.android.gms") } } } @@ -110,11 +112,16 @@ abstract class BaseGmsCoreSupportResourcePatch( "$packageName.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION", ).replace( "com.google.android.c2dm", - "$gmsCoreVendor.android.c2dm", + "$gmsCoreVendorGroupId.android.c2dm", ).replace( "", - "", + "", ), ) } + + private companion object { + private const val VANCED_VENDOR = "com.mgoogle" + private const val PACKAGE_NAME_REGEX_PATTERN = "^[a-z]\\w*(\\.[a-z]\\w*)+\$" + } } diff --git a/src/main/kotlin/app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch.kt b/src/main/kotlin/app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch.kt index eb7f7e87..c1c849c0 100644 --- a/src/main/kotlin/app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch.kt @@ -49,7 +49,8 @@ abstract class BaseIntegrationsPatch( opcodes: Iterable? = null, strings: Iterable? = null, customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null, - private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}, + private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {}, + private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {} ) : MethodFingerprint( returnType, accessFlags, @@ -58,18 +59,45 @@ abstract class BaseIntegrationsPatch( strings, customFingerprint, ) { + @Deprecated("Previous constructor that is missing the insert index." + + "Here only for binary compatibility, " + + "and this can be removed after the next major version update.") + constructor( + returnType: String? = null, + accessFlags: Int? = null, + parameters: Iterable? = null, + opcodes: Iterable? = null, + strings: Iterable? = null, + customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null, + contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {} + ) : this( + returnType, + accessFlags, + parameters, + opcodes, + strings, + customFingerprint, + object : IHookInsertIndexResolver {}, + contextRegisterResolver + ) + fun invoke(integrationsDescriptor: String) { result?.mutableMethod?.let { method -> + val insertIndex = insertIndexResolver(method) val contextRegister = contextRegisterResolver(method) method.addInstruction( - 0, - "sput-object v$contextRegister, " + - "$integrationsDescriptor->context:Landroid/content/Context;", + insertIndex, + "invoke-static/range { v$contextRegister .. v$contextRegister }, " + + "$integrationsDescriptor->setContext(Landroid/content/Context;)V", ) } ?: throw PatchException("Could not find hook target fingerprint.") } + interface IHookInsertIndexResolver : (Method) -> Int { + override operator fun invoke(method: Method) = 0 + } + interface IRegisterResolver : (Method) -> Int { override operator fun invoke(method: Method) = method.implementation!!.registerCount - 1 } diff --git a/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/fingerprints/InitFingerprint.kt b/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/fingerprints/InitFingerprint.kt index f61e36bc..65c634a0 100644 --- a/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/fingerprints/InitFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/tiktok/misc/integrations/fingerprints/InitFingerprint.kt @@ -1,10 +1,14 @@ package app.revanced.patches.tiktok.misc.integrations.fingerprints +import app.revanced.patcher.extensions.or import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint +import com.android.tools.smali.dexlib2.AccessFlags internal object InitFingerprint : IntegrationsFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR, customFingerprint = { methodDef, _ -> methodDef.definingClass.endsWith("/AwemeHostApplication;") && - methodDef.name == "onCreate" - } + methodDef.name == "" + }, + insertIndexResolver = { 1 } // Insert after call to super class. ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt index b73927b6..063f033e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt @@ -36,9 +36,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ], ), ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt index 5cc676ff..a90956e0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt @@ -30,9 +30,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt index d03c3ff2..06e496e0 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt @@ -35,9 +35,13 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt index 894d3085..89398b8d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlBytecodePatch.kt @@ -23,9 +23,13 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ], ), ], @@ -39,7 +43,6 @@ object CopyVideoUrlBytecodePatch : BytecodePatch(emptySet()) { ) override fun execute(context: BytecodeContext) { - // Initialize buttons and inject visibility control BUTTONS_DESCRIPTORS.forEach { descriptor -> PlayerControlsBytecodePatch.initializeControl("$descriptor->initializeButton(Landroid/view/View;)V") PlayerControlsBytecodePatch.injectVisibilityCheckCall("$descriptor->changeVisibility(Z)V") diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt index 591e16bf..7fdacaef 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt @@ -32,9 +32,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt new file mode 100644 index 00000000..e9f2c920 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt @@ -0,0 +1,79 @@ +package app.revanced.patches.youtube.interaction.downloads + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.youtube.interaction.downloads.fingerprints.OfflineVideoEndpointFingerprint +import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch +import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint +import app.revanced.patches.youtube.video.information.VideoInformationPatch +import app.revanced.util.resultOrThrow + +@Patch( + name = "Downloads", + description = "Adds support to download videos with an external downloader app" + + "using the in-app download button or a video player action button.", + dependencies = [ + DownloadsResourcePatch::class, + PlayerControlsBytecodePatch::class, + VideoInformationPatch::class, + ], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube", + [ + "18.48.39", + "18.49.37", + "19.01.34", + "19.02.39", + "19.03.36", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" + ], + ), + ], +) +@Suppress("unused") +object DownloadsPatch : BytecodePatch( + setOf( + OfflineVideoEndpointFingerprint, + MainActivityFingerprint + ) +) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/DownloadsPatch;" + private const val BUTTON_DESCRIPTOR = "Lapp/revanced/integrations/youtube/videoplayer/ExternalDownloadButton;" + + override fun execute(context: BytecodeContext) { + PlayerControlsBytecodePatch.initializeControl("$BUTTON_DESCRIPTOR->initializeButton(Landroid/view/View;)V") + PlayerControlsBytecodePatch.injectVisibilityCheckCall("$BUTTON_DESCRIPTOR->changeVisibility(Z)V") + + // Main activity is used to launch downloader intent. + MainActivityFingerprint.resultOrThrow().mutableMethod.apply { + addInstruction( + implementation!!.instructions.lastIndex, + "invoke-static { p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->activityCreated(Landroid/app/Activity;)V" + ) + } + + OfflineVideoEndpointFingerprint.resultOrThrow().mutableMethod.apply { + addInstructionsWithLabels( + 0, + """ + invoke-static/range {p3 .. p3}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick(Ljava/lang/String;)Z + move-result v0 + if-eqz v0, :show_native_downloader + return-void + :show_native_downloader + nop + """ + ) + } + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsResourcePatch.kt similarity index 92% rename from src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsResourcePatch.kt rename to src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsResourcePatch.kt index e24b7e6c..24285e53 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsResourcePatch.kt @@ -21,7 +21,7 @@ import app.revanced.util.copyResources AddResourcesPatch::class, ], ) -internal object ExternalDownloadsResourcePatch : ResourcePatch() { +internal object DownloadsResourcePatch : ResourcePatch() { override fun execute(context: ResourceContext) { AddResourcesPatch(this::class) @@ -31,6 +31,7 @@ internal object ExternalDownloadsResourcePatch : ResourcePatch() { sorting = Sorting.UNSORTED, preferences = setOf( SwitchPreference("revanced_external_downloader"), + SwitchPreference("revanced_external_downloader_action_button"), TextPreference("revanced_external_downloader_name", inputType = InputType.TEXT), ), ), diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt deleted file mode 100644 index fdda9fdb..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/ExternalDownloadsBytecodePatch.kt +++ /dev/null @@ -1,54 +0,0 @@ -package app.revanced.patches.youtube.interaction.downloads - -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch -import app.revanced.patches.youtube.video.information.VideoInformationPatch - -@Patch( - name = "External downloads", - description = "Adds support to download and save YouTube videos using an external downloader app.", - dependencies = [ - ExternalDownloadsResourcePatch::class, - PlayerControlsBytecodePatch::class, - VideoInformationPatch::class, - ], - compatiblePackages = [ - CompatiblePackage( - "com.google.android.youtube", - [ - "18.48.39", - "18.49.37", - "19.01.34", - "19.02.39", - "19.03.35", - "19.03.36", - "19.04.37", - ], - ), - ], -) -@Suppress("unused") -object ExternalDownloadsBytecodePatch : BytecodePatch(emptySet()) { - private const val BUTTON_DESCRIPTOR = "Lapp/revanced/integrations/youtube/videoplayer/ExternalDownloadButton;" - - override fun execute(context: BytecodeContext) { - /* - initialize the control - */ - - PlayerControlsBytecodePatch.initializeControl( - "$BUTTON_DESCRIPTOR->initializeButton(Landroid/view/View;)V", - ) - - /* - add code to change the visibility of the control - */ - - PlayerControlsBytecodePatch.injectVisibilityCheckCall( - "$BUTTON_DESCRIPTOR->changeVisibility(Z)V", - ) - } -} diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/fingerprints/OfflineVideoEndpointFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/fingerprints/OfflineVideoEndpointFingerprint.kt new file mode 100644 index 00000000..f28bc556 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/fingerprints/OfflineVideoEndpointFingerprint.kt @@ -0,0 +1,16 @@ +package app.revanced.patches.youtube.interaction.downloads.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object OfflineVideoEndpointFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", + parameters = listOf( + "Ljava/util/Map;", + "L", + "Ljava/lang/String", // VideoId + "L"), + strings = listOf("Object is not an offlineable video: ") +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt index a7cbd0a7..e18a8f07 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/DisablePreciseSeekingGesturePatch.kt @@ -32,9 +32,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt index 0b11595d..3c4be5ad 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSeekbarTappingPatch.kt @@ -34,9 +34,13 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt index ec38b7e7..eb5ef93c 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/EnableSlideToSeekPatch.kt @@ -30,9 +30,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsBytecodePatch.kt index 2ad39c70..5e21c607 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsBytecodePatch.kt @@ -36,9 +36,13 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt index 6afc7290..00f15cab 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt @@ -34,9 +34,13 @@ import app.revanced.util.exception "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt index 6debdf1a..2a628482 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt @@ -33,9 +33,13 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/HideAutoplayButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/HideAutoplayButtonPatch.kt index 5937185e..d96caab7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/HideAutoplayButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/autoplay/HideAutoplayButtonPatch.kt @@ -43,9 +43,13 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/HideCaptionsButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/HideCaptionsButtonPatch.kt index a9f2b9f7..88e85668 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/HideCaptionsButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/captions/HideCaptionsButtonPatch.kt @@ -34,9 +34,13 @@ import com.android.tools.smali.dexlib2.Opcode "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt index a8ac8121..c660344d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt @@ -10,10 +10,10 @@ import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting import app.revanced.patches.shared.misc.settings.preference.SwitchPreference -import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.* -import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUtils.REGISTER_TEMPLATE_REPLACEMENT -import app.revanced.patches.youtube.layout.buttons.navigation.utils.InjectionUtils.injectHook +import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.ANDROID_AUTOMOTIVE_STRING +import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.AddCreateButtonViewFingerprint import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.util.exception import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -24,8 +24,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction dependencies = [ IntegrationsPatch::class, SettingsPatch::class, - ResolvePivotBarFingerprintsPatch::class, AddResourcesPatch::class, + NavigationBarHookPatch::class, ], compatiblePackages = [ CompatiblePackage( @@ -41,9 +41,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37", ], ), ], @@ -72,53 +76,7 @@ object NavigationButtonsPatch : BytecodePatch( ), ) - /* - * Resolve fingerprints - */ - - val initializeButtonsResult = InitializeButtonsFingerprint.result!! - - val fingerprintResults = - arrayOf(PivotBarEnumFingerprint, PivotBarButtonsViewFingerprint) - .onEach { - if (!it.resolve( - context, - initializeButtonsResult.mutableMethod, - initializeButtonsResult.mutableClass, - ) - ) { - throw it.exception - } - } - .map { it.result!!.scanResult.patternScanResult!! } - - val enumScanResult = fingerprintResults[0] - val buttonViewResult = fingerprintResults[1] - - val enumHookInsertIndex = enumScanResult.startIndex + 2 - val buttonHookInsertIndex = buttonViewResult.endIndex - - /* - * Inject hooks - */ - - val enumHook = "sput-object v$REGISTER_TEMPLATE_REPLACEMENT, " + - "$INTEGRATIONS_CLASS_DESCRIPTOR->lastNavigationButton:Ljava/lang/Enum;" - val buttonHook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " + - "$INTEGRATIONS_CLASS_DESCRIPTOR->hideButton(Landroid/view/View;)V" - - // Inject bottom to top to not mess up the indices - mapOf( - buttonHook to buttonHookInsertIndex, - enumHook to enumHookInsertIndex, - ).forEach { (hook, insertIndex) -> - initializeButtonsResult.mutableMethod.injectHook(hook, insertIndex) - } - - /* - * Hide create or switch it with notifications buttons. - */ - + // Switch create with notifications button. AddCreateButtonViewFingerprint.result?.let { it.mutableMethod.apply { val stringIndex = it.scanResult.stringsScanResult!!.matches.find { match -> @@ -126,7 +84,8 @@ object NavigationButtonsPatch : BytecodePatch( }!!.index val conditionalCheckIndex = stringIndex - 1 - val conditionRegister = getInstruction(conditionalCheckIndex).registerA + val conditionRegister = + getInstruction(conditionalCheckIndex).registerA addInstructions( conditionalCheckIndex, @@ -138,26 +97,7 @@ object NavigationButtonsPatch : BytecodePatch( } } ?: throw AddCreateButtonViewFingerprint.exception - /* - * Resolve fingerprints - */ - - InitializeButtonsFingerprint.result!!.let { - if (!PivotBarCreateButtonViewFingerprint.resolve(context, it.mutableMethod, it.mutableClass)) { - throw PivotBarCreateButtonViewFingerprint.exception - } - } - - PivotBarCreateButtonViewFingerprint.result!!.apply { - val insertIndex = scanResult.patternScanResult!!.endIndex - - /* - * Inject hooks - */ - val hook = "invoke-static { v$REGISTER_TEMPLATE_REPLACEMENT }, " + - "$INTEGRATIONS_CLASS_DESCRIPTOR->hideCreateButton(Landroid/view/View;)V" - - mutableMethod.injectHook(hook, insertIndex) - } + // Hook navigation button created, in order to hide them. + NavigationBarHookPatch.hookNavigationButtonCreated(INTEGRATIONS_CLASS_DESCRIPTOR) } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt deleted file mode 100644 index eacab72b..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/ResolvePivotBarFingerprintsPatch.kt +++ /dev/null @@ -1,37 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.navigation - -import app.revanced.util.exception -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.PatchException -import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch -import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.InitializeButtonsFingerprint -import app.revanced.patches.youtube.layout.buttons.navigation.fingerprints.PivotBarConstructorFingerprint - -@Patch( - description = "Resolves necessary fingerprints.", - dependencies = [ResourceMappingPatch::class] -) -internal object ResolvePivotBarFingerprintsPatch : BytecodePatch( - setOf(PivotBarConstructorFingerprint) -) { - internal var imageOnlyTabResourceId: Long = -1 - - override fun execute(context: BytecodeContext) { - // imageOnlyTabResourceId is used in InitializeButtonsFingerprint fingerprint - ResourceMappingPatch.resourceMappings.find { it.type == "layout" && it.name == "image_only_tab" } - ?.let { imageOnlyTabResourceId = it.id } ?: throw PatchException("Failed to find resource") - - PivotBarConstructorFingerprint.result?.let { - // Resolve InitializeButtonsFingerprint on the class of the method - // which PivotBarConstructorFingerprint resolved to - if (!InitializeButtonsFingerprint.resolve( - context, - it.classDef - ) - ) throw InitializeButtonsFingerprint.exception - } ?: throw PivotBarConstructorFingerprint.exception - } - -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt deleted file mode 100644 index 7827a4f4..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarButtonsViewFingerprint.kt +++ /dev/null @@ -1,12 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object PivotBarButtonsViewFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL_RANGE, - Opcode.MOVE_RESULT_OBJECT, // target reference - Opcode.GOTO, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt deleted file mode 100644 index a32ee0cb..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarCreateButtonViewFingerprint.kt +++ /dev/null @@ -1,13 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object PivotBarCreateButtonViewFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_DIRECT_RANGE, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT_OBJECT, - Opcode.INVOKE_STATIC - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarEnumFingerprint.kt deleted file mode 100644 index df40cc9e..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarEnumFingerprint.kt +++ /dev/null @@ -1,15 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object PivotBarEnumFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_STATIC, - Opcode.MOVE_RESULT_OBJECT, - Opcode.IF_NEZ, // target reference - Opcode.SGET_OBJECT, - Opcode.INVOKE_VIRTUAL, - Opcode.MOVE_RESULT, - ) -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt deleted file mode 100644 index f97305c1..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/utils/InjectionUtils.kt +++ /dev/null @@ -1,30 +0,0 @@ -package app.revanced.patches.youtube.layout.buttons.navigation.utils - -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction -import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod -import com.android.tools.smali.dexlib2.Opcode.MOVE_RESULT_OBJECT -import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction - -internal object InjectionUtils { - const val REGISTER_TEMPLATE_REPLACEMENT: String = "REGISTER_INDEX" - - /** - * Injects an instruction into insertIndex of the hook. - * @param hook The hook to insert. - * @param insertIndex The index to insert the instruction at. - * [MOVE_RESULT_OBJECT] has to be the previous instruction before [insertIndex]. - */ - fun MutableMethod.injectHook(hook: String, insertIndex: Int) { - val injectTarget = this - - // Register to pass to the hook - val registerIndex = insertIndex - 1 // MOVE_RESULT_OBJECT is always the previous instruction - val register = injectTarget.getInstruction(registerIndex).registerA - - injectTarget.addInstruction( - insertIndex, - hook.replace("REGISTER_INDEX", register.toString()), - ) - } -} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch.kt index 7d16a8e3..b51f3270 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/player/hide/HidePlayerButtonsPatch.kt @@ -38,9 +38,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/AlbumCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/AlbumCardsPatch.kt index 674af6dd..b11b2443 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/AlbumCardsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/albumcards/AlbumCardsPatch.kt @@ -32,9 +32,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/BreakingNewsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/BreakingNewsPatch.kt index 0b7f0553..34e2232b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/BreakingNewsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/breakingnews/BreakingNewsPatch.kt @@ -32,9 +32,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt index cfff7f9e..9cdb9c9b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/comments/CommentsPatch.kt @@ -32,9 +32,13 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/CrowdfundingBoxPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/CrowdfundingBoxPatch.kt index 1985b5b8..b429d69a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/CrowdfundingBoxPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/crowdfundingbox/CrowdfundingBoxPatch.kt @@ -32,9 +32,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt index 68458d25..aecd7cf1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt @@ -35,9 +35,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/HideFilterBarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/HideFilterBarPatch.kt index 67a2e2d3..0a836aa5 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/HideFilterBarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/filterbar/HideFilterBarPatch.kt @@ -32,9 +32,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/HideFloatingMicrophoneButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/HideFloatingMicrophoneButtonPatch.kt index e7831935..1b4606c4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/HideFloatingMicrophoneButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/floatingmicrophone/HideFloatingMicrophoneButtonPatch.kt @@ -28,9 +28,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt index caf22e8a..0a4ea85b 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt @@ -28,9 +28,13 @@ import app.revanced.util.exception "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt index f72d80a3..5a7428d7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt @@ -12,6 +12,7 @@ import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.all.misc.resources.AddResourcesPatch import app.revanced.patches.shared.misc.settings.preference.InputType +import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting import app.revanced.patches.shared.misc.settings.preference.SwitchPreference @@ -20,8 +21,10 @@ import app.revanced.patches.youtube.layout.hide.general.fingerprints.ParseElemen import app.revanced.patches.youtube.layout.hide.general.fingerprints.PlayerOverlayFingerprint import app.revanced.patches.youtube.layout.hide.general.fingerprints.ShowWatermarkFingerprint import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch +import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch +import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch -import app.revanced.util.exception +import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction @@ -33,6 +36,8 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction LithoFilterPatch::class, SettingsPatch::class, AddResourcesPatch::class, + NavigationBarHookPatch::class, + PlayerTypeHookPatch::class // Used by Keyword Content filter. ], compatiblePackages = [ CompatiblePackage( @@ -48,9 +53,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37", ], ), ], @@ -65,6 +74,8 @@ object HideLayoutComponentsPatch : BytecodePatch( "Lapp/revanced/integrations/youtube/patches/components/DescriptionComponentsFilter;" private const val CUSTOM_FILTER_CLASS_NAME = "Lapp/revanced/integrations/youtube/patches/components/CustomFilter;" + private const val KEYWORD_FILTER_CLASS_NAME = + "Lapp/revanced/integrations/youtube/patches/components/KeywordContentFilter;" override fun execute(context: BytecodeContext) { AddResourcesPatch(this::class) @@ -90,6 +101,7 @@ object HideLayoutComponentsPatch : BytecodePatch( SwitchPreference("revanced_hide_emergency_box"), SwitchPreference("revanced_hide_expandable_chip"), SwitchPreference("revanced_hide_info_panels"), + SwitchPreference("revanced_hide_join_membership_button"), SwitchPreference("revanced_hide_medical_panels"), SwitchPreference("revanced_hide_quick_actions"), SwitchPreference("revanced_hide_related_videos"), @@ -104,7 +116,6 @@ object HideLayoutComponentsPatch : BytecodePatch( SwitchPreference("revanced_hide_feed_survey"), SwitchPreference("revanced_hide_for_you_shelf"), SwitchPreference("revanced_hide_image_shelf"), - SwitchPreference("revanced_hide_join_membership_button"), SwitchPreference("revanced_hide_latest_posts_ads"), SwitchPreference("revanced_hide_mix_playlists"), SwitchPreference("revanced_hide_movies_section"), @@ -113,6 +124,20 @@ object HideLayoutComponentsPatch : BytecodePatch( SwitchPreference("revanced_hide_search_result_shelf_header"), ) + SettingsPatch.PreferenceScreen.FEED.addPreferences( + PreferenceScreen( + key = "revanced_hide_keyword_content_screen", + sorting = Sorting.UNSORTED, + preferences = setOf( + SwitchPreference("revanced_hide_keyword_content_home"), + SwitchPreference("revanced_hide_keyword_content_subscriptions"), + SwitchPreference("revanced_hide_keyword_content_search"), + TextPreference("revanced_hide_keyword_content_phrases", inputType = InputType.TEXT_MULTI_LINE), + NonInteractivePreference("revanced_hide_keyword_content_about") + ) + ) + ) + SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences( SwitchPreference("revanced_hide_gray_separator"), PreferenceScreen( @@ -132,19 +157,19 @@ object HideLayoutComponentsPatch : BytecodePatch( LithoFilterPatch.addFilter(LAYOUT_COMPONENTS_FILTER_CLASS_DESCRIPTOR) LithoFilterPatch.addFilter(DESCRIPTION_COMPONENTS_FILTER_CLASS_NAME) + LithoFilterPatch.addFilter(KEYWORD_FILTER_CLASS_NAME) LithoFilterPatch.addFilter(CUSTOM_FILTER_CLASS_NAME) // region Mix playlists - ParseElementFromBufferFingerprint.result?.let { result -> - val returnEmptyComponentInstruction = - result.mutableMethod.getInstructions().last { it.opcode == Opcode.INVOKE_STATIC } + ParseElementFromBufferFingerprint.resultOrThrow().let { result -> + val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex result.mutableMethod.apply { - val consumeByteBufferIndex = result.scanResult.patternScanResult!!.startIndex val conversionContextRegister = getInstruction(consumeByteBufferIndex - 2).registerA val byteBufferRegister = getInstruction(consumeByteBufferIndex).registerD + val returnEmptyComponentInstruction = getInstructions().last { it.opcode == Opcode.INVOKE_STATIC } addInstructionsWithLabels( consumeByteBufferIndex, @@ -156,15 +181,15 @@ object HideLayoutComponentsPatch : BytecodePatch( ExternalLabel("return_empty_component", returnEmptyComponentInstruction), ) } - } ?: throw ParseElementFromBufferFingerprint.exception + } // endregion // region Watermark (legacy code for old versions of YouTube) ShowWatermarkFingerprint.also { - it.resolve(context, PlayerOverlayFingerprint.result?.classDef ?: throw PlayerOverlayFingerprint.exception) - }.result?.mutableMethod?.apply { + it.resolve(context, PlayerOverlayFingerprint.resultOrThrow().classDef) + }.resultOrThrow().mutableMethod.apply { val index = implementation!!.instructions.size - 5 removeInstruction(index) @@ -175,7 +200,7 @@ object HideLayoutComponentsPatch : BytecodePatch( move-result p2 """, ) - } ?: throw ShowWatermarkFingerprint.exception + } // endregion } diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt index 1b7772aa..7cb8d865 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt @@ -39,9 +39,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch.kt index b910c83c..91948d7f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/loadmorebutton/HideLoadMoreButtonPatch.kt @@ -28,9 +28,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt index bdc042ab..00d9dfe6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt @@ -33,9 +33,13 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt index 1e1c1d93..5758d813 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt @@ -30,9 +30,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt index 588367fd..8e8434af 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/seekbar/HideSeekbarPatch.kt @@ -35,9 +35,13 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt index 32de7918..e65eced6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt @@ -14,6 +14,8 @@ import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch import app.revanced.patches.youtube.layout.hide.shorts.fingerprints.* import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch +import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch +import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction @@ -25,7 +27,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction IntegrationsPatch::class, LithoFilterPatch::class, HideShortsComponentsResourcePatch::class, - ResourceMappingPatch::class + ResourceMappingPatch::class, + NavigationBarHookPatch::class, + PlayerTypeHookPatch::class ], compatiblePackages = [ CompatiblePackage( @@ -40,9 +44,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsResourcePatch.kt index 83528f34..8593cd05 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsResourcePatch.kt @@ -17,18 +17,33 @@ object HideShortsComponentsResourcePatch : ResourcePatch() { AddResourcesPatch(this::class) SettingsPatch.PreferenceScreen.SHORTS.addPreferences( - SwitchPreference("revanced_hide_shorts"), + SwitchPreference("revanced_hide_shorts_home"), + SwitchPreference("revanced_hide_shorts_subscriptions"), + SwitchPreference("revanced_hide_shorts_search"), + + // Shorts player components. + // Ideally each group should be ordered similar to how they appear in the UI + // since this Setting menu currently uses the ordering used here. + + // Vertical row of buttons on right side of the screen. + SwitchPreference("revanced_hide_shorts_like_button"), + SwitchPreference("revanced_hide_shorts_dislike_button"), + SwitchPreference("revanced_hide_shorts_comments_button"), + SwitchPreference("revanced_hide_shorts_share_button"), + SwitchPreference("revanced_hide_shorts_remix_button"), + SwitchPreference("revanced_hide_shorts_sound_button"), + + // Everything else. + SwitchPreference("revanced_hide_shorts_thanks_button"), SwitchPreference("revanced_hide_shorts_join_button"), SwitchPreference("revanced_hide_shorts_subscribe_button"), SwitchPreference("revanced_hide_shorts_subscribe_button_paused"), - SwitchPreference("revanced_hide_shorts_thanks_button"), - SwitchPreference("revanced_hide_shorts_comments_button"), - SwitchPreference("revanced_hide_shorts_remix_button"), - SwitchPreference("revanced_hide_shorts_share_button"), - SwitchPreference("revanced_hide_shorts_info_panel"), SwitchPreference("revanced_hide_shorts_channel_bar"), - SwitchPreference("revanced_hide_shorts_sound_button"), - SwitchPreference("revanced_hide_shorts_navigation_bar") + SwitchPreference("revanced_hide_shorts_info_panel"), + SwitchPreference("revanced_hide_shorts_full_video_link_label"), + SwitchPreference("revanced_hide_shorts_video_title"), + SwitchPreference("revanced_hide_shorts_sound_metadata_label"), + SwitchPreference("revanced_hide_shorts_navigation_bar"), ) ResourceMappingPatch.resourceMappings.find { @@ -42,4 +57,4 @@ object HideShortsComponentsResourcePatch : ResourcePatch() { it.type == "dimen" && it.name == "reel_player_right_cell_button_height" }.id } -} \ No newline at end of file +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/DisableSuggestedVideoEndScreenPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/DisableSuggestedVideoEndScreenPatch.kt index 9b6c1a8f..c939e786 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/DisableSuggestedVideoEndScreenPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/suggestedvideoendscreen/DisableSuggestedVideoEndScreenPatch.kt @@ -27,9 +27,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt index 17d96a2f..a3c731ef 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt @@ -28,9 +28,13 @@ import app.revanced.util.exception "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt index 47760116..58fade4e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt @@ -29,9 +29,13 @@ import app.revanced.util.exception "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt index 9dcbc49d..d5e1893a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/player/background/PlayerControlsBackgroundPatch.kt @@ -24,9 +24,13 @@ import org.w3c.dom.Element "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ], ), ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt index 93b9cc0c..783474eb 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt @@ -32,6 +32,7 @@ import app.revanced.patches.youtube.video.videoid.VideoIdPatch import app.revanced.util.exception import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -57,9 +58,13 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] @@ -88,8 +93,6 @@ object ReturnYouTubeDislikePatch : BytecodePatch( private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ReturnYouTubeDislikeFilterPatch;" - private fun MethodFingerprint.resultOrThrow() = result ?: throw exception - override fun execute(context: BytecodeContext) { // region Inject newVideoLoaded event handler to update dislikes when a new video is loaded. diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt index f981f8a5..3cd258b7 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt @@ -33,9 +33,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/RestoreOldSeekbarThumbnailsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/RestoreOldSeekbarThumbnailsPatch.kt index a300571e..77de2e75 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/RestoreOldSeekbarThumbnailsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/RestoreOldSeekbarThumbnailsPatch.kt @@ -29,9 +29,13 @@ import app.revanced.util.exception "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockBytecodePatch.kt index 201dbb76..52ab535e 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockBytecodePatch.kt @@ -42,9 +42,13 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt index eea41751..b4a64d79 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt @@ -32,9 +32,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt index 425adf11..7ed28781 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt @@ -38,9 +38,13 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt index 454cced2..b770c774 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/tabletminiplayer/TabletMiniPlayerPatch.kt @@ -37,9 +37,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ) ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch.kt index 3ac26ac9..ac69564d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemeBytecodePatch.kt @@ -41,9 +41,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt index 4c642c7b..4daa6248 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt @@ -23,7 +23,7 @@ import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.reques import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnSucceededFingerprint import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch -import app.revanced.util.exception +import app.revanced.util.resultOrThrow import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation @@ -53,9 +53,13 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ], ), ], @@ -144,11 +148,8 @@ object AlternativeThumbnailsPatch : BytecodePatch( NonInteractivePreference("revanced_alt_thumbnail_stills_about"), ) - fun MethodFingerprint.getResultOrThrow() = - result ?: throw exception - fun MethodFingerprint.alsoResolve(fingerprint: MethodFingerprint) = - also { resolve(context, fingerprint.getResultOrThrow().classDef) }.getResultOrThrow() + also { resolve(context, fingerprint.resultOrThrow().classDef) }.resultOrThrow() fun MethodFingerprint.resolveAndLetMutableMethod( fingerprint: MethodFingerprint, @@ -172,7 +173,7 @@ object AlternativeThumbnailsPatch : BytecodePatch( // The URL is required for the failure callback hook, but the URL field is obfuscated. // Add a helper get method that returns the URL field. - RequestFingerprint.getResultOrThrow().apply { + RequestFingerprint.resultOrThrow().apply { // The url is the only string field that is set inside the constructor. val urlFieldInstruction = mutableMethod.getInstructions().first { if (it.opcode != Opcode.IPUT_OBJECT) return@first false diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt index f30ce323..55c11096 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt @@ -33,9 +33,13 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt index 5e871159..123bbd35 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt @@ -28,9 +28,13 @@ import app.revanced.util.exception "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt index 9da25f79..aeb1788d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/ClientSpoofPatch.kt @@ -1,47 +1,86 @@ package app.revanced.patches.youtube.misc.fix.playback -import app.revanced.util.exception -import app.revanced.patcher.data.BytecodeContext -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction -import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.UserAgentHeaderBuilderFingerprint -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.all.misc.transformation.BaseTransformInstructionsPatch +import app.revanced.patches.all.misc.transformation.IMethodCall +import app.revanced.patches.all.misc.transformation.Instruction35cInfo +import app.revanced.patches.all.misc.transformation.filterMapInstruction35c +import app.revanced.util.getReference +import com.android.tools.smali.dexlib2.iface.ClassDef +import com.android.tools.smali.dexlib2.iface.Method +import com.android.tools.smali.dexlib2.iface.instruction.Instruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference @Patch( name = "Client spoof", - description = "Adds options to spoof the client to allow video playback.", - dependencies = [SpoofSignaturePatch::class], + description = "Spoofs the client to allow video playback.", compatiblePackages = [ - CompatiblePackage( - "com.google.android.youtube", [ - "18.48.39", - "18.49.37", - "19.01.34", - "19.02.39", - "19.03.35", - "19.03.36", - "19.04.37" - ] - ) - ] + CompatiblePackage("com.google.android.youtube"), + ], ) -object ClientSpoofPatch : BytecodePatch( - setOf(UserAgentHeaderBuilderFingerprint) -) { +object ClientSpoofPatch : BaseTransformInstructionsPatch() { private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube" + private const val USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE = + "Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;" - override fun execute(context: BytecodeContext) { - UserAgentHeaderBuilderFingerprint.result?.let { result -> - val insertIndex = result.scanResult.patternScanResult!!.endIndex - result.mutableMethod.apply { - val packageNameRegister = getInstruction(insertIndex).registerD + override fun filterMap( + classDef: ClassDef, + method: Method, + instruction: Instruction, + instructionIndex: Int, + ) = filterMapInstruction35c( + "Lapp/revanced/integrations", + classDef, + instruction, + instructionIndex, + ) - addInstruction(insertIndex, "const-string v$packageNameRegister, \"$ORIGINAL_PACKAGE_NAME\"") - } + override fun transform(mutableMethod: MutableMethod, entry: Instruction35cInfo) { + val (_, _, instructionIndex) = entry - } ?: throw UserAgentHeaderBuilderFingerprint.exception + // Replace the result of context.getPackageName(), if it is used in a user agent string. + mutableMethod.apply { + // After context.getPackageName() the result is moved to a register. + val targetRegister = ( + getInstruction(instructionIndex + 1) + as? OneRegisterInstruction ?: return + ).registerA + + // IndexOutOfBoundsException is not possible here, + // but no such occurrences are present in the app. + val referee = getInstruction(instructionIndex + 2).getReference()?.toString() + + // This can technically also match non-user agent string builder append methods, + // but no such occurrences are present in the app. + if (referee != USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE) { + return + } + + // Overwrite the result of context.getPackageName() with the original package name. + replaceInstruction( + instructionIndex + 1, + "const-string v$targetRegister, \"${ORIGINAL_PACKAGE_NAME}\"", + ) + } + } + + @Suppress("unused") + private enum class MethodCall( + override val definedClassName: String, + override val methodName: String, + override val methodParams: Array, + override val returnType: String, + ) : IMethodCall { + GetPackageName( + "Landroid/content/Context;", + "getPackageName", + emptyArray(), + "Ljava/lang/String;", + ), } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch.kt index 5a00c791..4e9a7833 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofSignaturePatch.kt @@ -13,21 +13,11 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.fix.playback.fingerprints.* -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ParamsMapPutFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplGeneralFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplLiveStreamFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.PlayerResponseModelImplRecommendedLevelFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.ScrubbedPreviewLayoutFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererDecoderRecommendedLevelFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererDecoderSpecFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardRendererSpecFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThumbnailFingerprint -import app.revanced.patches.youtube.misc.fix.playback.fingerprints.StoryboardThumbnailParentFingerprint import app.revanced.patches.youtube.misc.playertype.PlayerTypeHookPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.video.information.VideoInformationPatch import app.revanced.patches.youtube.video.playerresponse.PlayerResponseMethodHookPatch -import app.revanced.util.* +import app.revanced.util.exception import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction @@ -43,6 +33,7 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction AddResourcesPatch::class, ], ) +@Deprecated("This patch will be removed in the future.") object SpoofSignaturePatch : BytecodePatch( setOf( PlayerResponseModelImplGeneralFingerprint, diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/UserAgentHeaderBuilderFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/UserAgentHeaderBuilderFingerprint.kt deleted file mode 100644 index 0d593ab8..00000000 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/fingerprints/UserAgentHeaderBuilderFingerprint.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.revanced.patches.youtube.misc.fix.playback.fingerprints - -import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode - -internal object UserAgentHeaderBuilderFingerprint : MethodFingerprint( - parameters = listOf("L", "L", "L"), - opcodes = listOf(Opcode.MOVE_RESULT_OBJECT, Opcode.INVOKE_VIRTUAL), - strings = listOf("(Linux; U; Android "), -) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt index a5be9adb..ff290235 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt @@ -6,12 +6,11 @@ import app.revanced.patches.youtube.layout.buttons.cast.HideCastButtonPatch import app.revanced.patches.youtube.misc.fix.playback.ClientSpoofPatch import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_NAME import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME -import app.revanced.patches.youtube.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorOption +import app.revanced.patches.youtube.misc.gms.GmsCoreSupportResourcePatch.gmsCoreVendorGroupIdOption import app.revanced.patches.youtube.misc.gms.fingerprints.* import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.shared.fingerprints.HomeActivityFingerprint - @Suppress("unused") object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( fromPackageName = YOUTUBE_PACKAGE_NAME, @@ -22,27 +21,32 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( GooglePlayUtilityFingerprint, CastDynamiteModuleFingerprint, CastDynamiteModuleV2Fingerprint, - CastContextFetchFingerprint + CastContextFetchFingerprint, ), mainActivityOnCreateFingerprint = HomeActivityFingerprint, integrationsPatchDependency = IntegrationsPatch::class, dependencies = setOf( HideCastButtonPatch::class, - ClientSpoofPatch::class + ClientSpoofPatch::class, ), gmsCoreSupportResourcePatch = GmsCoreSupportResourcePatch, compatiblePackages = setOf( CompatiblePackage( - "com.google.android.youtube", setOf( + "com.google.android.youtube", + setOf( "18.48.39", "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" - ) - ) + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37", + ), + ), ), fingerprints = setOf( ServiceCheckFingerprint, @@ -51,7 +55,7 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch( CastDynamiteModuleV2Fingerprint, CastContextFetchFingerprint, PrimeMethodFingerprint, - ) + ), ) { - override val gmsCoreVendor by gmsCoreVendorOption + override val gmsCoreVendor by gmsCoreVendorGroupIdOption } diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportResourcePatch.kt index 151e1b6c..730d921a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportResourcePatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportResourcePatch.kt @@ -8,12 +8,11 @@ import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_ import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME import app.revanced.patches.youtube.misc.settings.SettingsPatch - object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch( fromPackageName = YOUTUBE_PACKAGE_NAME, toPackageName = REVANCED_YOUTUBE_PACKAGE_NAME, spoofedPackageSignature = "24bb24c05e47e0aefa68a58a766179d9b613a600", - dependencies = setOf(SettingsPatch::class, AddResourcesPatch::class) + dependencies = setOf(SettingsPatch::class, AddResourcesPatch::class), ) { override fun execute(context: ResourceContext) { AddResourcesPatch(this::class) @@ -22,9 +21,9 @@ object GmsCoreSupportResourcePatch : BaseGmsCoreSupportResourcePatch( IntentPreference( "microg_settings", intent = IntentPreference.Intent("", "org.microg.gms.ui.SettingsActivity") { - "$gmsCoreVendor.android.gms" - } - ) + "$gmsCoreVendorGroupId.android.gms" + }, + ), ) super.execute(context) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt index b140c3b5..3228a7c6 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt @@ -30,9 +30,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt index a76331da..68286864 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt @@ -34,9 +34,13 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt index e85f11c4..37fa28b9 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/LithoFilterPatch.kt @@ -10,14 +10,20 @@ import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction import app.revanced.patcher.fingerprint.MethodFingerprint import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.annotation.Patch import app.revanced.patcher.util.smali.ExternalLabel import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.litho.filter.fingerprints.* +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.Instruction 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.reference.FieldReference +import com.android.tools.smali.dexlib2.iface.reference.TypeReference import java.io.Closeable @Patch( @@ -102,7 +108,11 @@ object LithoFilterPatch : BytecodePatch( val emptyComponentFieldIndex = builderMethodIndex + 2 bytesToComponentContextMethod.mutableMethod.apply { - val insertHookIndex = bytesToComponentContextMethod.scanResult.patternScanResult!!.endIndex + 1 + val insertHookIndex = indexOfFirstInstruction { + opcode == Opcode.IPUT_OBJECT && + getReference()?.type == "Ljava/lang/StringBuilder;" + } + 1 + if (insertHookIndex <= 0) throw PatchException("Could not find insert index") // region Get free registers that this patch uses. // Registers are overwritten right after they are used in this patch, therefore free to clobber. diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt index e8ad437f..419e0f91 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/litho/filter/fingerprints/ComponentContextParserFingerprint.kt @@ -1,13 +1,7 @@ package app.revanced.patches.youtube.misc.litho.filter.fingerprints import app.revanced.patcher.fingerprint.MethodFingerprint -import com.android.tools.smali.dexlib2.Opcode internal object ComponentContextParserFingerprint : MethodFingerprint( - opcodes = listOf( - Opcode.INVOKE_VIRTUAL, - Opcode.INVOKE_VIRTUAL, - Opcode.IPUT_OBJECT, - ), strings = listOf("Component was not found %s because it was removed due to duplicate converter bindings.") ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt index e83b4b49..4374262a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/minimizedplayback/MinimizedPlaybackPatch.kt @@ -39,9 +39,13 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt new file mode 100644 index 00000000..5b19cdc0 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookPatch.kt @@ -0,0 +1,130 @@ +package app.revanced.patches.youtube.misc.navigation + +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstructions +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch +import app.revanced.patches.youtube.misc.navigation.fingerprints.* +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstruction +import app.revanced.util.resultOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction +import com.android.tools.smali.dexlib2.iface.instruction.Instruction +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction +import com.android.tools.smali.dexlib2.iface.reference.MethodReference +import com.android.tools.smali.dexlib2.util.MethodUtil + +@Patch( + description = "Hooks the active navigation or search bar.", + dependencies = [ + IntegrationsPatch::class, + NavigationBarHookResourcePatch::class, + ], +) +@Suppress("unused") +object NavigationBarHookPatch : BytecodePatch( + setOf( + PivotBarConstructorFingerprint, + NavigationEnumFingerprint, + PivotBarButtonsCreateDrawableViewFingerprint, + PivotBarButtonsCreateResourceViewFingerprint, + NavigationBarHookCallbackFingerprint, + ActionBarSearchResultsFingerprint, + ), +) { + internal const val INTEGRATIONS_CLASS_DESCRIPTOR = + "Lapp/revanced/integrations/youtube/shared/NavigationBar;" + + internal const val INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR = + "Lapp/revanced/integrations/youtube/shared/NavigationBar\$NavigationButton;" + + override fun execute(context: BytecodeContext) { + fun MutableMethod.addHook(hook: Hook, insertPredicate: Instruction.() -> Boolean) { + val filtered = getInstructions().filter(insertPredicate) + if (filtered.isEmpty()) throw PatchException("Could not find insert indexes") + filtered.forEach { + val insertIndex = it.location.index + 2 + val register = getInstruction(insertIndex - 1).registerA + + addInstruction( + insertIndex, + "invoke-static { v$register }, " + + "$INTEGRATIONS_CLASS_DESCRIPTOR->${hook.methodName}(${hook.parameters})V", + ) + } + } + + InitializeButtonsFingerprint.apply { + resolve(context, PivotBarConstructorFingerprint.resultOrThrow().classDef) + }.resultOrThrow().mutableMethod.apply { + // Hook the current navigation bar enum value. Note, the 'You' tab does not have an enum value. + val navigationEnumClassName = NavigationEnumFingerprint.resultOrThrow().mutableClass.type + addHook(Hook.SET_LAST_APP_NAVIGATION_ENUM) { + opcode == Opcode.INVOKE_STATIC && + getReference()?.definingClass == navigationEnumClassName + } + + // Hook the creation of navigation tab views. + val drawableTabMethod = PivotBarButtonsCreateDrawableViewFingerprint.resultOrThrow().mutableMethod + addHook(Hook.NAVIGATION_TAB_LOADED) predicate@{ + MethodUtil.methodSignaturesMatch( + getReference() ?: return@predicate false, + drawableTabMethod, + ) + } + + val imageResourceTabMethod = PivotBarButtonsCreateResourceViewFingerprint.resultOrThrow().method + addHook(Hook.NAVIGATION_IMAGE_RESOURCE_TAB_LOADED) predicate@{ + MethodUtil.methodSignaturesMatch( + getReference() ?: return@predicate false, + imageResourceTabMethod, + ) + } + } + + // Hook the search bar. + + // Two different layouts are used at the hooked code. + // Insert before the first ViewGroup method call after inflating, + // so this works regardless which layout is used. + ActionBarSearchResultsFingerprint.resultOrThrow().mutableMethod.apply { + val instructionIndex = indexOfFirstInstruction { + opcode == Opcode.INVOKE_VIRTUAL && getReference()?.name == "setLayoutDirection" + } + + val viewRegister = getInstruction(instructionIndex).registerC + + addInstruction( + instructionIndex, + "invoke-static { v$viewRegister }, " + + "$INTEGRATIONS_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V", + ) + } + } + + val hookNavigationButtonCreated: (String) -> Unit by lazy { + val method = NavigationBarHookCallbackFingerprint.resultOrThrow().mutableMethod + + { integrationsClassDescriptor -> + method.addInstruction( + 0, + "invoke-static { p0, p1 }, " + + "$integrationsClassDescriptor->navigationTabCreated" + + "(${INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR}Landroid/view/View;)V", + ) + } + } + + private enum class Hook(val methodName: String, val parameters: String) { + SET_LAST_APP_NAVIGATION_ENUM("setLastAppNavigationEnum", "Ljava/lang/Enum;"), + NAVIGATION_TAB_LOADED("navigationTabLoaded", "Landroid/view/View;"), + NAVIGATION_IMAGE_RESOURCE_TAB_LOADED("navigationImageResourceTabLoaded", "Landroid/view/View;"), + SEARCH_BAR_RESULTS_VIEW_LOADED("searchBarResultsViewLoaded", "Landroid/view/View;"), + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt new file mode 100644 index 00000000..3841f2bf --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/NavigationBarHookResourcePatch.kt @@ -0,0 +1,24 @@ +package app.revanced.patches.youtube.misc.navigation + +import app.revanced.patcher.data.ResourceContext +import app.revanced.patcher.patch.ResourcePatch +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch + +@Patch( + dependencies = [ResourceMappingPatch::class] +) +internal object NavigationBarHookResourcePatch : ResourcePatch() { + internal var imageOnlyTabResourceId: Long = -1 + internal var actionBarSearchResultsViewMicId: Long = -1 + + override fun execute(context: ResourceContext) { + imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.first { + it.type == "layout" && it.name == "image_only_tab" + }.id + + actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.first { + it.type == "layout" && it.name == "action_bar_search_results_view_mic" + }.id + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt new file mode 100644 index 00000000..2ba8106f --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/ActionBarSearchResultsFingerprint.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.youtube.misc.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patches.youtube.misc.navigation.NavigationBarHookResourcePatch +import app.revanced.util.patch.LiteralValueFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object ActionBarSearchResultsFingerprint : LiteralValueFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "Landroid/view/View;", + parameters = listOf("Landroid/view/LayoutInflater;"), + literalSupplier = { NavigationBarHookResourcePatch.actionBarSearchResultsViewMicId } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/InitializeButtonsFingerprint.kt similarity index 52% rename from src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/InitializeButtonsFingerprint.kt index f64015c7..f91d1b36 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/InitializeButtonsFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/InitializeButtonsFingerprint.kt @@ -1,13 +1,16 @@ -package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints +package app.revanced.patches.youtube.misc.navigation.fingerprints import app.revanced.patcher.extensions.or -import app.revanced.patches.youtube.layout.buttons.navigation.ResolvePivotBarFingerprintsPatch +import app.revanced.patches.youtube.misc.navigation.NavigationBarHookResourcePatch import app.revanced.util.patch.LiteralValueFingerprint import com.android.tools.smali.dexlib2.AccessFlags +/** + * Resolves to the class found in [PivotBarConstructorFingerprint]. + */ internal object InitializeButtonsFingerprint : LiteralValueFingerprint( accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, returnType = "V", parameters = listOf(), - literalSupplier = { ResolvePivotBarFingerprintsPatch.imageOnlyTabResourceId } + literalSupplier = { NavigationBarHookResourcePatch.imageOnlyTabResourceId } ) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt new file mode 100644 index 00000000..1d69dfe8 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationBarHookCallbackFingerprint.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.youtube.misc.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import app.revanced.patches.youtube.layout.buttons.navigation.NavigationButtonsPatch +import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Integrations method, used for callback into to other patches. + * Specifically, [NavigationButtonsPatch]. + */ +internal object NavigationBarHookCallbackFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC, + returnType = "V", + parameters = listOf(NavigationBarHookPatch.INTEGRATIONS_NAVIGATION_BUTTON_DESCRIPTOR, "Landroid/view/View;"), + customFingerprint = { methodDef, _ -> + methodDef.name == "navigationTabCreatedCallback" && + methodDef.definingClass == NavigationBarHookPatch.INTEGRATIONS_CLASS_DESCRIPTOR + }, +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationEnumFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationEnumFingerprint.kt new file mode 100644 index 00000000..c084cf5e --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/NavigationEnumFingerprint.kt @@ -0,0 +1,21 @@ +package app.revanced.patches.youtube.misc.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +/** + * Resolves to the Enum class that looks up ordinal -> instance. + */ +internal object NavigationEnumFingerprint : MethodFingerprint( + accessFlags = AccessFlags.STATIC or AccessFlags.CONSTRUCTOR, + strings = listOf( + "PIVOT_HOME", + "TAB_SHORTS", + "CREATION_TAB_LARGE", + "PIVOT_SUBSCRIPTIONS", + "TAB_ACTIVITY", + "VIDEO_LIBRARY_WHITE", + "INCOGNITO_CIRCLE" + ) +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt new file mode 100644 index 00000000..0192f6e3 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateDrawableViewFingerprint.kt @@ -0,0 +1,17 @@ +package app.revanced.patches.youtube.misc.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object PivotBarButtonsCreateDrawableViewFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + // Method has different number of parameters in some app targets. + // Parameters are checked in custom fingerprint. + returnType = "Landroid/view/View;", + customFingerprint = { methodDef, classDef -> + classDef.type == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" && + // Only one method has a Drawable parameter. + methodDef.parameterTypes.firstOrNull() == "Landroid/graphics/drawable/Drawable;" + } +) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt new file mode 100644 index 00000000..cef0b517 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarButtonsCreateResourceViewFingerprint.kt @@ -0,0 +1,14 @@ +package app.revanced.patches.youtube.misc.navigation.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal object PivotBarButtonsCreateResourceViewFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "Z", "I", "L"), + returnType = "Landroid/view/View;", + customFingerprint = { _, classDef -> + classDef.type == "Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;" + } +) \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarConstructorFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarConstructorFingerprint.kt similarity index 82% rename from src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarConstructorFingerprint.kt rename to src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarConstructorFingerprint.kt index 37674a2b..57bc63e4 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/fingerprints/PivotBarConstructorFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/navigation/fingerprints/PivotBarConstructorFingerprint.kt @@ -1,4 +1,4 @@ -package app.revanced.patches.youtube.layout.buttons.navigation.fingerprints +package app.revanced.patches.youtube.misc.navigation.fingerprints import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/PlayerOverlaysHookPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/PlayerOverlaysHookPatch.kt index a48cc48c..c94ac05d 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/PlayerOverlaysHookPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/PlayerOverlaysHookPatch.kt @@ -3,30 +3,31 @@ package app.revanced.patches.youtube.misc.playeroverlay import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.patch.BytecodePatch -import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.playeroverlay.fingerprint.PlayerOverlaysOnFinishInflateFingerprint +import app.revanced.util.exception @Patch( - description = "Hook for adding custom overlays to the video player.", + description = "Hook for the video player overlay", dependencies = [IntegrationsPatch::class], - compatiblePackages = [ - CompatiblePackage("com.google.android.youtube", [ - "18.32.39" - ]) - ] ) + +/** + * Edit: This patch is not in use and may not work. + */ @Suppress("unused") -object PlayerOverlaysHookPatch : BytecodePatch( // TODO: delete this unused outdated patch and its integration code. +object PlayerOverlaysHookPatch : BytecodePatch( setOf(PlayerOverlaysOnFinishInflateFingerprint) ) { + private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/PlayerOverlaysHookPatch;" + override fun execute(context: BytecodeContext) { - // hook YouTubePlayerOverlaysLayout.onFinishInflate() - val method = PlayerOverlaysOnFinishInflateFingerprint.result!!.mutableMethod - method.addInstruction( - method.implementation!!.instructions.size - 2, - "invoke-static { p0 }, Lapp/revanced/integrations/youtube/patches/PlayerOverlaysHookPatch;->YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava/lang/Object;)V" - ) + PlayerOverlaysOnFinishInflateFingerprint.result?.mutableMethod?.apply { + addInstruction( + implementation!!.instructions.lastIndex, + "invoke-static { p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->playerOverlayInflated(Landroid/view/ViewGroup;)V" + ) + } ?: throw PlayerOverlaysOnFinishInflateFingerprint.exception } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt index 1d40fc36..11658c95 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/playeroverlay/fingerprint/PlayerOverlaysOnFinishInflateFingerprint.kt @@ -1,10 +1,14 @@ package app.revanced.patches.youtube.misc.playeroverlay.fingerprint - +import app.revanced.patcher.extensions.or import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags internal object PlayerOverlaysOnFinishInflateFingerprint : MethodFingerprint( + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + returnType = "V", customFingerprint = { methodDef, _ -> - methodDef.definingClass.endsWith("YouTubePlayerOverlaysLayout;") && methodDef.name == "onFinishInflate" - } + methodDef.definingClass.endsWith("/YouTubePlayerOverlaysLayout;") + && methodDef.name == "onFinishInflate" + }, ) diff --git a/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt index 06c737fe..28404a8f 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt @@ -35,9 +35,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/HDRBrightnessPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/HDRBrightnessPatch.kt index cb255b32..31141a31 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/HDRBrightnessPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/hdrbrightness/HDRBrightnessPatch.kt @@ -10,17 +10,19 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch import app.revanced.patches.youtube.misc.settings.SettingsPatch import app.revanced.patches.youtube.video.hdrbrightness.fingerprints.HDRBrightnessFingerprint +import app.revanced.util.exception 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 +@Deprecated("Patch is obsolete and the hooked code is no longer present in 19.09+") @Patch( - name = "HDR auto brightness", description = "Adds an option to make the brightness of HDR videos follow the system default.", dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class], compatiblePackages = [ CompatiblePackage( - "com.google.android.youtube", [ + "com.google.android.youtube", + [ "18.32.39", "18.37.36", "18.38.44", @@ -31,41 +33,49 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + // 19.09+ is dramatically different and the patched code is not present. ] ) ] ) @Suppress("unused") object HDRBrightnessPatch : BytecodePatch( - setOf(HDRBrightnessFingerprint) + setOf(HDRBrightnessFingerprint), ) { override fun execute(context: BytecodeContext) { AddResourcesPatch(this::class) + if (HDRBrightnessFingerprint.result == null) throw HDRBrightnessFingerprint.exception + SettingsPatch.PreferenceScreen.VIDEO.addPreferences( - SwitchPreference("revanced_hdr_auto_brightness") + SwitchPreference("revanced_hdr_auto_brightness"), ) - val method = HDRBrightnessFingerprint.result!!.mutableMethod - - method.implementation!!.instructions.filter { instruction -> - val fieldReference = (instruction as? ReferenceInstruction)?.reference as? FieldReference - fieldReference?.let { it.name == "screenBrightness" } == true - }.forEach { instruction -> - val brightnessRegisterIndex = method.implementation!!.instructions.indexOf(instruction) - val register = (instruction as TwoRegisterInstruction).registerA - - val insertIndex = brightnessRegisterIndex + 1 - method.addInstructions( - insertIndex, - """ - invoke-static {v$register}, Lapp/revanced/integrations/youtube/patches/HDRAutoBrightnessPatch;->getHDRBrightness(F)F - move-result v$register - """ - ) - } + // FIXME + // One of the changes made here effectively does nothing: + // It calls getHDRBrightness() and ignores the results. + HDRBrightnessFingerprint.result?.mutableMethod?.apply { + implementation!!.instructions.filter { instruction -> + ((instruction as? ReferenceInstruction)?.reference as? FieldReference) + ?.name == "screenBrightness" + }.forEach { instruction -> + val brightnessRegisterIndex = implementation!!.instructions.indexOf(instruction) + val register = (instruction as TwoRegisterInstruction).registerA + val insertIndex = brightnessRegisterIndex + 1 + addInstructions( + insertIndex, + """ + invoke-static {v$register}, Lapp/revanced/integrations/youtube/patches/HDRAutoBrightnessPatch;->getHDRBrightness(F)F + move-result v$register + """, + ) + } + } ?: throw HDRBrightnessFingerprint.exception } } diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt index 160e81df..858d30b1 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/quality/RememberVideoQualityPatch.kt @@ -39,9 +39,13 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt index bbaf5371..f8e9330a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt @@ -19,9 +19,13 @@ import app.revanced.patches.youtube.video.speed.remember.RememberPlaybackSpeedPa "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37", + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ], ), ], diff --git a/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt index e45d3095..25b01b1a 100644 --- a/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtube/video/videoqualitymenu/RestoreOldVideoQualityMenuPatch.kt @@ -35,9 +35,13 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction "18.49.37", "19.01.34", "19.02.39", - "19.03.35", "19.03.36", - "19.04.37" + "19.04.38", + "19.05.36", + "19.06.39", + "19.07.40", + "19.08.36", + "19.09.37" ] ) ] diff --git a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/HideAdsPatch.kt b/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/HideAdsPatch.kt index 229a5b9a..dcb3311c 100644 --- a/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/HideAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/youtubevanced/ad/general/HideAdsPatch.kt @@ -1,6 +1,5 @@ package app.revanced.patches.youtubevanced.ad.general -import app.revanced.util.exception import app.revanced.patcher.data.BytecodeContext import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction @@ -9,17 +8,19 @@ import app.revanced.patcher.patch.annotation.CompatiblePackage import app.revanced.patcher.patch.annotation.Patch import app.revanced.patches.shared.misc.fix.verticalscroll.VerticalScrollPatch import app.revanced.patches.youtubevanced.ad.general.fingerprints.ContainsAdFingerprint +import app.revanced.util.exception import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c +@Deprecated("This patch is going to be removed in the future.") @Patch( - name = "Hide ads", description = "Removes general ads.", dependencies = [VerticalScrollPatch::class], - compatiblePackages = [CompatiblePackage("com.vanced.android.youtube")] + compatiblePackages = [CompatiblePackage("com.vanced.android.youtube")], + use = false, ) @Suppress("unused") object HideAdsPatch : BytecodePatch( - setOf(ContainsAdFingerprint) + setOf(ContainsAdFingerprint), ) { override fun execute(context: BytecodeContext) { ContainsAdFingerprint.result?.let { result -> @@ -40,14 +41,14 @@ object HideAdsPatch : BytecodePatch( "hero_promo_image", "statement_banner", "primetime_promo", - "carousel_footered_layout" + "carousel_footered_layout", ).forEach { component -> addInstructions( insertIndex, """ const-string v$adsListRegister, "$component" invoke-interface {v0, v$adsListRegister}, Ljava/util/List;->add(Ljava/lang/Object;)Z - """ + """, ) } } diff --git a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt index f47ae90d..8daf7770 100644 --- a/src/main/kotlin/app/revanced/util/BytecodeUtils.kt +++ b/src/main/kotlin/app/revanced/util/BytecodeUtils.kt @@ -15,6 +15,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction import com.android.tools.smali.dexlib2.iface.reference.Reference import com.android.tools.smali.dexlib2.util.MethodUtil + +fun MethodFingerprint.resultOrThrow() = result ?: throw exception + /** * The [PatchException] of failing to resolve a [MethodFingerprint]. * diff --git a/src/main/resources/addresources/values/strings.xml b/src/main/resources/addresources/values/strings.xml index c7461f62..b799eef2 100644 --- a/src/main/resources/addresources/values/strings.xml +++ b/src/main/resources/addresources/values/strings.xml @@ -167,9 +167,24 @@ Custom filter is disabled Custom filter List of component path builder strings to filter separated by new line - Invalid custom filter (must be ASCII only): %s Invalid custom filter: %s - Custom filter reset to default + Hide keyword content + Hide search and feed videos using keyword filters + Hide home videos by keywords + Videos in the home tab are filtered by keywords + Videos in the home tab are not filtered by keywords + Hide subscription videos by keywords + Videos in the subscriptions tab are filtered by keywords + Videos in the subscriptions tab are not filtered by keywords + Hide search results by keywords + Search results are filtered by keywords + Search results are not filtered by keywords + Keywords to hide + Keywords and phrases to hide, separated by new lines\n\nWords with uppercase letters in the middle must be entered with the casing (ie: iPhone, TikTok, LeBlanc) + About keyword filtering + Home/Subscription/Search results are filtered to hide content that matches keyword phrases\n\nLimitations\n• Some Shorts may not be hidden\n• Some UI components may not be hidden\n• Searching for a keyword may show no results + Invalid keyword. Cannot use: \'%s\' as a filter + Invalid keyword. \'%s\' is less than %s characters Hide general ads @@ -199,6 +214,7 @@ Hide merchandise banners Merchandise banners are hidden Merchandise banners are shown + Failed to hide full-screen ad. Disabling to prevent issues Hide YouTube Premium promotions @@ -226,12 +242,15 @@ Dialog will be shown This does not bypass the age restriction. It just accepts it automatically. - + External downloads Settings for using an external downloader Show external download button Download button shown in player Download button not shown in player + Override download action button + Download button opens your external downloader + Download button opens the native in-app downloader Downloader package name Package name of your installed external downloader app, such as NewPipe or Seal %s is not installed. Please install it. @@ -460,9 +479,15 @@ Thumbnail seekbar is shown - Hide Shorts in feed - Shorts are hidden - Shorts are shown + Hide Shorts in home feed + Shorts in home feed are hidden + Shorts in home feed are shown + Hide Shorts in subscription feed + Shorts in subscription feed are hidden + Shorts in subscription feed are shown + Hide Shorts in search results + Shorts in search results are hidden + Shorts in search results are shown Hide join button Join button is hidden Join button is shown @@ -475,6 +500,12 @@ Hide thanks button Thanks button is hidden Thanks button is shown + Hide like button + Like button is hidden + Like button is shown + Hide dislike button + Dislike button is hidden + Dislike button is shown Hide comments button Comments button is hidden Comments button is shown @@ -490,6 +521,15 @@ Hide channel bar Channel bar is hidden Channel bar is shown + Hide Shorts video title + Title is hidden + Title is shown + Hide sound metadata label + Label is hidden + Label is shown + Hide full video link label + Label is hidden + Label is shown Hide sound button Sound button is hidden Sound button is shown