mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2026-01-19 17:13:59 +00:00
Compare commits
29 Commits
v4.7.0-dev
...
v4.8.0-dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49db0cee1b | ||
|
|
531955a111 | ||
|
|
e53cc9bba9 | ||
|
|
fc43dd709f | ||
|
|
3a018ff002 | ||
|
|
86f11480e7 | ||
|
|
0190d5a5c9 | ||
|
|
50735fabbc | ||
|
|
653631703c | ||
|
|
2587508944 | ||
|
|
533f9a964d | ||
|
|
fb0b3bd673 | ||
|
|
96e17cf4de | ||
|
|
a7bd0b111e | ||
|
|
7ecd992def | ||
|
|
217d3c69ba | ||
|
|
e329e1dd1a | ||
|
|
6a8b669ba2 | ||
|
|
6fd46ad9b6 | ||
|
|
50ddb680ed | ||
|
|
cc7f79d903 | ||
|
|
57274b5435 | ||
|
|
8295b7a22e | ||
|
|
366f754a6a | ||
|
|
c272333adb | ||
|
|
ef6c00a520 | ||
|
|
58ce37b0d3 | ||
|
|
4b7e12f995 | ||
|
|
2e59965bb5 |
114
CHANGELOG.md
114
CHANGELOG.md
@@ -1,3 +1,117 @@
|
|||||||
|
# [4.8.0-dev.2](https://github.com/ReVanced/revanced-patches/compare/v4.8.0-dev.1...v4.8.0-dev.2) (2024-04-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Case patch option title correctly ([259c8b4](https://github.com/ReVanced/revanced-patches/commit/259c8b4e58df51d92d7e19417e13afa3848afc73))
|
||||||
|
|
||||||
|
# [4.8.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v4.7.0...v4.8.0-dev.1) (2024-04-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide video action buttons:** Remove obsolete `hide Shop button` ([#3057](https://github.com/ReVanced/revanced-patches/issues/3057)) ([b5e34f3](https://github.com/ReVanced/revanced-patches/commit/b5e34f3aabc1d9df8c41f92251618243caecdc9f))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Hide Shorts components:** Hide like / dislike button in video ads ([#3062](https://github.com/ReVanced/revanced-patches/issues/3062)) ([1296985](https://github.com/ReVanced/revanced-patches/commit/12969853adfe530eb6006df38e1a5aa30b28fdf9))
|
||||||
|
|
||||||
|
# [4.7.0](https://github.com/ReVanced/revanced-patches/compare/v4.6.0...v4.7.0) (2024-04-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **Tumblr - Fix old versions:** Improve reliability by removing remnances of Tumblr Live ([#2988](https://github.com/ReVanced/revanced-patches/issues/2988)) ([897b4db](https://github.com/ReVanced/revanced-patches/commit/897b4dbce984270ae1fd7de5bd30bd05153e45f2))
|
||||||
|
* **YouTube - GmsCore support:** Prompt to disable battery optimizations, if not done already ([#2958](https://github.com/ReVanced/revanced-patches/issues/2958)) ([82acb84](https://github.com/ReVanced/revanced-patches/commit/82acb84b5f6ff0722a2eb080b53da9dd3622502f))
|
||||||
|
* **YouTube - Hide ads:** rename `Hide paid content` to `Hide paid promotion label` ([#3026](https://github.com/ReVanced/revanced-patches/issues/3026)) ([17e4ac9](https://github.com/ReVanced/revanced-patches/commit/17e4ac978a2f109fd62469a3163b636cd63c55ae))
|
||||||
|
* **YouTube - Hide load more button:** Include patch with `Hide layout components`, and hide button only in search feed ([#2959](https://github.com/ReVanced/revanced-patches/issues/2959)) ([b007e8e](https://github.com/ReVanced/revanced-patches/commit/b007e8e06a3afad79b40bec1c6a14604f059049c))
|
||||||
|
* **YouTube - Hide Shorts components:** Correctly hide Shorts if navigation tab is changed using device back button ([#3007](https://github.com/ReVanced/revanced-patches/issues/3007)) ([e5848e9](https://github.com/ReVanced/revanced-patches/commit/e5848e99c4cc838595164ef673a77fe60d28086b))
|
||||||
|
* **YouTube - Player flyout menu:** Add hide Lock screen menu ([#2985](https://github.com/ReVanced/revanced-patches/issues/2985)) ([308de4a](https://github.com/ReVanced/revanced-patches/commit/308de4a63ca99b8d30d6b3242f98d6f0e2aefb37))
|
||||||
|
* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([9d6f305](https://github.com/ReVanced/revanced-patches/commit/9d6f305b7c923e62b89581d221fedbe1e3f81835))
|
||||||
|
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([80de996](https://github.com/ReVanced/revanced-patches/commit/80de99666555694670529bbfe2e0be7a14d66555))
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([3c95aac](https://github.com/ReVanced/revanced-patches/commit/3c95aac838693b354d3a7b0e3dc57c6da5adfa9e))
|
||||||
|
* **Amazon:** Add `Always allow deep-linking` patch ([#3000](https://github.com/ReVanced/revanced-patches/issues/3000)) ([a92b7fb](https://github.com/ReVanced/revanced-patches/commit/a92b7fb43c8b1b45577360cdc6d883fe2815c2f2))
|
||||||
|
* **Strava - Unlock subscription:** Remove compatible version constraint ([80a5599](https://github.com/ReVanced/revanced-patches/commit/80a55991683d7b22626224fa2935a5bf9bfcbfee))
|
||||||
|
* **Twitter:** Add `Sanitize sharing links` patch ([#3003](https://github.com/ReVanced/revanced-patches/issues/3003)) ([186b887](https://github.com/ReVanced/revanced-patches/commit/186b8874157eef1b882b05d491ba1d4ca2809535))
|
||||||
|
* **YouTube - Hide layout components:** Add option to hide horizontal shelves ([#2951](https://github.com/ReVanced/revanced-patches/issues/2951)) ([9ae0650](https://github.com/ReVanced/revanced-patches/commit/9ae0650c0005d882299996aa442410bab4261395))
|
||||||
|
* **YouTube - Hide layout components:** Hide playables ([8423515](https://github.com/ReVanced/revanced-patches/commit/842351548baa33737db09be1cbca9f87c1951341))
|
||||||
|
* **YouTube - Hide Shorts components:** Hide `Shop`, `Location` and `Save sound to playlist` buttons ([#3018](https://github.com/ReVanced/revanced-patches/issues/3018)) ([5210ac4](https://github.com/ReVanced/revanced-patches/commit/5210ac431c191987264865bf8e789ea9f3fdd360))
|
||||||
|
* **YouTube - Hide Shorts components:** Hide tagged products, hide search suggestions ([#3019](https://github.com/ReVanced/revanced-patches/issues/3019)) ([e0d2fe5](https://github.com/ReVanced/revanced-patches/commit/e0d2fe5bd2e681b9a5252a8e4ad582cc019b1606))
|
||||||
|
* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([f6c3bc4](https://github.com/ReVanced/revanced-patches/commit/f6c3bc43190d33e06f49b74fc056d26da1bb014a))
|
||||||
|
* **YouTube:** Add 'About' preference to settings menu ([#2981](https://github.com/ReVanced/revanced-patches/issues/2981)) ([5abf894](https://github.com/ReVanced/revanced-patches/commit/5abf89444a3e6a211ec03c242eb9a7847542b08c))
|
||||||
|
* **YouTube:** Match overlay icons style to YouTube ([#3023](https://github.com/ReVanced/revanced-patches/issues/3023)) ([6849393](https://github.com/ReVanced/revanced-patches/commit/684939314be3d0d43482f229b2adb033e7aa492a))
|
||||||
|
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([730f3e3](https://github.com/ReVanced/revanced-patches/commit/730f3e3a7e058b60f9a8130980ecb0a747fa0a8a))
|
||||||
|
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([10e170a](https://github.com/ReVanced/revanced-patches/commit/10e170a7302fdb585efee663ca13c814aea46c54))
|
||||||
|
|
||||||
|
# [4.7.0-dev.16](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.15...v4.7.0-dev.16) (2024-04-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Swipe controls:** Save and restore brightness and add auto-brightness toggle ([#2996](https://github.com/ReVanced/revanced-patches/issues/2996)) ([f6c3bc4](https://github.com/ReVanced/revanced-patches/commit/f6c3bc43190d33e06f49b74fc056d26da1bb014a))
|
||||||
|
|
||||||
|
# [4.7.0-dev.15](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.14...v4.7.0-dev.15) (2024-04-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube:** Support version `19.09.38`, `19.10.39` and `19.11.43` ([#2971](https://github.com/ReVanced/revanced-patches/issues/2971)) ([730f3e3](https://github.com/ReVanced/revanced-patches/commit/730f3e3a7e058b60f9a8130980ecb0a747fa0a8a))
|
||||||
|
|
||||||
|
# [4.7.0-dev.14](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.13...v4.7.0-dev.14) (2024-04-20)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YT Music - Hide 'Get Music Premium' label:** Remove occurences of label in settings ([#3046](https://github.com/ReVanced/revanced-patches/issues/3046)) ([10e170a](https://github.com/ReVanced/revanced-patches/commit/10e170a7302fdb585efee663ca13c814aea46c54))
|
||||||
|
|
||||||
|
# [4.7.0-dev.13](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.12...v4.7.0-dev.13) (2024-04-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube Music - Remove upgrade button:** Fix compatibility with latest versions ([#3045](https://github.com/ReVanced/revanced-patches/issues/3045)) ([80de996](https://github.com/ReVanced/revanced-patches/commit/80de99666555694670529bbfe2e0be7a14d66555))
|
||||||
|
|
||||||
|
# [4.7.0-dev.12](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.11...v4.7.0-dev.12) (2024-04-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Add `Hex` patch ([#3034](https://github.com/ReVanced/revanced-patches/issues/3034)) ([3c95aac](https://github.com/ReVanced/revanced-patches/commit/3c95aac838693b354d3a7b0e3dc57c6da5adfa9e))
|
||||||
|
|
||||||
|
# [4.7.0-dev.11](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.10...v4.7.0-dev.11) (2024-04-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Spoof device dimensions:** Warn about potential performance issues ([#3039](https://github.com/ReVanced/revanced-patches/issues/3039)) ([9d6f305](https://github.com/ReVanced/revanced-patches/commit/9d6f305b7c923e62b89581d221fedbe1e3f81835))
|
||||||
|
|
||||||
|
# [4.7.0-dev.10](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.9...v4.7.0-dev.10) (2024-04-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube:** Add 'About' preference to settings menu ([#2981](https://github.com/ReVanced/revanced-patches/issues/2981)) ([5abf894](https://github.com/ReVanced/revanced-patches/commit/5abf89444a3e6a211ec03c242eb9a7847542b08c))
|
||||||
|
* **YouTube:** Match overlay icons style to YouTube ([#3023](https://github.com/ReVanced/revanced-patches/issues/3023)) ([6849393](https://github.com/ReVanced/revanced-patches/commit/684939314be3d0d43482f229b2adb033e7aa492a))
|
||||||
|
|
||||||
|
# [4.7.0-dev.9](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.8...v4.7.0-dev.9) (2024-04-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **YouTube - Hide ads:** rename `Hide paid content` to `Hide paid promotion label` ([#3026](https://github.com/ReVanced/revanced-patches/issues/3026)) ([17e4ac9](https://github.com/ReVanced/revanced-patches/commit/17e4ac978a2f109fd62469a3163b636cd63c55ae))
|
||||||
|
|
||||||
|
# [4.7.0-dev.8](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.7...v4.7.0-dev.8) (2024-04-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* **YouTube - Hide Shorts components:** Hide tagged products, hide search suggestions ([#3019](https://github.com/ReVanced/revanced-patches/issues/3019)) ([e0d2fe5](https://github.com/ReVanced/revanced-patches/commit/e0d2fe5bd2e681b9a5252a8e4ad582cc019b1606))
|
||||||
|
|
||||||
# [4.7.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.6...v4.7.0-dev.7) (2024-04-14)
|
# [4.7.0-dev.7](https://github.com/ReVanced/revanced-patches/compare/v4.7.0-dev.6...v4.7.0-dev.7) (2024-04-14)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ public final class app/revanced/patches/all/misc/debugging/EnableAndroidDebuggin
|
|||||||
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/all/misc/hex/HexPatch : app/revanced/patches/shared/misc/hex/BaseHexPatch {
|
||||||
|
public fun <init> ()V
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch : app/revanced/patcher/patch/ResourcePatch {
|
public final class app/revanced/patches/all/misc/network/OverrideCertificatePinningPatch : app/revanced/patcher/patch/ResourcePatch {
|
||||||
public static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch;
|
public static final field INSTANCE Lapp/revanced/patches/all/misc/network/OverrideCertificatePinningPatch;
|
||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
@@ -669,6 +673,21 @@ public abstract class app/revanced/patches/shared/misc/gms/BaseGmsCoreSupportRes
|
|||||||
protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String;
|
protected final fun getGmsCoreVendorGroupId ()Ljava/lang/String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract class app/revanced/patches/shared/misc/hex/BaseHexPatch : app/revanced/patcher/patch/RawResourcePatch {
|
||||||
|
public fun <init> ()V
|
||||||
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
|
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement {
|
||||||
|
public static final field Companion Lapp/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion;
|
||||||
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
|
||||||
|
public final fun replacePattern ([B)V
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/shared/misc/hex/BaseHexPatch$Replacement$Companion {
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch {
|
public abstract class app/revanced/patches/shared/misc/integrations/BaseIntegrationsPatch : app/revanced/patcher/patch/BytecodePatch {
|
||||||
public fun <init> (Ljava/lang/String;Ljava/util/Set;)V
|
public fun <init> (Ljava/lang/String;Ljava/util/Set;)V
|
||||||
public fun <init> (Ljava/util/Set;)V
|
public fun <init> (Ljava/util/Set;)V
|
||||||
@@ -705,6 +724,7 @@ public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch
|
|||||||
public static final field INSTANCE Lapp/revanced/patches/shared/misc/mapping/ResourceMappingPatch;
|
public static final field INSTANCE Lapp/revanced/patches/shared/misc/mapping/ResourceMappingPatch;
|
||||||
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
public synthetic fun execute (Lapp/revanced/patcher/data/Context;)V
|
||||||
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
public fun execute (Lapp/revanced/patcher/data/ResourceContext;)V
|
||||||
|
public final fun get (Ljava/lang/String;Ljava/lang/String;)J
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch$ResourceElement {
|
public final class app/revanced/patches/shared/misc/mapping/ResourceMappingPatch$ResourceElement {
|
||||||
@@ -844,6 +864,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/ListPref
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/shared/misc/settings/preference/NonInteractivePreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
public final class app/revanced/patches/shared/misc/settings/preference/NonInteractivePreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
|
||||||
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
|
||||||
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
|
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
|
||||||
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||||
public final fun getSelectable ()Z
|
public final fun getSelectable ()Z
|
||||||
@@ -1825,11 +1847,12 @@ public final class app/revanced/patches/yuka/misc/unlockpremium/UnlockPremiumPat
|
|||||||
|
|
||||||
public final class app/revanced/util/BytecodeUtilsKt {
|
public final class app/revanced/util/BytecodeUtilsKt {
|
||||||
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
|
public static final fun containsWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)Z
|
||||||
public static final fun findIndexForIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
|
||||||
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
|
public static final fun findMutableMethodOf (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lcom/android/tools/smali/dexlib2/iface/Method;)Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;
|
||||||
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
|
public static final fun getException (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/patch/PatchException;
|
||||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
|
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 indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||||
|
public static final fun indexOfIdResource (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
||||||
|
public static final fun indexOfIdResourceOrThrow (Lcom/android/tools/smali/dexlib2/iface/Method;Ljava/lang/String;)I
|
||||||
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
|
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 resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
|
||||||
public static final fun returnEarly (Ljava/util/List;Z)V
|
public static final fun returnEarly (Ljava/util/List;Z)V
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
org.gradle.caching = true
|
org.gradle.caching = true
|
||||||
kotlin.code.style = official
|
kotlin.code.style = official
|
||||||
version = 4.7.0-dev.7
|
version = 4.8.0-dev.2
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package app.revanced.patches.all.misc.hex
|
||||||
|
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.registerNewPatchOption
|
||||||
|
import app.revanced.patches.shared.misc.hex.BaseHexPatch
|
||||||
|
import app.revanced.util.Utils.trimIndentMultiline
|
||||||
|
import app.revanced.patcher.patch.Patch as PatchClass
|
||||||
|
|
||||||
|
@Patch(
|
||||||
|
name = "Hex",
|
||||||
|
description = "Replaces a hexadecimal patterns of bytes of files in an APK.",
|
||||||
|
use = false,
|
||||||
|
)
|
||||||
|
@Suppress("unused")
|
||||||
|
class HexPatch : BaseHexPatch() {
|
||||||
|
// TODO: Instead of stringArrayOption, use a custom option type to work around
|
||||||
|
// https://github.com/ReVanced/revanced-library/issues/48.
|
||||||
|
// Replace the custom option type with a stringArrayOption once the issue is resolved.
|
||||||
|
private val replacementsOption by registerNewPatchOption<PatchClass<*>, List<String>>(
|
||||||
|
key = "replacements",
|
||||||
|
title = "Replacements",
|
||||||
|
description = """
|
||||||
|
Hexadecimal patterns to search for and replace with another in a target file.
|
||||||
|
|
||||||
|
A pattern is a sequence of case insensitive strings, each representing hexadecimal bytes, separated by spaces.
|
||||||
|
An example pattern is 'aa 01 02 FF'.
|
||||||
|
|
||||||
|
Every pattern must be followed by a pipe ('|'), the replacement pattern,
|
||||||
|
another pipe ('|'), and the path to the file to make the changes in relative to the APK root.
|
||||||
|
The replacement pattern must have the same length as the original pattern.
|
||||||
|
|
||||||
|
Full example of a valid input:
|
||||||
|
'aa 01 02 FF|00 00 00 00|path/to/file'
|
||||||
|
""".trimIndentMultiline(),
|
||||||
|
required = true,
|
||||||
|
valueType = "StringArray",
|
||||||
|
)
|
||||||
|
|
||||||
|
override val replacements
|
||||||
|
get() = replacementsOption!!.map { from ->
|
||||||
|
val (pattern, replacementPattern, targetFilePath) = try {
|
||||||
|
from.split("|", limit = 3)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw PatchException(
|
||||||
|
"Invalid input: $from.\n" +
|
||||||
|
"Every pattern must be followed by a pipe ('|'), " +
|
||||||
|
"the replacement pattern, another pipe ('|'), " +
|
||||||
|
"and the path to the file to make the changes in relative to the APK root. ",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Replacement(pattern, replacementPattern, targetFilePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,23 +2,28 @@ package app.revanced.patches.music.layout.premium
|
|||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
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.getInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
|
import app.revanced.patches.music.layout.premium.fingerprints.HideGetPremiumFingerprint
|
||||||
|
import app.revanced.patches.music.layout.premium.fingerprints.MembershipSettingsFingerprint
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Hide 'Get Music Premium' label",
|
name = "Hide 'Get Music Premium' label",
|
||||||
description = "Hides the red \"Get Music Premium\" label from the account menu.",
|
description = "Hides the \"Get Music Premium\" label from the account menu and settings.",
|
||||||
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
compatiblePackages = [CompatiblePackage("com.google.android.apps.youtube.music")],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object HideGetPremiumPatch : BytecodePatch(
|
object HideGetPremiumPatch : BytecodePatch(
|
||||||
setOf(HideGetPremiumFingerprint),
|
setOf(
|
||||||
|
HideGetPremiumFingerprint,
|
||||||
|
MembershipSettingsFingerprint,
|
||||||
|
),
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
HideGetPremiumFingerprint.result?.let {
|
HideGetPremiumFingerprint.result?.let {
|
||||||
@@ -41,5 +46,13 @@ object HideGetPremiumPatch : BytecodePatch(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} ?: throw HideGetPremiumFingerprint.exception
|
} ?: throw HideGetPremiumFingerprint.exception
|
||||||
|
|
||||||
|
MembershipSettingsFingerprint.result?.mutableMethod?.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const/4 v0, 0x0
|
||||||
|
return-object v0
|
||||||
|
""",
|
||||||
|
) ?: throw MembershipSettingsFingerprint.exception
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ internal object HideGetPremiumFingerprint : MethodFingerprint(
|
|||||||
listOf(
|
listOf(
|
||||||
Opcode.IF_NEZ,
|
Opcode.IF_NEZ,
|
||||||
Opcode.CONST_16,
|
Opcode.CONST_16,
|
||||||
|
Opcode.GOTO,
|
||||||
|
Opcode.NOP,
|
||||||
Opcode.INVOKE_VIRTUAL,
|
Opcode.INVOKE_VIRTUAL,
|
||||||
),
|
),
|
||||||
listOf("FEmusic_history", "FEmusic_offline"),
|
listOf("FEmusic_history", "FEmusic_offline"),
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
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 MembershipSettingsFingerprint : MethodFingerprint(
|
||||||
|
returnType = "Ljava/lang/CharSequence;",
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.INVOKE_INTERFACE,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.INVOKE_VIRTUAL,
|
||||||
|
Opcode.MOVE_RESULT_OBJECT,
|
||||||
|
Opcode.IF_EQZ,
|
||||||
|
Opcode.IGET_OBJECT
|
||||||
|
)
|
||||||
|
)
|
||||||
@@ -13,6 +13,7 @@ internal object PivotBarConstructorFingerprint : MethodFingerprint(
|
|||||||
Opcode.CHECK_CAST,
|
Opcode.CHECK_CAST,
|
||||||
Opcode.INVOKE_INTERFACE,
|
Opcode.INVOKE_INTERFACE,
|
||||||
Opcode.GOTO,
|
Opcode.GOTO,
|
||||||
|
Opcode.NOP,
|
||||||
Opcode.IPUT_OBJECT,
|
Opcode.IPUT_OBJECT,
|
||||||
Opcode.RETURN_VOID,
|
Opcode.RETURN_VOID,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
package app.revanced.patches.shared.misc.hex
|
||||||
|
|
||||||
|
import app.revanced.patcher.data.ResourceContext
|
||||||
|
import app.revanced.patcher.patch.PatchException
|
||||||
|
import app.revanced.patcher.patch.RawResourcePatch
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
abstract class BaseHexPatch : RawResourcePatch() {
|
||||||
|
internal abstract val replacements: List<Replacement>
|
||||||
|
|
||||||
|
override fun execute(context: ResourceContext) {
|
||||||
|
replacements.groupBy { it.targetFilePath }.forEach { (targetFilePath, replacements) ->
|
||||||
|
val targetFile = try {
|
||||||
|
context[targetFilePath, true]
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw PatchException("Could not find target file: $targetFilePath")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Use a file channel to read and write the file instead of reading the whole file into memory,
|
||||||
|
// in order to reduce memory usage.
|
||||||
|
val targetFileBytes = targetFile.readBytes()
|
||||||
|
|
||||||
|
replacements.forEach { replacement ->
|
||||||
|
replacement.replacePattern(targetFileBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
targetFile.writeBytes(targetFileBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a pattern to search for and its replacement pattern.
|
||||||
|
*
|
||||||
|
* @property pattern The pattern to search for.
|
||||||
|
* @property replacementPattern The pattern to replace the [pattern] with.
|
||||||
|
* @property targetFilePath The path to the file to make the changes in relative to the APK root.
|
||||||
|
*/
|
||||||
|
class Replacement(
|
||||||
|
private val pattern: String,
|
||||||
|
replacementPattern: String,
|
||||||
|
internal val targetFilePath: String,
|
||||||
|
) {
|
||||||
|
private val patternBytes = pattern.toByteArrayPattern()
|
||||||
|
private val replacementPattern = replacementPattern.toByteArrayPattern()
|
||||||
|
|
||||||
|
init {
|
||||||
|
if (this.patternBytes.size != this.replacementPattern.size) {
|
||||||
|
throw PatchException("Pattern and replacement pattern must have the same length: $pattern")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the [patternBytes] with the [replacementPattern] in the [targetFileBytes].
|
||||||
|
*
|
||||||
|
* @param targetFileBytes The bytes of the file to make the changes in.
|
||||||
|
*/
|
||||||
|
fun replacePattern(targetFileBytes: ByteArray) {
|
||||||
|
val startIndex = indexOfPatternIn(targetFileBytes)
|
||||||
|
|
||||||
|
if (startIndex == -1) {
|
||||||
|
throw PatchException("Pattern not found in target file: $pattern")
|
||||||
|
}
|
||||||
|
|
||||||
|
replacementPattern.copyInto(targetFileBytes, startIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Allow searching in a file channel instead of a byte array to reduce memory usage.
|
||||||
|
/**
|
||||||
|
* Returns the index of the first occurrence of [patternBytes] in the haystack
|
||||||
|
* using the Boyer-Moore algorithm.
|
||||||
|
*
|
||||||
|
* @param haystack The array to search in.
|
||||||
|
*
|
||||||
|
* @return The index of the first occurrence of the [patternBytes] in the haystack or -1
|
||||||
|
* if the [patternBytes] is not found.
|
||||||
|
*/
|
||||||
|
private fun indexOfPatternIn(haystack: ByteArray): Int {
|
||||||
|
val needle = patternBytes
|
||||||
|
|
||||||
|
val haystackLength = haystack.size - 1
|
||||||
|
val needleLength = needle.size - 1
|
||||||
|
val right = IntArray(256) { -1 }
|
||||||
|
|
||||||
|
for (i in 0 until needleLength) right[needle[i].toInt().and(0xFF)] = i
|
||||||
|
|
||||||
|
var skip: Int
|
||||||
|
for (i in 0..haystackLength - needleLength) {
|
||||||
|
skip = 0
|
||||||
|
|
||||||
|
for (j in needleLength - 1 downTo 0)
|
||||||
|
if (needle[j] != haystack[i + j]) {
|
||||||
|
skip = max(1, j - right[haystack[i + j].toInt().and(0xFF)])
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip == 0) return i
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Convert a string representing a pattern of hexadecimal bytes to a byte array.
|
||||||
|
*
|
||||||
|
* @return The byte array representing the pattern.
|
||||||
|
* @throws PatchException If the pattern is invalid.
|
||||||
|
*/
|
||||||
|
private fun String.toByteArrayPattern() = try {
|
||||||
|
split(" ").map { it.toInt(16).toByte() }.toByteArray()
|
||||||
|
} catch (e: NumberFormatException) {
|
||||||
|
throw PatchException(
|
||||||
|
"Could not parse pattern: $this. A pattern is a sequence of case insensitive strings " +
|
||||||
|
"representing hexadecimal bytes separated by spaces",
|
||||||
|
e,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,17 +2,21 @@ package app.revanced.patches.shared.misc.integrations
|
|||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.PatchException
|
import app.revanced.patcher.patch.PatchException
|
||||||
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint.IRegisterResolver
|
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint.IRegisterResolver
|
||||||
|
import app.revanced.patches.shared.misc.integrations.fingerprints.ReVancedUtilsPatchesVersionFingerprint
|
||||||
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||||
import com.android.tools.smali.dexlib2.iface.Method
|
import com.android.tools.smali.dexlib2.iface.Method
|
||||||
|
import java.util.jar.JarFile
|
||||||
|
|
||||||
abstract class BaseIntegrationsPatch(
|
abstract class BaseIntegrationsPatch(
|
||||||
private val hooks: Set<IntegrationsFingerprint>,
|
private val hooks: Set<IntegrationsFingerprint>,
|
||||||
) : BytecodePatch(hooks) {
|
) : BytecodePatch(hooks + setOf(ReVancedUtilsPatchesVersionFingerprint)) {
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
"Use the constructor without the integrationsDescriptor parameter",
|
"Use the constructor without the integrationsDescriptor parameter",
|
||||||
@@ -34,6 +38,46 @@ abstract class BaseIntegrationsPatch(
|
|||||||
hooks.forEach { hook ->
|
hooks.forEach { hook ->
|
||||||
hook.invoke(INTEGRATIONS_CLASS_DESCRIPTOR)
|
hook.invoke(INTEGRATIONS_CLASS_DESCRIPTOR)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Modify Utils method to include the patches release version version.
|
||||||
|
ReVancedUtilsPatchesVersionFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
|
val manifestValue = getPatchesManifestEntry("Version")
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
const-string v0, "$manifestValue"
|
||||||
|
return-object v0
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The value for the manifest entry,
|
||||||
|
* or "Unknown" if the entry does not exist or is blank.
|
||||||
|
*/
|
||||||
|
@Suppress("SameParameterValue")
|
||||||
|
private fun getPatchesManifestEntry(attributeKey: String) = JarFile(getCurrentJarFilePath()).use { jarFile ->
|
||||||
|
jarFile.manifest.mainAttributes.entries.firstOrNull { it.key.toString() == attributeKey }?.value?.toString()
|
||||||
|
?: "Unknown"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The file path for the jar this classfile is contained inside.
|
||||||
|
*/
|
||||||
|
private fun getCurrentJarFilePath(): String {
|
||||||
|
val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class"
|
||||||
|
val classUrl = object {}::class.java.classLoader.getResource(className)
|
||||||
|
if (classUrl != null) {
|
||||||
|
val urlString = classUrl.toString()
|
||||||
|
|
||||||
|
if (urlString.startsWith("jar:file:")) {
|
||||||
|
val end = urlString.indexOf('!')
|
||||||
|
return urlString.substring("jar:file:".length, end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw IllegalStateException("Not running from inside a JAR file.")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +94,7 @@ abstract class BaseIntegrationsPatch(
|
|||||||
strings: Iterable<String>? = null,
|
strings: Iterable<String>? = null,
|
||||||
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
|
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
|
||||||
private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {},
|
private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {},
|
||||||
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
|
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
|
||||||
) : MethodFingerprint(
|
) : MethodFingerprint(
|
||||||
returnType,
|
returnType,
|
||||||
accessFlags,
|
accessFlags,
|
||||||
@@ -59,9 +103,11 @@ abstract class BaseIntegrationsPatch(
|
|||||||
strings,
|
strings,
|
||||||
customFingerprint,
|
customFingerprint,
|
||||||
) {
|
) {
|
||||||
@Deprecated("Previous constructor that is missing the insert index." +
|
@Deprecated(
|
||||||
|
"Previous constructor that is missing the insert index." +
|
||||||
"Here only for binary compatibility, " +
|
"Here only for binary compatibility, " +
|
||||||
"and this can be removed after the next major version update.")
|
"and this can be removed after the next major version update.",
|
||||||
|
)
|
||||||
constructor(
|
constructor(
|
||||||
returnType: String? = null,
|
returnType: String? = null,
|
||||||
accessFlags: Int? = null,
|
accessFlags: Int? = null,
|
||||||
@@ -69,7 +115,7 @@ abstract class BaseIntegrationsPatch(
|
|||||||
opcodes: Iterable<Opcode?>? = null,
|
opcodes: Iterable<Opcode?>? = null,
|
||||||
strings: Iterable<String>? = null,
|
strings: Iterable<String>? = null,
|
||||||
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
|
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
|
||||||
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
|
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
|
||||||
) : this(
|
) : this(
|
||||||
returnType,
|
returnType,
|
||||||
accessFlags,
|
accessFlags,
|
||||||
@@ -78,7 +124,7 @@ abstract class BaseIntegrationsPatch(
|
|||||||
strings,
|
strings,
|
||||||
customFingerprint,
|
customFingerprint,
|
||||||
object : IHookInsertIndexResolver {},
|
object : IHookInsertIndexResolver {},
|
||||||
contextRegisterResolver
|
contextRegisterResolver,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun invoke(integrationsDescriptor: String) {
|
fun invoke(integrationsDescriptor: String) {
|
||||||
@@ -103,7 +149,7 @@ abstract class BaseIntegrationsPatch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
internal companion object {
|
||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;"
|
internal const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.shared.misc.integrations.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal object ReVancedUtilsPatchesVersionFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
|
returnType = "Ljava/lang/String;",
|
||||||
|
parameters = listOf(),
|
||||||
|
customFingerprint = { methodDef, classDef ->
|
||||||
|
methodDef.name == "getPatchesReleaseVersion" &&
|
||||||
|
classDef.type == BaseIntegrationsPatch.INTEGRATIONS_CLASS_DESCRIPTOR
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -8,19 +8,15 @@ import java.util.concurrent.Executors
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
object ResourceMappingPatch : ResourcePatch() {
|
object ResourceMappingPatch : ResourcePatch() {
|
||||||
internal lateinit var resourceMappings: List<ResourceElement>
|
private val resourceMappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
|
||||||
private set
|
|
||||||
|
|
||||||
private val THREAD_COUNT = Runtime.getRuntime().availableProcessors()
|
private val THREAD_COUNT = Runtime.getRuntime().availableProcessors()
|
||||||
private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT)
|
private val threadPoolExecutor = Executors.newFixedThreadPool(THREAD_COUNT)
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
// save the file in memory to concurrently read from
|
// sSve the file in memory to concurrently read from it.
|
||||||
val resourceXmlFile = context.get("res/values/public.xml").readBytes()
|
val resourceXmlFile = context.get("res/values/public.xml").readBytes()
|
||||||
|
|
||||||
// create a synchronized list to store the resource mappings
|
|
||||||
val mappings = Collections.synchronizedList(mutableListOf<ResourceElement>())
|
|
||||||
|
|
||||||
for (threadIndex in 0 until THREAD_COUNT) {
|
for (threadIndex in 0 until THREAD_COUNT) {
|
||||||
threadPoolExecutor.execute thread@{
|
threadPoolExecutor.execute thread@{
|
||||||
context.xmlEditor[resourceXmlFile.inputStream()].use { editor ->
|
context.xmlEditor[resourceXmlFile.inputStream()].use { editor ->
|
||||||
@@ -33,7 +29,7 @@ object ResourceMappingPatch : ResourcePatch() {
|
|||||||
val batchStart = jobSize * threadIndex
|
val batchStart = jobSize * threadIndex
|
||||||
val batchEnd = jobSize * (threadIndex + 1)
|
val batchEnd = jobSize * (threadIndex + 1)
|
||||||
element@ for (i in batchStart until batchEnd) {
|
element@ for (i in batchStart until batchEnd) {
|
||||||
// make sure to not go out of bounds when rounding errors occur at calculating the jobSize
|
// Prevent out of bounds.
|
||||||
if (i >= resourcesLength) return@thread
|
if (i >= resourcesLength) return@thread
|
||||||
|
|
||||||
val node = resources.item(i)
|
val node = resources.item(i)
|
||||||
@@ -46,18 +42,18 @@ object ResourceMappingPatch : ResourcePatch() {
|
|||||||
|
|
||||||
val id = node.getAttribute("id").substring(2).toLong(16)
|
val id = node.getAttribute("id").substring(2).toLong(16)
|
||||||
|
|
||||||
mappings.add(ResourceElement(typeAttribute, nameAttribute, id))
|
resourceMappings.add(ResourceElement(typeAttribute, nameAttribute, id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
threadPoolExecutor
|
threadPoolExecutor.also { it.shutdown() }.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
|
||||||
.also { it.shutdown() }
|
|
||||||
.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS)
|
|
||||||
|
|
||||||
resourceMappings = mappings
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun get(type: String, name: String) = resourceMappings.first {
|
||||||
|
it.type == type && it.name == name
|
||||||
|
}.id
|
||||||
|
|
||||||
data class ResourceElement(val type: String, val name: String, val id: Long)
|
data class ResourceElement(val type: String, val name: String, val id: Long)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,19 @@ import org.w3c.dom.Document
|
|||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
class NonInteractivePreference(
|
class NonInteractivePreference(
|
||||||
key: String,
|
key: String,
|
||||||
|
titleKey: String = "${key}_title",
|
||||||
summaryKey: String? = "${key}_summary",
|
summaryKey: String? = "${key}_summary",
|
||||||
tag: String = "Preference",
|
tag: String = "Preference",
|
||||||
val selectable: Boolean = false
|
val selectable: Boolean = false
|
||||||
) : BasePreference(null, "${key}_title", summaryKey, tag) {
|
) : BasePreference(key, titleKey, summaryKey, tag) {
|
||||||
|
|
||||||
|
@Deprecated("Here only for binary compatibility, and should be removed after the next major version update.")
|
||||||
|
constructor(
|
||||||
|
key: String,
|
||||||
|
summaryKey: String? = "${key}_summary",
|
||||||
|
tag: String = "Preference",
|
||||||
|
selectable: Boolean = false
|
||||||
|
) : this(key, "${key}_title", summaryKey, tag, selectable)
|
||||||
|
|
||||||
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
|
||||||
super.serialize(ownerDocument, resourceCallback).apply {
|
super.serialize(ownerDocument, resourceCallback).apply {
|
||||||
|
|||||||
@@ -11,12 +11,11 @@ object PremiumNavbarTabResourcePatch : ResourcePatch() {
|
|||||||
internal var premiumTabId = -1L
|
internal var premiumTabId = -1L
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
premiumTabId = ResourceMappingPatch.resourceMappings.single {
|
premiumTabId = ResourceMappingPatch["id", "premium_tab"]
|
||||||
it.type == "id" && it.name == "premium_tab"
|
|
||||||
}.id
|
|
||||||
|
|
||||||
showBottomNavigationItemsTextId = ResourceMappingPatch.resourceMappings.single {
|
showBottomNavigationItemsTextId = ResourceMappingPatch[
|
||||||
it.type == "bool" && it.name == "show_bottom_navigation_items_text"
|
"bool",
|
||||||
}.id
|
"show_bottom_navigation_items_text",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,17 @@ object SettingsPatch : BytecodePatch(
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
PreferenceScreen.MISC.OTHER.addPreferences(
|
PreferenceScreen.MISC.OTHER.addPreferences(
|
||||||
SwitchPreference("revanced_debug")
|
// The debug setting is shared across multiple apps and the key must be the same.
|
||||||
|
// But the title and summary must be different, otherwise when the strings file is flattened
|
||||||
|
// for Crowdin push, Crowdin gets confused by the duplicate keys.
|
||||||
|
// FIXME: Ideally the shared debug strings are extracted into a common app group
|
||||||
|
// and then both apps import that. But for now unique unique title and summary keys also works.
|
||||||
|
SwitchPreference(
|
||||||
|
key = "revanced_debug",
|
||||||
|
titleKey = "revanced_twitch_debug_title",
|
||||||
|
summaryOnKey = "revanced_twitch_debug_summary_on",
|
||||||
|
summaryOffKey = "revanced_twitch_debug_summary_off"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Hook onCreate to handle fragment creation
|
// Hook onCreate to handle fragment creation
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
LithoFilterPatch::class,
|
LithoFilterPatch::class,
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
object HideAdsResourcePatch : ResourcePatch() {
|
object HideAdsResourcePatch : ResourcePatch() {
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
private const val FILTER_CLASS_DESCRIPTOR =
|
||||||
@@ -30,16 +30,16 @@ object HideAdsResourcePatch : ResourcePatch() {
|
|||||||
SwitchPreference("revanced_hide_general_ads"),
|
SwitchPreference("revanced_hide_general_ads"),
|
||||||
SwitchPreference("revanced_hide_fullscreen_ads"),
|
SwitchPreference("revanced_hide_fullscreen_ads"),
|
||||||
SwitchPreference("revanced_hide_buttoned_ads"),
|
SwitchPreference("revanced_hide_buttoned_ads"),
|
||||||
SwitchPreference("revanced_hide_paid_content_ads"),
|
SwitchPreference("revanced_hide_paid_promotion_label"),
|
||||||
SwitchPreference("revanced_hide_self_sponsor_ads"),
|
SwitchPreference("revanced_hide_self_sponsor_ads"),
|
||||||
SwitchPreference("revanced_hide_products_banner"),
|
SwitchPreference("revanced_hide_products_banner"),
|
||||||
SwitchPreference("revanced_hide_shopping_links"),
|
SwitchPreference("revanced_hide_shopping_links"),
|
||||||
SwitchPreference("revanced_hide_web_search_results"),
|
SwitchPreference("revanced_hide_web_search_results"),
|
||||||
SwitchPreference("revanced_hide_merchandise_banners")
|
SwitchPreference("revanced_hide_merchandise_banners"),
|
||||||
)
|
)
|
||||||
|
|
||||||
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
LithoFilterPatch.addFilter(FILTER_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
adAttributionId = ResourceMappingPatch.resourceMappings.single { it.name == "ad_attribution" }.id
|
adAttributionId = ResourceMappingPatch["id", "ad_attribution"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ import app.revanced.util.resultOrThrow
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
IntegrationsPatch::class,
|
IntegrationsPatch::class,
|
||||||
PlayerTypeHookPatch::class,
|
PlayerTypeHookPatch::class,
|
||||||
SwipeControlsResourcePatch::class
|
SwipeControlsResourcePatch::class,
|
||||||
],
|
],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
@@ -42,17 +42,22 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
]
|
"19.10.39",
|
||||||
)
|
"19.11.43", // 19.12.x has an issue with opening YT using external links,
|
||||||
]
|
// and the app then crashes if double tap to skip forward/back is immediately used.
|
||||||
|
// The stack trace shows a call coming from integrations SwipeController,
|
||||||
|
// but it may be a bug in YT itself as other target versions do not have this issue.
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object SwipeControlsBytecodePatch : BytecodePatch(
|
object SwipeControlsBytecodePatch : BytecodePatch(
|
||||||
setOf(
|
setOf(
|
||||||
MainActivityFingerprint,
|
MainActivityFingerprint,
|
||||||
SwipeControlsHostActivityFingerprint
|
SwipeControlsHostActivityFingerprint,
|
||||||
)
|
),
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
|
val wrapperClass = SwipeControlsHostActivityFingerprint.result!!.mutableClass
|
||||||
@@ -74,9 +79,9 @@ object SwipeControlsBytecodePatch : BytecodePatch(
|
|||||||
accessFlags and AccessFlags.FINAL.value.inv(),
|
accessFlags and AccessFlags.FINAL.value.inv(),
|
||||||
annotations,
|
annotations,
|
||||||
hiddenApiRestrictions,
|
hiddenApiRestrictions,
|
||||||
implementation
|
implementation,
|
||||||
).toMutable()
|
).toMutable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ internal object SwipeControlsResourcePatch : ResourcePatch() {
|
|||||||
SwitchPreference("revanced_swipe_press_to_engage"),
|
SwitchPreference("revanced_swipe_press_to_engage"),
|
||||||
SwitchPreference("revanced_swipe_haptic_feedback"),
|
SwitchPreference("revanced_swipe_haptic_feedback"),
|
||||||
SwitchPreference("revanced_swipe_save_and_restore_brightness"),
|
SwitchPreference("revanced_swipe_save_and_restore_brightness"),
|
||||||
|
SwitchPreference("revanced_swipe_lowest_value_enable_auto_brightness"),
|
||||||
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
|
TextPreference("revanced_swipe_overlay_timeout", inputType = InputType.NUMBER),
|
||||||
TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER),
|
TextPreference("revanced_swipe_text_overlay_size", inputType = InputType.NUMBER),
|
||||||
TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER),
|
TextPreference("revanced_swipe_overlay_background_alpha", inputType = InputType.NUMBER),
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ import app.revanced.util.exception
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@@ -63,8 +65,7 @@ object HideButtonsPatch : ResourcePatch() {
|
|||||||
SwitchPreference("revanced_hide_download_button"),
|
SwitchPreference("revanced_hide_download_button"),
|
||||||
SwitchPreference("revanced_hide_thanks_button"),
|
SwitchPreference("revanced_hide_thanks_button"),
|
||||||
SwitchPreference("revanced_hide_clip_button"),
|
SwitchPreference("revanced_hide_clip_button"),
|
||||||
SwitchPreference("revanced_hide_playlist_button"),
|
SwitchPreference("revanced_hide_playlist_button")
|
||||||
SwitchPreference("revanced_hide_shop_button")
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
|||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
|
import app.revanced.patches.youtube.shared.fingerprints.LayoutConstructorFingerprint
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import app.revanced.util.findIndexForIdResource
|
import app.revanced.util.indexOfIdResourceOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
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.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
@@ -27,7 +27,7 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|||||||
IntegrationsPatch::class,
|
IntegrationsPatch::class,
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
],
|
],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
@@ -49,27 +49,29 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
]
|
"19.10.39",
|
||||||
)
|
"19.11.43",
|
||||||
]
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object HideAutoplayButtonPatch : BytecodePatch(
|
object HideAutoplayButtonPatch : BytecodePatch(
|
||||||
setOf(LayoutConstructorFingerprint)
|
setOf(LayoutConstructorFingerprint),
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
||||||
SwitchPreference("revanced_hide_autoplay_button")
|
SwitchPreference("revanced_hide_autoplay_button"),
|
||||||
)
|
)
|
||||||
|
|
||||||
LayoutConstructorFingerprint.result?.mutableMethod?.apply {
|
LayoutConstructorFingerprint.result?.mutableMethod?.apply {
|
||||||
val layoutGenMethodInstructions = implementation!!.instructions
|
val layoutGenMethodInstructions = implementation!!.instructions
|
||||||
|
|
||||||
// resolve the offsets of where to insert the branch instructions and ...
|
// resolve the offsets of where to insert the branch instructions and ...
|
||||||
val insertIndex = findIndexForIdResource("autonav_preview_stub")
|
val insertIndex = indexOfIdResourceOrThrow("autonav_preview_stub")
|
||||||
|
|
||||||
// where to branch away
|
// where to branch away
|
||||||
val branchIndex =
|
val branchIndex =
|
||||||
@@ -90,8 +92,8 @@ object HideAutoplayButtonPatch : BytecodePatch(
|
|||||||
move-result v$clobberRegister
|
move-result v$clobberRegister
|
||||||
if-eqz v$clobberRegister, :hidden
|
if-eqz v$clobberRegister, :hidden
|
||||||
""",
|
""",
|
||||||
ExternalLabel("hidden", jumpInstruction)
|
ExternalLabel("hidden", jumpInstruction),
|
||||||
)
|
)
|
||||||
} ?: throw LayoutConstructorFingerprint.exception
|
} ?: throw LayoutConstructorFingerprint.exception
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.Opcode
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37",
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
internal object AlbumCardsResourcePatch : ResourcePatch() {
|
internal object AlbumCardsResourcePatch : ResourcePatch() {
|
||||||
@@ -22,11 +22,9 @@ internal object AlbumCardsResourcePatch : ResourcePatch() {
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.FEED.addPreferences(
|
SettingsPatch.PreferenceScreen.FEED.addPreferences(
|
||||||
SwitchPreference("revanced_hide_album_cards")
|
SwitchPreference("revanced_hide_album_cards"),
|
||||||
)
|
)
|
||||||
|
|
||||||
albumCardId = ResourceMappingPatch.resourceMappings.single {
|
albumCardId = ResourceMappingPatch["layout", "album_card"]
|
||||||
it.type == "layout" && it.name == "album_card"
|
|
||||||
}.id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
|
internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
|
||||||
@@ -22,11 +22,12 @@ internal object CrowdfundingBoxResourcePatch : ResourcePatch() {
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.FEED.addPreferences(
|
SettingsPatch.PreferenceScreen.FEED.addPreferences(
|
||||||
SwitchPreference("revanced_hide_crowdfunding_box")
|
SwitchPreference("revanced_hide_crowdfunding_box"),
|
||||||
)
|
)
|
||||||
|
|
||||||
crowdfundingBoxId = ResourceMappingPatch.resourceMappings.single {
|
crowdfundingBoxId = ResourceMappingPatch[
|
||||||
it.type == "layout" && it.name == "donation_companion"
|
"layout",
|
||||||
}.id
|
"donation_companion",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction21c
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
|
internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
|
||||||
@@ -24,15 +24,13 @@ internal object HideEndscreenCardsResourcePatch : ResourcePatch() {
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
||||||
SwitchPreference("revanced_hide_endscreen_cards")
|
SwitchPreference("revanced_hide_endscreen_cards"),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun findEndscreenResourceId(name: String) = ResourceMappingPatch.resourceMappings.single {
|
fun idOf(name: String) = ResourceMappingPatch["layout", "endscreen_element_layout_$name"]
|
||||||
it.type == "layout" && it.name == "endscreen_element_layout_$name"
|
|
||||||
}.id
|
|
||||||
|
|
||||||
layoutCircle = findEndscreenResourceId("circle")
|
layoutCircle = idOf("circle")
|
||||||
layoutIcon = findEndscreenResourceId("icon")
|
layoutIcon = idOf("icon")
|
||||||
layoutVideo = findEndscreenResourceId("video")
|
layoutVideo = idOf("video")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -25,15 +25,12 @@ internal object HideFilterBarResourcePatch : ResourcePatch() {
|
|||||||
SwitchPreference("revanced_hide_filter_bar_feed_in_feed"),
|
SwitchPreference("revanced_hide_filter_bar_feed_in_feed"),
|
||||||
SwitchPreference("revanced_hide_filter_bar_feed_in_search"),
|
SwitchPreference("revanced_hide_filter_bar_feed_in_search"),
|
||||||
SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"),
|
SwitchPreference("revanced_hide_filter_bar_feed_in_related_videos"),
|
||||||
)
|
),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
relatedChipCloudMarginId = "related_chip_cloud_reduced_margins".layoutResourceId("layout")
|
relatedChipCloudMarginId = ResourceMappingPatch["layout", "related_chip_cloud_reduced_margins"]
|
||||||
filterBarHeightId = "filter_bar_height".layoutResourceId()
|
filterBarHeightId = ResourceMappingPatch["dimen", "filter_bar_height"]
|
||||||
barContainerHeightId = "bar_container_height".layoutResourceId()
|
barContainerHeightId = ResourceMappingPatch["dimen", "bar_container_height"]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private fun String.layoutResourceId(type: String = "dimen") =
|
|
||||||
ResourceMappingPatch.resourceMappings.single { it.type == type && it.name == this }.id
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.revanced.patches.youtube.layout.hide.floatingmicrophone
|
package app.revanced.patches.youtube.layout.hide.floatingmicrophone
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
import app.revanced.patcher.data.ResourceContext
|
||||||
import app.revanced.patcher.patch.PatchException
|
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||||
@@ -13,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
|
internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
|
||||||
internal var fabButtonId: Long = -1
|
internal var fabButtonId: Long = -1
|
||||||
@@ -23,10 +22,9 @@ internal object HideFloatingMicrophoneButtonResourcePatch : ResourcePatch() {
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
SettingsPatch.PreferenceScreen.GENERAL_LAYOUT.addPreferences(
|
||||||
SwitchPreference("revanced_hide_floating_microphone_button")
|
SwitchPreference("revanced_hide_floating_microphone_button"),
|
||||||
)
|
)
|
||||||
|
|
||||||
fabButtonId = ResourceMappingPatch.resourceMappings.find { it.type == "id" && it.name == "fab" }?.id
|
fabButtonId = ResourceMappingPatch["id", "fab"]
|
||||||
?: throw PatchException("Can not find required fab button resource id")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ import app.revanced.util.exception
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -57,7 +57,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37",
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -101,7 +103,6 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
|||||||
SwitchPreference("revanced_hide_info_panels"),
|
SwitchPreference("revanced_hide_info_panels"),
|
||||||
SwitchPreference("revanced_hide_join_membership_button"),
|
SwitchPreference("revanced_hide_join_membership_button"),
|
||||||
SwitchPreference("revanced_hide_medical_panels"),
|
SwitchPreference("revanced_hide_medical_panels"),
|
||||||
SwitchPreference("revanced_hide_playables"),
|
|
||||||
SwitchPreference("revanced_hide_quick_actions"),
|
SwitchPreference("revanced_hide_quick_actions"),
|
||||||
SwitchPreference("revanced_hide_related_videos"),
|
SwitchPreference("revanced_hide_related_videos"),
|
||||||
SwitchPreference("revanced_hide_subscribers_community_guidelines"),
|
SwitchPreference("revanced_hide_subscribers_community_guidelines"),
|
||||||
@@ -120,6 +121,7 @@ object HideLayoutComponentsPatch : BytecodePatch(
|
|||||||
SwitchPreference("revanced_hide_mix_playlists"),
|
SwitchPreference("revanced_hide_mix_playlists"),
|
||||||
SwitchPreference("revanced_hide_movies_section"),
|
SwitchPreference("revanced_hide_movies_section"),
|
||||||
SwitchPreference("revanced_hide_notify_me_button"),
|
SwitchPreference("revanced_hide_notify_me_button"),
|
||||||
|
SwitchPreference("revanced_hide_playables"),
|
||||||
SwitchPreference("revanced_hide_search_result_recommendations"),
|
SwitchPreference("revanced_hide_search_result_recommendations"),
|
||||||
SwitchPreference("revanced_hide_search_result_shelf_header"),
|
SwitchPreference("revanced_hide_search_result_shelf_header"),
|
||||||
SwitchPreference("revanced_hide_show_more_button"),
|
SwitchPreference("revanced_hide_show_more_button"),
|
||||||
|
|||||||
@@ -5,22 +5,22 @@ import app.revanced.patcher.patch.ResourcePatch
|
|||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||||
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
dependencies = [
|
dependencies = [
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
internal object HideLayoutComponentsResourcePatch : ResourcePatch() {
|
internal object HideLayoutComponentsResourcePatch : ResourcePatch() {
|
||||||
internal var expandButtonDownId: Long = -1
|
internal var expandButtonDownId: Long = -1
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
expandButtonDownId = ResourceMappingPatch.resourceMappings.single {
|
expandButtonDownId = ResourceMappingPatch[
|
||||||
it.type == "layout" && it.name == "expand_button_down"
|
"layout",
|
||||||
}.id
|
"expand_button_down",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
object HideInfocardsResourcePatch : ResourcePatch() {
|
object HideInfocardsResourcePatch : ResourcePatch() {
|
||||||
@@ -22,11 +22,12 @@ object HideInfocardsResourcePatch : ResourcePatch() {
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
||||||
SwitchPreference("revanced_hide_info_cards")
|
SwitchPreference("revanced_hide_info_cards"),
|
||||||
)
|
)
|
||||||
|
|
||||||
drawerResourceId = ResourceMappingPatch.resourceMappings.single {
|
drawerResourceId = ResourceMappingPatch[
|
||||||
it.type == "id" && it.name == "info_cards_drawer_header"
|
"id",
|
||||||
}.id
|
"info_cards_drawer_header",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
package app.revanced.patches.youtube.layout.hide.shorts
|
package app.revanced.patches.youtube.layout.hide.shorts
|
||||||
|
|
||||||
import app.revanced.util.exception
|
|
||||||
import app.revanced.util.findIndexForIdResource
|
|
||||||
import app.revanced.util.injectHideViewCall
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
@@ -15,9 +12,15 @@ import app.revanced.patches.youtube.layout.hide.shorts.fingerprints.*
|
|||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
import app.revanced.patches.youtube.misc.litho.filter.LithoFilterPatch
|
||||||
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
|
import app.revanced.patches.youtube.misc.navigation.NavigationBarHookPatch
|
||||||
|
import app.revanced.util.exception
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfIdResourceOrThrow
|
||||||
|
import app.revanced.util.injectHideViewCall
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
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.OneRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Hide Shorts components",
|
name = "Hide Shorts components",
|
||||||
@@ -27,11 +30,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
LithoFilterPatch::class,
|
LithoFilterPatch::class,
|
||||||
HideShortsComponentsResourcePatch::class,
|
HideShortsComponentsResourcePatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
NavigationBarHookPatch::class
|
NavigationBarHookPatch::class,
|
||||||
],
|
],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
"com.google.android.youtube", [
|
"com.google.android.youtube",
|
||||||
|
[
|
||||||
"18.32.39",
|
"18.32.39",
|
||||||
"18.37.36",
|
"18.37.36",
|
||||||
"18.38.44",
|
"18.38.44",
|
||||||
@@ -48,10 +52,12 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
]
|
"19.10.39",
|
||||||
)
|
"19.11.43",
|
||||||
]
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object HideShortsComponentsPatch : BytecodePatch(
|
object HideShortsComponentsPatch : BytecodePatch(
|
||||||
@@ -60,8 +66,8 @@ object HideShortsComponentsPatch : BytecodePatch(
|
|||||||
ReelConstructorFingerprint,
|
ReelConstructorFingerprint,
|
||||||
BottomNavigationBarFingerprint,
|
BottomNavigationBarFingerprint,
|
||||||
RenderBottomNavigationBarParentFingerprint,
|
RenderBottomNavigationBarParentFingerprint,
|
||||||
SetPivotBarVisibilityParentFingerprint
|
SetPivotBarVisibilityParentFingerprint,
|
||||||
)
|
),
|
||||||
) {
|
) {
|
||||||
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;"
|
private const val FILTER_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/components/ShortsFilter;"
|
||||||
|
|
||||||
@@ -79,7 +85,7 @@ object HideShortsComponentsPatch : BytecodePatch(
|
|||||||
insertIndex,
|
insertIndex,
|
||||||
viewRegister,
|
viewRegister,
|
||||||
FILTER_CLASS_DESCRIPTOR,
|
FILTER_CLASS_DESCRIPTOR,
|
||||||
"hideShortsShelf"
|
"hideShortsShelf",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} // Do not throw an exception if not resolved.
|
} // Do not throw an exception if not resolved.
|
||||||
@@ -93,7 +99,6 @@ object HideShortsComponentsPatch : BytecodePatch(
|
|||||||
ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) }
|
ShortsButtons.entries.forEach { button -> button.injectHideCall(it.mutableMethod) }
|
||||||
} ?: throw CreateShortsButtonsFingerprint.exception
|
} ?: throw CreateShortsButtonsFingerprint.exception
|
||||||
|
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Hide the Shorts buttons in newer versions of YouTube.
|
// region Hide the Shorts buttons in newer versions of YouTube.
|
||||||
@@ -106,8 +111,9 @@ object HideShortsComponentsPatch : BytecodePatch(
|
|||||||
|
|
||||||
// Hook to get the pivotBar view.
|
// Hook to get the pivotBar view.
|
||||||
SetPivotBarVisibilityParentFingerprint.result?.let {
|
SetPivotBarVisibilityParentFingerprint.result?.let {
|
||||||
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef))
|
if (!SetPivotBarVisibilityFingerprint.resolve(context, it.classDef)) {
|
||||||
throw SetPivotBarVisibilityFingerprint.exception
|
throw SetPivotBarVisibilityFingerprint.exception
|
||||||
|
}
|
||||||
|
|
||||||
SetPivotBarVisibilityFingerprint.result!!.let { result ->
|
SetPivotBarVisibilityFingerprint.result!!.let { result ->
|
||||||
result.mutableMethod.apply {
|
result.mutableMethod.apply {
|
||||||
@@ -116,7 +122,7 @@ object HideShortsComponentsPatch : BytecodePatch(
|
|||||||
addInstruction(
|
addInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" +
|
"sput-object v$viewRegister, $FILTER_CLASS_DESCRIPTOR->pivotBar:" +
|
||||||
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;"
|
"Lcom/google/android/libraries/youtube/rendering/ui/pivotbar/PivotBar;",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,8 +130,9 @@ object HideShortsComponentsPatch : BytecodePatch(
|
|||||||
|
|
||||||
// Hook to hide the navigation bar when Shorts are being played.
|
// Hook to hide the navigation bar when Shorts are being played.
|
||||||
RenderBottomNavigationBarParentFingerprint.result?.let {
|
RenderBottomNavigationBarParentFingerprint.result?.let {
|
||||||
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef))
|
if (!RenderBottomNavigationBarFingerprint.resolve(context, it.classDef)) {
|
||||||
throw RenderBottomNavigationBarFingerprint.exception
|
throw RenderBottomNavigationBarFingerprint.exception
|
||||||
|
}
|
||||||
|
|
||||||
RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply {
|
RenderBottomNavigationBarFingerprint.result!!.mutableMethod.apply {
|
||||||
addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V")
|
addInstruction(0, "invoke-static { }, $FILTER_CLASS_DESCRIPTOR->hideNavigationBar()V")
|
||||||
@@ -142,7 +149,7 @@ object HideShortsComponentsPatch : BytecodePatch(
|
|||||||
addInstruction(
|
addInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" +
|
"invoke-static { v$viewRegister }, $FILTER_CLASS_DESCRIPTOR->" +
|
||||||
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;"
|
"hideNavigationBar(Landroid/view/View;)Landroid/view/View;",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} ?: throw BottomNavigationBarFingerprint.exception
|
} ?: throw BottomNavigationBarFingerprint.exception
|
||||||
@@ -150,18 +157,25 @@ object HideShortsComponentsPatch : BytecodePatch(
|
|||||||
// endregion
|
// endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private enum class ShortsButtons(private val resourceName: String, private val methodName: String) {
|
private enum class ShortsButtons(private val resourceName: String, private val methodName: String) {
|
||||||
|
LIKE("reel_dyn_like", "hideLikeButton"),
|
||||||
|
DISLIKE("reel_dyn_dislike", "hideDislikeButton"),
|
||||||
COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"),
|
COMMENTS("reel_dyn_comment", "hideShortsCommentsButton"),
|
||||||
REMIX("reel_dyn_remix", "hideShortsRemixButton"),
|
REMIX("reel_dyn_remix", "hideShortsRemixButton"),
|
||||||
SHARE("reel_dyn_share", "hideShortsShareButton");
|
SHARE("reel_dyn_share", "hideShortsShareButton");
|
||||||
|
|
||||||
fun injectHideCall(method: MutableMethod) {
|
fun injectHideCall(method: MutableMethod) {
|
||||||
val referencedIndex = method.findIndexForIdResource(resourceName)
|
val referencedIndex = method.indexOfIdResourceOrThrow(resourceName)
|
||||||
|
|
||||||
val setIdIndex = referencedIndex + 1
|
val instruction = method.implementation!!.instructions
|
||||||
|
.subList(referencedIndex, referencedIndex + 20)
|
||||||
|
.first {
|
||||||
|
it.opcode == Opcode.INVOKE_VIRTUAL && it.getReference<MethodReference>()?.name == "setId"
|
||||||
|
}
|
||||||
|
|
||||||
|
val setIdIndex = instruction.location.index
|
||||||
val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC
|
val viewRegister = method.getInstruction<FiveRegisterInstruction>(setIdIndex).registerC
|
||||||
method.injectHideViewCall(setIdIndex, viewRegister, FILTER_CLASS_DESCRIPTOR, methodName)
|
method.injectHideViewCall(setIdIndex + 1, viewRegister, FILTER_CLASS_DESCRIPTOR, methodName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,13 +34,14 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
|
|||||||
SwitchPreference("revanced_hide_shorts_sound_button"),
|
SwitchPreference("revanced_hide_shorts_sound_button"),
|
||||||
|
|
||||||
// Everything else.
|
// Everything else.
|
||||||
SwitchPreference("revanced_hide_shorts_thanks_button"),
|
|
||||||
SwitchPreference("revanced_hide_shorts_shop_button"),
|
|
||||||
SwitchPreference("revanced_hide_shorts_location_button"),
|
|
||||||
SwitchPreference("revanced_hide_shorts_save_sound_button"),
|
|
||||||
SwitchPreference("revanced_hide_shorts_join_button"),
|
SwitchPreference("revanced_hide_shorts_join_button"),
|
||||||
SwitchPreference("revanced_hide_shorts_subscribe_button"),
|
SwitchPreference("revanced_hide_shorts_subscribe_button"),
|
||||||
SwitchPreference("revanced_hide_shorts_subscribe_button_paused"),
|
SwitchPreference("revanced_hide_shorts_paused_overlay_buttons"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_save_sound_button"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_shop_button"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_tagged_products"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_search_suggestions"),
|
||||||
|
SwitchPreference("revanced_hide_shorts_location_label"),
|
||||||
SwitchPreference("revanced_hide_shorts_channel_bar"),
|
SwitchPreference("revanced_hide_shorts_channel_bar"),
|
||||||
SwitchPreference("revanced_hide_shorts_info_panel"),
|
SwitchPreference("revanced_hide_shorts_info_panel"),
|
||||||
SwitchPreference("revanced_hide_shorts_full_video_link_label"),
|
SwitchPreference("revanced_hide_shorts_full_video_link_label"),
|
||||||
@@ -49,15 +50,19 @@ object HideShortsComponentsResourcePatch : ResourcePatch() {
|
|||||||
SwitchPreference("revanced_hide_shorts_navigation_bar"),
|
SwitchPreference("revanced_hide_shorts_navigation_bar"),
|
||||||
)
|
)
|
||||||
|
|
||||||
ResourceMappingPatch.resourceMappings.find {
|
reelPlayerRightCellButtonHeight = ResourceMappingPatch[
|
||||||
it.type == "layout" && it.name == "reel_multiple_items_shelf"
|
"dimen",
|
||||||
}?.also {
|
"reel_player_right_cell_button_height",
|
||||||
reelMultipleItemShelfId = it.id
|
]
|
||||||
}
|
|
||||||
|
|
||||||
reelPlayerRightCellButtonHeight =
|
// Resource not present in new versions of the app.
|
||||||
ResourceMappingPatch.resourceMappings.single {
|
try {
|
||||||
it.type == "dimen" && it.name == "reel_player_right_cell_button_height"
|
ResourceMappingPatch[
|
||||||
}.id
|
"dimen",
|
||||||
|
"reel_player_right_cell_button_height",
|
||||||
|
]
|
||||||
|
} catch (e: NoSuchElementException) {
|
||||||
|
return
|
||||||
|
}.also { reelPlayerRightCellButtonHeight = it }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
|
package app.revanced.patches.youtube.layout.hide.shorts.fingerprints
|
||||||
|
|
||||||
import app.revanced.patcher.extensions.or
|
|
||||||
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch
|
import app.revanced.patches.youtube.layout.hide.shorts.HideShortsComponentsResourcePatch
|
||||||
import app.revanced.util.patch.LiteralValueFingerprint
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
|
||||||
|
|
||||||
internal object CreateShortsButtonsFingerprint : LiteralValueFingerprint(
|
internal object CreateShortsButtonsFingerprint : LiteralValueFingerprint(
|
||||||
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
// YT 19.12.x moved this code inside another method, and each method has different parameters.
|
||||||
returnType = "V",
|
returnType = "V",
|
||||||
parameters = listOf("Z", "Z", "L"),
|
|
||||||
literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight }
|
literalSupplier = { HideShortsComponentsResourcePatch.reelPlayerRightCellButtonHeight }
|
||||||
)
|
)
|
||||||
@@ -33,7 +33,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
ResourceMappingPatch::class,
|
ResourceMappingPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
|
internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
|
||||||
@@ -22,11 +22,12 @@ internal object DisableSuggestedVideoEndScreenResourcePatch : ResourcePatch() {
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
||||||
SwitchPreference("revanced_disable_suggested_video_end_screen")
|
SwitchPreference("revanced_disable_suggested_video_end_screen"),
|
||||||
)
|
)
|
||||||
|
|
||||||
sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch.resourceMappings.single {
|
sizeAdjustableLiteAutoNavOverlay = ResourceMappingPatch[
|
||||||
it.type == "layout" && it.name == "size_adjustable_lite_autonav_overlay"
|
"layout",
|
||||||
}.id
|
"size_adjustable_lite_autonav_overlay",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ import app.revanced.util.exception
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ import app.revanced.util.exception
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ import org.w3c.dom.Element
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import app.revanced.patches.shared.misc.settings.preference.TextPreference
|
|||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class]
|
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
|
||||||
)
|
)
|
||||||
internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
|
internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
|
||||||
internal var scrimOverlayId = -1L
|
internal var scrimOverlayId = -1L
|
||||||
@@ -19,11 +19,12 @@ internal object CustomPlayerOverlayOpacityResourcePatch : ResourcePatch() {
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
SettingsPatch.PreferenceScreen.PLAYER.addPreferences(
|
||||||
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER)
|
TextPreference("revanced_player_overlay_opacity", inputType = InputType.NUMBER),
|
||||||
)
|
)
|
||||||
|
|
||||||
scrimOverlayId = ResourceMappingPatch.resourceMappings.single {
|
scrimOverlayId = ResourceMappingPatch[
|
||||||
it.type == "id" && it.name == "scrim_overlay"
|
"id",
|
||||||
}.id
|
"scrim_overlay",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,9 @@ import com.android.tools.smali.dexlib2.iface.reference.TypeReference
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import app.revanced.patches.youtube.misc.settings.SettingsResourcePatch
|
|||||||
@Patch(
|
@Patch(
|
||||||
dependencies = [
|
dependencies = [
|
||||||
SettingsPatch::class,
|
SettingsPatch::class,
|
||||||
AddResourcesPatch::class
|
AddResourcesPatch::class,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
|
internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
|
||||||
internal var oldUIDislikeId: Long = -1
|
internal var oldUIDislikeId: Long = -1
|
||||||
@@ -25,11 +25,12 @@ internal object ReturnYouTubeDislikeResourcePatch : ResourcePatch() {
|
|||||||
key = "revanced_settings_screen_09",
|
key = "revanced_settings_screen_09",
|
||||||
titleKey = "revanced_ryd_settings_title",
|
titleKey = "revanced_ryd_settings_title",
|
||||||
summaryKey = null,
|
summaryKey = null,
|
||||||
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent")
|
intent = SettingsPatch.newIntent("revanced_ryd_settings_intent"),
|
||||||
)
|
)
|
||||||
|
|
||||||
oldUIDislikeId = ResourceMappingPatch.resourceMappings.single {
|
oldUIDislikeId = ResourceMappingPatch[
|
||||||
it.type == "id" && it.name == "dislike_button"
|
"id",
|
||||||
}.id
|
"dislike_button",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -35,7 +35,9 @@ import app.revanced.util.exception
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -15,18 +15,18 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
|
|||||||
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
|
internal var inlineTimeBarPlayedNotHighlightedColorId = -1L
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
fun findColorResource(resourceName: String): Long {
|
reelTimeBarPlayedColorId = ResourceMappingPatch[
|
||||||
return ResourceMappingPatch.resourceMappings
|
"color",
|
||||||
.find { it.type == "color" && it.name == resourceName }?.id
|
"reel_time_bar_played_color",
|
||||||
?: throw PatchException("Could not find color resource: $resourceName")
|
]
|
||||||
}
|
inlineTimeBarColorizedBarPlayedColorDarkId = ResourceMappingPatch[
|
||||||
|
"color",
|
||||||
reelTimeBarPlayedColorId =
|
"inline_time_bar_colorized_bar_played_color_dark",
|
||||||
findColorResource("reel_time_bar_played_color")
|
]
|
||||||
inlineTimeBarColorizedBarPlayedColorDarkId =
|
inlineTimeBarPlayedNotHighlightedColorId = ResourceMappingPatch[
|
||||||
findColorResource("inline_time_bar_colorized_bar_played_color_dark")
|
"color",
|
||||||
inlineTimeBarPlayedNotHighlightedColorId =
|
"inline_time_bar_played_not_highlighted_color",
|
||||||
findColorResource("inline_time_bar_played_not_highlighted_color")
|
]
|
||||||
|
|
||||||
// Edit the resume playback drawable and replace the progress bar with a custom drawable
|
// Edit the resume playback drawable and replace the progress bar with a custom drawable
|
||||||
context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor ->
|
context.xmlEditor["res/drawable/resume_playback_progressbar_drawable.xml"].use { editor ->
|
||||||
@@ -39,10 +39,9 @@ internal object SeekbarColorResourcePatch : ResourcePatch() {
|
|||||||
}
|
}
|
||||||
val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element
|
val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element
|
||||||
val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element
|
val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element
|
||||||
val replacementNode =
|
val replacementNode = document.createElement(
|
||||||
document.createElement(
|
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable",
|
||||||
"app.revanced.integrations.youtube.patches.theme.ProgressBarDrawable",
|
)
|
||||||
)
|
|
||||||
scaleNode.replaceChild(replacementNode, shapeNode)
|
scaleNode.replaceChild(replacementNode, shapeNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package app.revanced.patches.youtube.layout.sponsorblock
|
package app.revanced.patches.youtube.layout.sponsorblock
|
||||||
|
|
||||||
import app.revanced.util.exception
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
@@ -25,6 +24,7 @@ import app.revanced.patches.youtube.shared.fingerprints.SeekbarFingerprint
|
|||||||
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
|
import app.revanced.patches.youtube.shared.fingerprints.SeekbarOnDrawFingerprint
|
||||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||||
|
import app.revanced.util.exception
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.*
|
import com.android.tools.smali.dexlib2.iface.instruction.*
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||||
@@ -37,7 +37,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
|||||||
description = "Adds options to enable and configure SponsorBlock, which can skip undesired video segments such as sponsored content.",
|
description = "Adds options to enable and configure SponsorBlock, which can skip undesired video segments such as sponsored content.",
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
"com.google.android.youtube", [
|
"com.google.android.youtube",
|
||||||
|
[
|
||||||
"18.48.39",
|
"18.48.39",
|
||||||
"18.49.37",
|
"18.49.37",
|
||||||
"19.01.34",
|
"19.01.34",
|
||||||
@@ -48,9 +49,11 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
]
|
"19.10.39",
|
||||||
)
|
"19.11.43",
|
||||||
|
],
|
||||||
|
),
|
||||||
],
|
],
|
||||||
dependencies = [
|
dependencies = [
|
||||||
IntegrationsPatch::class,
|
IntegrationsPatch::class,
|
||||||
@@ -60,8 +63,8 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
|||||||
// Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts.
|
// Used to prevent SponsorBlock from running on Shorts because SponsorBlock does not yet support Shorts.
|
||||||
PlayerTypeHookPatch::class,
|
PlayerTypeHookPatch::class,
|
||||||
PlayerControlsBytecodePatch::class,
|
PlayerControlsBytecodePatch::class,
|
||||||
SponsorBlockResourcePatch::class
|
SponsorBlockResourcePatch::class,
|
||||||
]
|
],
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object SponsorBlockBytecodePatch : BytecodePatch(
|
object SponsorBlockBytecodePatch : BytecodePatch(
|
||||||
@@ -69,8 +72,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
SeekbarFingerprint,
|
SeekbarFingerprint,
|
||||||
AppendTimeFingerprint,
|
AppendTimeFingerprint,
|
||||||
LayoutConstructorFingerprint,
|
LayoutConstructorFingerprint,
|
||||||
AutoRepeatParentFingerprint
|
AutoRepeatParentFingerprint,
|
||||||
)
|
),
|
||||||
) {
|
) {
|
||||||
private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
|
private const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;"
|
"Lapp/revanced/integrations/youtube/sponsorblock/SegmentPlaybackController;"
|
||||||
@@ -83,8 +86,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
LayoutConstructorFingerprint.result?.let {
|
LayoutConstructorFingerprint.result?.let {
|
||||||
if (!ControlsOverlayFingerprint.resolve(context, it.classDef))
|
if (!ControlsOverlayFingerprint.resolve(context, it.classDef)) {
|
||||||
throw ControlsOverlayFingerprint.exception
|
throw ControlsOverlayFingerprint.exception
|
||||||
|
}
|
||||||
} ?: throw LayoutConstructorFingerprint.exception
|
} ?: throw LayoutConstructorFingerprint.exception
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -93,7 +97,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
with(VideoInformationPatch) {
|
with(VideoInformationPatch) {
|
||||||
videoTimeHook(
|
videoTimeHook(
|
||||||
INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR,
|
INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR,
|
||||||
"setVideoTime"
|
"setVideoTime",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +125,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
seekbarMethod.addInstruction(
|
seekbarMethod.addInstruction(
|
||||||
moveRectangleToRegisterIndex + 1,
|
moveRectangleToRegisterIndex + 1,
|
||||||
"invoke-static/range {p0 .. p0}, " +
|
"invoke-static/range {p0 .. p0}, " +
|
||||||
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V"
|
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarRect(Ljava/lang/Object;)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
for ((index, instruction) in seekbarMethodInstructions.withIndex()) {
|
for ((index, instruction) in seekbarMethodInstructions.withIndex()) {
|
||||||
@@ -136,7 +140,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
seekbarMethod.addInstruction(
|
seekbarMethod.addInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"invoke-static {v${invokeInstruction.registerC}}, " +
|
"invoke-static {v${invokeInstruction.registerC}}, " +
|
||||||
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V"
|
"$INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->setSponsorBarThickness(I)V",
|
||||||
)
|
)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -154,7 +158,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
}
|
}
|
||||||
seekbarMethod.addInstruction(
|
seekbarMethod.addInstruction(
|
||||||
i,
|
i,
|
||||||
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V"
|
"invoke-static {v$canvasInstance, v$centerY}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->drawSponsorTimeBars(Landroid/graphics/Canvas;F)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
break
|
break
|
||||||
@@ -166,9 +170,9 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult
|
val controlsMethodResult = PlayerControlsBytecodePatch.showPlayerControlsFingerprintResult
|
||||||
|
|
||||||
val controlsLayoutStubResourceId =
|
val controlsLayoutStubResourceId =
|
||||||
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "controls_layout_stub" }.id
|
ResourceMappingPatch["id", "controls_layout_stub"]
|
||||||
val zoomOverlayResourceId =
|
val zoomOverlayResourceId =
|
||||||
ResourceMappingPatch.resourceMappings.single { it.type == "id" && it.name == "video_zoom_overlay_stub" }.id
|
ResourceMappingPatch["id", "video_zoom_overlay_stub"]
|
||||||
|
|
||||||
methods@ for (method in controlsMethodResult.mutableClass.methods) {
|
methods@ for (method in controlsMethodResult.mutableClass.methods) {
|
||||||
val instructions = method.implementation?.instructions!!
|
val instructions = method.implementation?.instructions!!
|
||||||
@@ -188,7 +192,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
"""
|
"""
|
||||||
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
|
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
|
||||||
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
|
invoke-static {v$inflatedViewRegister}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/View;)V
|
||||||
"""
|
""",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,7 +205,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
"""
|
"""
|
||||||
invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
|
invoke-static {p1}, $INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
|
||||||
invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
|
invoke-static {p1}, $INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR->changeVisibilityNegatedImmediate(Z)V
|
||||||
""".trimIndent()
|
""".trimIndent(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,7 +227,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
"""
|
"""
|
||||||
invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String;
|
invoke-static {v$targetRegister}, $INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR->appendTimeWithoutSegments(Ljava/lang/String;)Ljava/lang/String;
|
||||||
move-result-object v$targetRegister
|
move-result-object v$targetRegister
|
||||||
"""
|
""",
|
||||||
)
|
)
|
||||||
|
|
||||||
// initialize the player controller
|
// initialize the player controller
|
||||||
@@ -236,10 +240,10 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA
|
val frameLayoutRegister = (getInstruction(startIndex + 2) as OneRegisterInstruction).registerA
|
||||||
addInstruction(
|
addInstruction(
|
||||||
startIndex + 3,
|
startIndex + 3,
|
||||||
"invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V"
|
"invoke-static {v$frameLayoutRegister}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->initialize(Landroid/view/ViewGroup;)V",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} ?: throw ControlsOverlayFingerprint.exception
|
} ?: throw ControlsOverlayFingerprint.exception
|
||||||
|
|
||||||
// get rectangle field name
|
// get rectangle field name
|
||||||
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
|
RectangleFieldInvalidatorFingerprint.resolve(context, seekbarSignatureResult.classDef)
|
||||||
@@ -258,7 +262,8 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
|
fun MutableMethod.replaceStringInstruction(index: Int, instruction: Instruction, with: String) {
|
||||||
val register = (instruction as OneRegisterInstruction).registerA
|
val register = (instruction as OneRegisterInstruction).registerA
|
||||||
this.replaceInstruction(
|
this.replaceInstruction(
|
||||||
index, "const-string v$register, \"$with\""
|
index,
|
||||||
|
"const-string v$register, \"$with\"",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
for ((index, it) in method.implementation!!.instructions.withIndex()) {
|
for ((index, it) in method.implementation!!.instructions.withIndex()) {
|
||||||
@@ -268,13 +273,12 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
"replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction(
|
"replaceMeWithsetSponsorBarRect" -> method.replaceStringInstruction(
|
||||||
index,
|
index,
|
||||||
it,
|
it,
|
||||||
rectangleFieldName
|
rectangleFieldName,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings")
|
} ?: throw PatchException("Could not find the method which contains the replaceMeWith* strings")
|
||||||
|
|
||||||
|
|
||||||
// The vote and create segment buttons automatically change their visibility when appropriate,
|
// The vote and create segment buttons automatically change their visibility when appropriate,
|
||||||
// but if buttons are showing when the end of the video is reached then they will not automatically hide.
|
// but if buttons are showing when the end of the video is reached then they will not automatically hide.
|
||||||
// Add a hook to forcefully hide when the end of the video is reached.
|
// Add a hook to forcefully hide when the end of the video is reached.
|
||||||
@@ -283,7 +287,7 @@ object SponsorBlockBytecodePatch : BytecodePatch(
|
|||||||
it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef)
|
it.resolve(context, AutoRepeatParentFingerprint.result!!.classDef)
|
||||||
}.result?.mutableMethod?.addInstruction(
|
}.result?.mutableMethod?.addInstruction(
|
||||||
0,
|
0,
|
||||||
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V"
|
"invoke-static {}, $INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR->endOfVideoReached()V",
|
||||||
) ?: throw AutoRepeatFingerprint.exception
|
) ?: throw AutoRepeatFingerprint.exception
|
||||||
|
|
||||||
// TODO: isSBChannelWhitelisting implementation
|
// TODO: isSBChannelWhitelisting implementation
|
||||||
|
|||||||
@@ -43,8 +43,10 @@ internal object SponsorBlockResourcePatch : ResourcePatch() {
|
|||||||
// required resource for back button, because when the base APK is used, this resource will not exist
|
// required resource for back button, because when the base APK is used, this resource will not exist
|
||||||
"drawable",
|
"drawable",
|
||||||
"revanced_sb_adjust.xml",
|
"revanced_sb_adjust.xml",
|
||||||
|
"revanced_sb_backward.xml",
|
||||||
"revanced_sb_compare.xml",
|
"revanced_sb_compare.xml",
|
||||||
"revanced_sb_edit.xml",
|
"revanced_sb_edit.xml",
|
||||||
|
"revanced_sb_forward.xml",
|
||||||
"revanced_sb_logo.xml",
|
"revanced_sb_logo.xml",
|
||||||
"revanced_sb_publish.xml",
|
"revanced_sb_publish.xml",
|
||||||
"revanced_sb_voting.xml",
|
"revanced_sb_voting.xml",
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ internal object MiniPlayerDimensionsCalculatorParentFingerprint : MethodFingerpr
|
|||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
Opcode.CONST_HIGH16,
|
Opcode.CONST_HIGH16,
|
||||||
Opcode.ADD_FLOAT_2ADDR,
|
Opcode.ADD_FLOAT_2ADDR,
|
||||||
Opcode.MUL_FLOAT,
|
null, // Opcode.MUL_FLOAT or Opcode.MUL_FLOAT_2ADDR
|
||||||
Opcode.CONST_4,
|
Opcode.CONST_4,
|
||||||
Opcode.INVOKE_STATIC,
|
Opcode.INVOKE_STATIC,
|
||||||
Opcode.MOVE_RESULT,
|
Opcode.MOVE_RESULT,
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatc
|
|||||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||||
import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch
|
import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch
|
||||||
|
import app.revanced.patches.youtube.layout.theme.fingerprints.ThemeHelperDarkColorFingerprint
|
||||||
|
import app.revanced.patches.youtube.layout.theme.fingerprints.ThemeHelperLightColorFingerprint
|
||||||
import app.revanced.patches.youtube.layout.theme.fingerprints.UseGradientLoadingScreenFingerprint
|
import app.revanced.patches.youtube.layout.theme.fingerprints.UseGradientLoadingScreenFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import app.revanced.util.indexOfFirstWideLiteralInstructionValue
|
import app.revanced.util.indexOfFirstWideLiteralInstructionValue
|
||||||
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
@@ -47,14 +50,20 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object ThemeBytecodePatch : BytecodePatch(
|
object ThemeBytecodePatch : BytecodePatch(
|
||||||
setOf(UseGradientLoadingScreenFingerprint)
|
setOf(
|
||||||
|
UseGradientLoadingScreenFingerprint,
|
||||||
|
ThemeHelperLightColorFingerprint,
|
||||||
|
ThemeHelperDarkColorFingerprint
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/integrations/youtube/patches/theme/ThemePatch;"
|
"Lapp/revanced/integrations/youtube/patches/theme/ThemePatch;"
|
||||||
@@ -121,6 +130,21 @@ object ThemeBytecodePatch : BytecodePatch(
|
|||||||
)
|
)
|
||||||
} ?: throw UseGradientLoadingScreenFingerprint.exception
|
} ?: throw UseGradientLoadingScreenFingerprint.exception
|
||||||
|
|
||||||
|
|
||||||
|
mapOf(
|
||||||
|
ThemeHelperLightColorFingerprint to lightThemeBackgroundColor,
|
||||||
|
ThemeHelperDarkColorFingerprint to darkThemeBackgroundColor
|
||||||
|
).forEach { (fingerprint, color) ->
|
||||||
|
fingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
|
addInstructions(
|
||||||
|
0, """
|
||||||
|
const-string v0, "$color"
|
||||||
|
return-object v0
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LithoColorHookPatch.lithoColorOverrideHook(INTEGRATIONS_CLASS_DESCRIPTOR, "getValue")
|
LithoColorHookPatch.lithoColorOverrideHook(INTEGRATIONS_CLASS_DESCRIPTOR, "getValue")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.theme.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal object ThemeHelperDarkColorFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
|
||||||
|
returnType = "Ljava/lang/String;",
|
||||||
|
parameters = listOf(),
|
||||||
|
customFingerprint = { methodDef, classDef ->
|
||||||
|
methodDef.name == "darkThemeResourceName" &&
|
||||||
|
classDef.type == SettingsPatch.THEME_HELPER_DESCRIPTOR
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package app.revanced.patches.youtube.layout.theme.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal object ThemeHelperLightColorFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
|
||||||
|
returnType = "Ljava/lang/String;",
|
||||||
|
parameters = listOf(),
|
||||||
|
customFingerprint = { methodDef, classDef ->
|
||||||
|
methodDef.name == "lightThemeResourceName" &&
|
||||||
|
classDef.type == SettingsPatch.THEME_HELPER_DESCRIPTOR
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -61,7 +61,9 @@ import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import app.revanced.util.exception
|
|||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Spoof device dimensions",
|
name = "Spoof device dimensions",
|
||||||
description = "Adds an option to spoof the device dimensions which unlocks higher video qualities if they aren't available on the device.",
|
description = "Adds an option to spoof the device dimensions which can unlock higher video qualities.",
|
||||||
dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class],
|
dependencies = [IntegrationsPatch::class, SettingsPatch::class, AddResourcesPatch::class],
|
||||||
compatiblePackages = [
|
compatiblePackages = [
|
||||||
CompatiblePackage(
|
CompatiblePackage(
|
||||||
@@ -34,7 +34,9 @@ import app.revanced.util.exception
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ object SpoofSignatureResourcePatch : ResourcePatch() {
|
|||||||
internal var scrubbedPreviewThumbnailResourceId: Long = -1
|
internal var scrubbedPreviewThumbnailResourceId: Long = -1
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch.resourceMappings.single {
|
scrubbedPreviewThumbnailResourceId = ResourceMappingPatch[
|
||||||
it.type == "id" && it.name == "thumbnail"
|
"id",
|
||||||
}.id
|
"thumbnail",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ object GmsCoreSupportPatch : BaseGmsCoreSupportPatch(
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37",
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ import com.android.tools.smali.dexlib2.iface.reference.StringReference
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,19 +6,14 @@ import app.revanced.patcher.patch.annotation.Patch
|
|||||||
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
import app.revanced.patches.shared.misc.mapping.ResourceMappingPatch
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
dependencies = [ResourceMappingPatch::class]
|
dependencies = [ResourceMappingPatch::class],
|
||||||
)
|
)
|
||||||
internal object NavigationBarHookResourcePatch : ResourcePatch() {
|
internal object NavigationBarHookResourcePatch : ResourcePatch() {
|
||||||
internal var imageOnlyTabResourceId: Long = -1
|
internal var imageOnlyTabResourceId: Long = -1
|
||||||
internal var actionBarSearchResultsViewMicId: Long = -1
|
internal var actionBarSearchResultsViewMicId: Long = -1
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
imageOnlyTabResourceId = ResourceMappingPatch.resourceMappings.first {
|
imageOnlyTabResourceId = ResourceMappingPatch["layout", "image_only_tab"]
|
||||||
it.type == "layout" && it.name == "image_only_tab"
|
actionBarSearchResultsViewMicId = ResourceMappingPatch["layout", "action_bar_search_results_view_mic"]
|
||||||
}.id
|
|
||||||
|
|
||||||
actionBarSearchResultsViewMicId = ResourceMappingPatch.resourceMappings.first {
|
|
||||||
it.type == "layout" && it.name == "action_bar_search_results_view_mic"
|
|
||||||
}.id
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ object BottomControlsResourcePatch : ResourcePatch(), Closeable {
|
|||||||
resourceContext = context
|
resourceContext = context
|
||||||
targetDocumentEditor = context.xmlEditor[TARGET_RESOURCE]
|
targetDocumentEditor = context.xmlEditor[TARGET_RESOURCE]
|
||||||
|
|
||||||
bottomUiContainerResourceId = ResourceMappingPatch.resourceMappings
|
bottomUiContainerResourceId = ResourceMappingPatch["id", "bottom_ui_container_stub"]
|
||||||
.single { it.type == "id" && it.name == "bottom_ui_container_stub" }.id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
|||||||
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
|
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
|
||||||
import app.revanced.patches.shared.misc.settings.preference.InputType
|
import app.revanced.patches.shared.misc.settings.preference.InputType
|
||||||
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
|
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
|
||||||
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
|
||||||
import app.revanced.patches.shared.misc.settings.preference.TextPreference
|
import app.revanced.patches.shared.misc.settings.preference.TextPreference
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
@@ -39,12 +40,20 @@ object SettingsPatch :
|
|||||||
private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations/youtube"
|
private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations/youtube"
|
||||||
private const val ACTIVITY_HOOK_CLASS_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settings/LicenseActivityHook;"
|
private const val ACTIVITY_HOOK_CLASS_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settings/LicenseActivityHook;"
|
||||||
|
|
||||||
private const val THEME_HELPER_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/ThemeHelper;"
|
internal const val THEME_HELPER_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/ThemeHelper;"
|
||||||
private const val SET_THEME_METHOD_NAME: String = "setTheme"
|
private const val SET_THEME_METHOD_NAME: String = "setTheme"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
|
// Add an about preference to the top.
|
||||||
|
SettingsResourcePatch += NonInteractivePreference(
|
||||||
|
key = "revanced_settings_screen_00_about",
|
||||||
|
summaryKey = null,
|
||||||
|
tag = "app.revanced.integrations.youtube.settings.preference.ReVancedYouTubeAboutPreference",
|
||||||
|
selectable = true,
|
||||||
|
)
|
||||||
|
|
||||||
PreferenceScreen.MISC.addPreferences(
|
PreferenceScreen.MISC.addPreferences(
|
||||||
TextPreference(
|
TextPreference(
|
||||||
key = null,
|
key = null,
|
||||||
@@ -52,7 +61,7 @@ object SettingsPatch :
|
|||||||
summaryKey = "revanced_pref_import_export_summary",
|
summaryKey = "revanced_pref_import_export_summary",
|
||||||
inputType = InputType.TEXT_MULTI_LINE,
|
inputType = InputType.TEXT_MULTI_LINE,
|
||||||
tag = "app.revanced.integrations.shared.settings.preference.ImportExportPreference",
|
tag = "app.revanced.integrations.shared.settings.preference.ImportExportPreference",
|
||||||
),
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
SetThemeFingerprint.result?.mutableMethod?.let { setThemeMethod ->
|
SetThemeFingerprint.result?.mutableMethod?.let { setThemeMethod ->
|
||||||
@@ -69,7 +78,7 @@ object SettingsPatch :
|
|||||||
replaceInstruction(
|
replaceInstruction(
|
||||||
returnIndex,
|
returnIndex,
|
||||||
"invoke-static { v$register }, " +
|
"invoke-static { v$register }, " +
|
||||||
"$THEME_HELPER_DESCRIPTOR->$SET_THEME_METHOD_NAME(Ljava/lang/Object;)V",
|
"$THEME_HELPER_DESCRIPTOR->$SET_THEME_METHOD_NAME(Ljava/lang/Enum;)V",
|
||||||
)
|
)
|
||||||
addInstruction(returnIndex + 1, "return-object v$register")
|
addInstruction(returnIndex + 1, "return-object v$register")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,7 @@ object SettingsResourcePatch : BaseSettingsResourcePatch(
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
// Used for a fingerprint from SettingsPatch.
|
// Used for a fingerprint from SettingsPatch.
|
||||||
appearanceStringId =
|
appearanceStringId = ResourceMappingPatch["string", "app_theme_appearance_dark"]
|
||||||
ResourceMappingPatch.resourceMappings.find {
|
|
||||||
it.type == "string" && it.name == "app_theme_appearance_dark"
|
|
||||||
}!!.id
|
|
||||||
|
|
||||||
arrayOf(
|
arrayOf(
|
||||||
ResourceGroup("layout", "revanced_settings_with_toolbar.xml"),
|
ResourceGroup("layout", "revanced_settings_with_toolbar.xml"),
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ import app.revanced.patches.youtube.video.speed.remember.RememberPlaybackSpeedPa
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ internal object CustomPlaybackSpeedResourcePatch : ResourcePatch() {
|
|||||||
var speedUnavailableId: Long = -1
|
var speedUnavailableId: Long = -1
|
||||||
|
|
||||||
override fun execute(context: ResourceContext) {
|
override fun execute(context: ResourceContext) {
|
||||||
speedUnavailableId = ResourceMappingPatch.resourceMappings.single {
|
speedUnavailableId = ResourceMappingPatch[
|
||||||
it.type == "string" && it.name == "varispeed_unavailable_message"
|
"string",
|
||||||
}.id
|
"varispeed_unavailable_message",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
|||||||
"19.06.39",
|
"19.06.39",
|
||||||
"19.07.40",
|
"19.07.40",
|
||||||
"19.08.36",
|
"19.08.36",
|
||||||
"19.09.37"
|
"19.09.38",
|
||||||
|
"19.10.39",
|
||||||
|
"19.11.43"
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package app.revanced.patches.youtube.video.videoqualitymenu
|
package app.revanced.patches.youtube.video.videoqualitymenu
|
||||||
|
|
||||||
import app.revanced.patcher.data.ResourceContext
|
import app.revanced.patcher.data.ResourceContext
|
||||||
import app.revanced.patcher.patch.PatchException
|
|
||||||
import app.revanced.patcher.patch.ResourcePatch
|
import app.revanced.patcher.patch.ResourcePatch
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
import app.revanced.patches.all.misc.resources.AddResourcesPatch
|
||||||
@@ -10,7 +9,7 @@ import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
|||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class]
|
dependencies = [SettingsPatch::class, ResourceMappingPatch::class, AddResourcesPatch::class],
|
||||||
)
|
)
|
||||||
object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
|
object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
|
||||||
internal var videoQualityBottomSheetListFragmentTitle = -1L
|
internal var videoQualityBottomSheetListFragmentTitle = -1L
|
||||||
@@ -19,13 +18,13 @@ object RestoreOldVideoQualityMenuResourcePatch : ResourcePatch() {
|
|||||||
AddResourcesPatch(this::class)
|
AddResourcesPatch(this::class)
|
||||||
|
|
||||||
SettingsPatch.PreferenceScreen.VIDEO.addPreferences(
|
SettingsPatch.PreferenceScreen.VIDEO.addPreferences(
|
||||||
SwitchPreference("revanced_restore_old_video_quality_menu")
|
SwitchPreference("revanced_restore_old_video_quality_menu"),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun findResource(name: String) = ResourceMappingPatch.resourceMappings.find { it.name == name }?.id
|
|
||||||
?: throw PatchException("Could not find resource")
|
|
||||||
|
|
||||||
// Used for the old type of the video quality menu.
|
// Used for the old type of the video quality menu.
|
||||||
videoQualityBottomSheetListFragmentTitle = findResource("video_quality_bottom_sheet_list_fragment_title")
|
videoQualityBottomSheetListFragmentTitle = ResourceMappingPatch[
|
||||||
|
"layout",
|
||||||
|
"video_quality_bottom_sheet_list_fragment_title",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
|
|||||||
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
|
|
||||||
|
|
||||||
fun MethodFingerprint.resultOrThrow() = result ?: throw exception
|
fun MethodFingerprint.resultOrThrow() = result ?: throw exception
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,24 +58,41 @@ fun MutableMethod.injectHideViewCall(
|
|||||||
insertIndex: Int,
|
insertIndex: Int,
|
||||||
viewRegister: Int,
|
viewRegister: Int,
|
||||||
classDescriptor: String,
|
classDescriptor: String,
|
||||||
targetMethod: String
|
targetMethod: String,
|
||||||
) = addInstruction(
|
) = addInstruction(
|
||||||
insertIndex,
|
insertIndex,
|
||||||
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V"
|
"invoke-static { v$viewRegister }, $classDescriptor->$targetMethod(Landroid/view/View;)V",
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the index of the first instruction with the id of the given resource name.
|
* Get the index of the first instruction with the id of the given resource name.
|
||||||
|
*
|
||||||
|
* Requires [ResourceMappingPatch] as a dependency.
|
||||||
*
|
*
|
||||||
* @param resourceName the name of the resource to find the id for.
|
* @param resourceName the name of the resource to find the id for.
|
||||||
* @return the index of the first instruction with the id of the given resource name, or -1 if not found.
|
* @return the index of the first instruction with the id of the given resource name, or -1 if not found.
|
||||||
|
* @throws PatchException if the resource cannot be found.
|
||||||
|
* @see [indexOfIdResourceOrThrow]
|
||||||
*/
|
*/
|
||||||
fun Method.findIndexForIdResource(resourceName: String): Int {
|
fun Method.indexOfIdResource(resourceName: String): Int {
|
||||||
fun getIdResourceId(resourceName: String) = ResourceMappingPatch.resourceMappings.single {
|
val resourceId = ResourceMappingPatch["id", resourceName]
|
||||||
it.type == "id" && it.name == resourceName
|
return indexOfFirstWideLiteralInstructionValue(resourceId)
|
||||||
}.id
|
}
|
||||||
|
|
||||||
return indexOfFirstWideLiteralInstructionValue(getIdResourceId(resourceName))
|
/**
|
||||||
|
* Get the index of the first instruction with the id of the given resource name or throw a [PatchException].
|
||||||
|
*
|
||||||
|
* Requires [ResourceMappingPatch] as a dependency.
|
||||||
|
*
|
||||||
|
* @throws [PatchException] if the resource is not found, or the method does not contain the resource id literal value.
|
||||||
|
*/
|
||||||
|
fun Method.indexOfIdResourceOrThrow(resourceName: String): Int {
|
||||||
|
val index = indexOfIdResource(resourceName)
|
||||||
|
if (index < 0) {
|
||||||
|
throw PatchException("Found resource id for: '$resourceName' but method does not contain the id: $this")
|
||||||
|
}
|
||||||
|
|
||||||
|
return index
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -130,27 +146,29 @@ inline fun <reified T : Reference> Instruction.getReference() = (this as? Refere
|
|||||||
fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) =
|
fun Method.indexOfFirstInstruction(predicate: Instruction.() -> Boolean) =
|
||||||
this.implementation!!.instructions.indexOfFirst(predicate)
|
this.implementation!!.instructions.indexOfFirst(predicate)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the resolved methods of [MethodFingerprint]s early.
|
* Return the resolved methods of [MethodFingerprint]s early.
|
||||||
*/
|
*/
|
||||||
fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) {
|
fun List<MethodFingerprint>.returnEarly(bool: Boolean = false) {
|
||||||
val const = if (bool) "0x1" else "0x0"
|
val const = if (bool) "0x1" else "0x0"
|
||||||
this.forEach { fingerprint ->
|
this.forEach { fingerprint ->
|
||||||
fingerprint.result?.let { result ->
|
fingerprint.result?.let { result ->
|
||||||
val stringInstructions = when (result.method.returnType.first()) {
|
val stringInstructions = when (result.method.returnType.first()) {
|
||||||
'L' -> """
|
'L' ->
|
||||||
|
"""
|
||||||
const/4 v0, $const
|
const/4 v0, $const
|
||||||
return-object v0
|
return-object v0
|
||||||
"""
|
"""
|
||||||
'V' -> "return-void"
|
'V' -> "return-void"
|
||||||
'I', 'Z' -> """
|
'I', 'Z' ->
|
||||||
|
"""
|
||||||
const/4 v0, $const
|
const/4 v0, $const
|
||||||
return v0
|
return v0
|
||||||
"""
|
"""
|
||||||
else -> throw Exception("This case should never happen.")
|
else -> throw Exception("This case should never happen.")
|
||||||
}
|
}
|
||||||
|
|
||||||
result.mutableMethod.addInstructions(0, stringInstructions)
|
result.mutableMethod.addInstructions(0, stringInstructions)
|
||||||
} ?: throw fingerprint.exception
|
} ?: throw fingerprint.exception
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,10 +53,15 @@
|
|||||||
<app id="youtube">
|
<app id="youtube">
|
||||||
<patch id="misc.settings.SettingsResourcePatch">
|
<patch id="misc.settings.SettingsResourcePatch">
|
||||||
<string name="revanced_settings">ReVanced</string>
|
<string name="revanced_settings">ReVanced</string>
|
||||||
|
<string name="revanced_settings_about_links_body">You are using ReVanced Patches version <i>%s</i></string>
|
||||||
|
<string name="revanced_settings_about_links_dev_header">Note</string>
|
||||||
|
<string name="revanced_settings_about_links_dev_body">This version is a pre-release and you may experience unexpected issues</string>
|
||||||
|
<string name="revanced_settings_about_links_header">Official links</string>
|
||||||
<string name="revanced_pref_import_export_title">Import / Export</string>
|
<string name="revanced_pref_import_export_title">Import / Export</string>
|
||||||
<string name="revanced_pref_import_export_summary">Import / Export ReVanced settings</string>
|
<string name="revanced_pref_import_export_summary">Import / Export ReVanced settings</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.settings.SettingsPatch">
|
<patch id="misc.settings.SettingsPatch">
|
||||||
|
<string name="revanced_settings_screen_00_about_title">About</string>
|
||||||
<string name="revanced_settings_screen_01_ads_title">Ads</string>
|
<string name="revanced_settings_screen_01_ads_title">Ads</string>
|
||||||
<string name="revanced_settings_screen_02_alt_thumbnails_title">Alternative thumbnails</string>
|
<string name="revanced_settings_screen_02_alt_thumbnails_title">Alternative thumbnails</string>
|
||||||
<string name="revanced_settings_screen_03_feed_title">Feed</string>
|
<string name="revanced_settings_screen_03_feed_title">Feed</string>
|
||||||
@@ -93,7 +98,7 @@
|
|||||||
<string name="revanced_hide_channel_watermark_summary_on">Watermark is hidden</string>
|
<string name="revanced_hide_channel_watermark_summary_on">Watermark is hidden</string>
|
||||||
<string name="revanced_hide_channel_watermark_summary_off">Watermark is shown</string>
|
<string name="revanced_hide_channel_watermark_summary_off">Watermark is shown</string>
|
||||||
<string name="revanced_hide_horizontal_shelves_title">Hide horizontal shelves</string>
|
<string name="revanced_hide_horizontal_shelves_title">Hide horizontal shelves</string>
|
||||||
<string name="revanced_hide_horizontal_shelves_summary_on">Shelves are hidden such as:\n• Breaking news\n• Continue watching\n• Explore more channels\n• Shopping\n• Watch it Again</string>
|
<string name="revanced_hide_horizontal_shelves_summary_on">Shelves are hidden such as:\n• Breaking news\n• Continue watching\n• Explore more channels\n• Shopping\n• Watch it again</string>
|
||||||
<string name="revanced_hide_horizontal_shelves_summary_off">Shelves are shown</string>
|
<string name="revanced_hide_horizontal_shelves_summary_off">Shelves are shown</string>
|
||||||
<!-- 'Join' should be translated using the same localized wording YouTube displays.
|
<!-- 'Join' should be translated using the same localized wording YouTube displays.
|
||||||
This appears in the video player for certain videos. -->
|
This appears in the video player for certain videos. -->
|
||||||
@@ -166,7 +171,7 @@
|
|||||||
<string name="revanced_hide_channel_bar_title">Hide channel bar</string>
|
<string name="revanced_hide_channel_bar_title">Hide channel bar</string>
|
||||||
<string name="revanced_hide_channel_bar_summary_on">Channel bar is hidden</string>
|
<string name="revanced_hide_channel_bar_summary_on">Channel bar is hidden</string>
|
||||||
<string name="revanced_hide_channel_bar_summary_off">Channel bar is shown</string>
|
<string name="revanced_hide_channel_bar_summary_off">Channel bar is shown</string>
|
||||||
<string name="revanced_hide_playables_title">Hide playables</string>
|
<string name="revanced_hide_playables_title">Hide Playables</string>
|
||||||
<string name="revanced_hide_playables_summary_on">Playables are hidden</string>
|
<string name="revanced_hide_playables_summary_on">Playables are hidden</string>
|
||||||
<string name="revanced_hide_playables_summary_off">Playables are shown</string>
|
<string name="revanced_hide_playables_summary_off">Playables are shown</string>
|
||||||
<string name="revanced_hide_quick_actions_title">Hide quick actions in fullscreen</string>
|
<string name="revanced_hide_quick_actions_title">Hide quick actions in fullscreen</string>
|
||||||
@@ -244,14 +249,14 @@
|
|||||||
<string name="revanced_hide_general_ads_summary_on">General ads are hidden</string>
|
<string name="revanced_hide_general_ads_summary_on">General ads are hidden</string>
|
||||||
<string name="revanced_hide_general_ads_summary_off">General ads are shown</string>
|
<string name="revanced_hide_general_ads_summary_off">General ads are shown</string>
|
||||||
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
|
<string name="revanced_hide_fullscreen_ads_title">Hide fullscreen ads</string>
|
||||||
<string name="revanced_hide_fullscreen_ads_summary_on">Fullscreen ads are hidden</string>
|
<string name="revanced_hide_fullscreen_ads_summary_on">Fullscreen ads are hidden\n\nThis feature is only available for older devices</string>
|
||||||
<string name="revanced_hide_fullscreen_ads_summary_off">Fullscreen ads are shown</string>
|
<string name="revanced_hide_fullscreen_ads_summary_off">Fullscreen ads are shown</string>
|
||||||
<string name="revanced_hide_buttoned_ads_title">Hide buttoned ads</string>
|
<string name="revanced_hide_buttoned_ads_title">Hide buttoned ads</string>
|
||||||
<string name="revanced_hide_buttoned_ads_summary_on">Buttoned ads are hidden</string>
|
<string name="revanced_hide_buttoned_ads_summary_on">Buttoned ads are hidden</string>
|
||||||
<string name="revanced_hide_buttoned_ads_summary_off">Buttoned ads are shown</string>
|
<string name="revanced_hide_buttoned_ads_summary_off">Buttoned ads are shown</string>
|
||||||
<string name="revanced_hide_paid_content_ads_title">Hide paid content</string>
|
<string name="revanced_hide_paid_promotion_label_title">Hide paid promotion label</string>
|
||||||
<string name="revanced_hide_paid_content_ads_summary_on">Paid content is hidden</string>
|
<string name="revanced_hide_paid_promotion_label_summary_on">Paid promotion label is hidden</string>
|
||||||
<string name="revanced_hide_paid_content_ads_summary_off">Paid content is shown</string>
|
<string name="revanced_hide_paid_promotion_label_summary_off">Paid promotion label is shown</string>
|
||||||
<string name="revanced_hide_self_sponsor_ads_title">Hide self sponsored cards</string>
|
<string name="revanced_hide_self_sponsor_ads_title">Hide self sponsored cards</string>
|
||||||
<string name="revanced_hide_self_sponsor_ads_summary_on">Self sponsored cards are hidden</string>
|
<string name="revanced_hide_self_sponsor_ads_summary_on">Self sponsored cards are hidden</string>
|
||||||
<string name="revanced_hide_self_sponsor_ads_summary_off">Self sponsored cards are shown</string>
|
<string name="revanced_hide_self_sponsor_ads_summary_off">Self sponsored cards are shown</string>
|
||||||
@@ -267,7 +272,7 @@
|
|||||||
<string name="revanced_hide_merchandise_banners_title">Hide merchandise banners</string>
|
<string name="revanced_hide_merchandise_banners_title">Hide merchandise banners</string>
|
||||||
<string name="revanced_hide_merchandise_banners_summary_on">Merchandise banners are hidden</string>
|
<string name="revanced_hide_merchandise_banners_summary_on">Merchandise banners are hidden</string>
|
||||||
<string name="revanced_hide_merchandise_banners_summary_off">Merchandise banners are shown</string>
|
<string name="revanced_hide_merchandise_banners_summary_off">Merchandise banners are shown</string>
|
||||||
<string name="revanced_hide_fullscreen_ads_feature_not_available_toast">Could not hide fullscreen ad. Hide setting disabled to prevent issues.</string>
|
<string name="revanced_hide_fullscreen_ads_feature_not_available_toast">Hide fullscreen ads only works with older devices</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="ad.getpremium.HideGetPremiumPatch">
|
<patch id="ad.getpremium.HideGetPremiumPatch">
|
||||||
<string name="revanced_hide_get_premium_title">Hide YouTube Premium promotions</string>
|
<string name="revanced_hide_get_premium_title">Hide YouTube Premium promotions</string>
|
||||||
@@ -335,6 +340,10 @@
|
|||||||
<string name="revanced_swipe_save_and_restore_brightness_title">Save and restore brightness</string>
|
<string name="revanced_swipe_save_and_restore_brightness_title">Save and restore brightness</string>
|
||||||
<string name="revanced_swipe_save_and_restore_brightness_summary_on">Save and restore brightness when exiting or entering fullscreen</string>
|
<string name="revanced_swipe_save_and_restore_brightness_summary_on">Save and restore brightness when exiting or entering fullscreen</string>
|
||||||
<string name="revanced_swipe_save_and_restore_brightness_summary_off">Do not save and restore brightness when exiting or entering fullscreen</string>
|
<string name="revanced_swipe_save_and_restore_brightness_summary_off">Do not save and restore brightness when exiting or entering fullscreen</string>
|
||||||
|
<string name="revanced_swipe_lowest_value_enable_auto_brightness_title">Enable auto-brightness gesture</string>
|
||||||
|
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_on">Swiping down to the lowest value of the brightness gesture enable auto-brightness</string>
|
||||||
|
<string name="revanced_swipe_lowest_value_enable_auto_brightness_summary_off">Swiping down to the lowest value does not enable auto-brightness</string>
|
||||||
|
<string name="revanced_swipe_lowest_value_enable_auto_brightness_overlay_text">Auto</string>
|
||||||
<string name="revanced_swipe_overlay_timeout_title">Swipe overlay timeout</string>
|
<string name="revanced_swipe_overlay_timeout_title">Swipe overlay timeout</string>
|
||||||
<string name="revanced_swipe_overlay_timeout_summary">The amount of milliseconds the overlay is visible</string>
|
<string name="revanced_swipe_overlay_timeout_summary">The amount of milliseconds the overlay is visible</string>
|
||||||
<string name="revanced_swipe_text_overlay_size_title">Swipe overlay text size</string>
|
<string name="revanced_swipe_text_overlay_size_title">Swipe overlay text size</string>
|
||||||
@@ -384,11 +393,6 @@
|
|||||||
<string name="revanced_hide_playlist_button_title">Hide Save to playlist</string>
|
<string name="revanced_hide_playlist_button_title">Hide Save to playlist</string>
|
||||||
<string name="revanced_hide_playlist_button_summary_on">Save to playlist button is hidden</string>
|
<string name="revanced_hide_playlist_button_summary_on">Save to playlist button is hidden</string>
|
||||||
<string name="revanced_hide_playlist_button_summary_off">Save to playlist button is shown</string>
|
<string name="revanced_hide_playlist_button_summary_off">Save to playlist button is shown</string>
|
||||||
<!-- 'Shop' should be translated with the same localized wording that YouTube displays.
|
|
||||||
Shop button appears only for some videos in certain regions. Translate the button name normally if this menu is never shown. -->
|
|
||||||
<string name="revanced_hide_shop_button_title">Hide Shop</string>
|
|
||||||
<string name="revanced_hide_shop_button_summary_on">Shop button is hidden</string>
|
|
||||||
<string name="revanced_hide_shop_button_summary_off">Shop button is shown</string>
|
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="layout.buttons.autoplay.HideAutoplayButtonPatch">
|
<patch id="layout.buttons.autoplay.HideAutoplayButtonPatch">
|
||||||
<string name="revanced_hide_autoplay_button_title">Hide autoplay button</string>
|
<string name="revanced_hide_autoplay_button_title">Hide autoplay button</string>
|
||||||
@@ -571,24 +575,24 @@
|
|||||||
<string name="revanced_hide_shorts_subscribe_button_title">Hide subscribe button</string>
|
<string name="revanced_hide_shorts_subscribe_button_title">Hide subscribe button</string>
|
||||||
<string name="revanced_hide_shorts_subscribe_button_summary_on">Subscribe button is hidden</string>
|
<string name="revanced_hide_shorts_subscribe_button_summary_on">Subscribe button is hidden</string>
|
||||||
<string name="revanced_hide_shorts_subscribe_button_summary_off">Subscribe button is shown</string>
|
<string name="revanced_hide_shorts_subscribe_button_summary_off">Subscribe button is shown</string>
|
||||||
<!-- 'subscribe' should be translated using the same localized wording YouTube displays for the button. -->
|
<string name="revanced_hide_shorts_paused_overlay_buttons_title">Hide paused overlay buttons</string>
|
||||||
<string name="revanced_hide_shorts_subscribe_button_paused_title">Hide subscribe button when paused</string>
|
<string name="revanced_hide_shorts_paused_overlay_buttons_summary_on">Paused overlay buttons are hidden</string>
|
||||||
<string name="revanced_hide_shorts_subscribe_button_paused_summary_on">Subscribe button is hidden</string>
|
<string name="revanced_hide_shorts_paused_overlay_buttons_summary_off">Paused overlay buttons are shown</string>
|
||||||
<string name="revanced_hide_shorts_subscribe_button_paused_summary_off">Subscribe button is shown</string>
|
|
||||||
<!-- 'thanks' should be translated using the same localized wording YouTube displays for the button.
|
|
||||||
If the button never shows up, then translate the button name normally. -->
|
|
||||||
<string name="revanced_hide_shorts_thanks_button_title">Hide thanks button</string>
|
|
||||||
<string name="revanced_hide_shorts_thanks_button_summary_on">Thanks button is hidden</string>
|
|
||||||
<string name="revanced_hide_shorts_thanks_button_summary_off">Thanks button is shown</string>
|
|
||||||
<string name="revanced_hide_shorts_shop_button_title">Hide shop button</string>
|
<string name="revanced_hide_shorts_shop_button_title">Hide shop button</string>
|
||||||
<string name="revanced_hide_shorts_shop_button_summary_on">Shop button is hidden</string>
|
<string name="revanced_hide_shorts_shop_button_summary_on">Shop button is hidden</string>
|
||||||
<string name="revanced_hide_shorts_shop_button_summary_off">Shop button is shown</string>
|
<string name="revanced_hide_shorts_shop_button_summary_off">Shop button is shown</string>
|
||||||
<string name="revanced_hide_shorts_location_button_title">Hide location button</string>
|
<string name="revanced_hide_shorts_tagged_products_title">Hide tagged products</string>
|
||||||
<string name="revanced_hide_shorts_location_button_summary_on">Location button is hidden</string>
|
<string name="revanced_hide_shorts_tagged_products_summary_on">Tagged products are hidden</string>
|
||||||
<string name="revanced_hide_shorts_location_button_summary_off">Location button is shown</string>
|
<string name="revanced_hide_shorts_tagged_products_summary_off">Tagged products are shown</string>
|
||||||
|
<string name="revanced_hide_shorts_location_label_title">Hide location label</string>
|
||||||
|
<string name="revanced_hide_shorts_location_label_summary_on">Location label is hidden</string>
|
||||||
|
<string name="revanced_hide_shorts_location_label_summary_off">Location label is shown</string>
|
||||||
<string name="revanced_hide_shorts_save_sound_button_title">Hide save sound to playlist button</string>
|
<string name="revanced_hide_shorts_save_sound_button_title">Hide save sound to playlist button</string>
|
||||||
<string name="revanced_hide_shorts_save_sound_button_summary_on">Save sound to playlist is hidden</string>
|
<string name="revanced_hide_shorts_save_sound_button_summary_on">Save sound to playlist is hidden</string>
|
||||||
<string name="revanced_hide_shorts_save_sound_button_summary_off">Save sound to playlist is shown</string>
|
<string name="revanced_hide_shorts_save_sound_button_summary_off">Save sound to playlist is shown</string>
|
||||||
|
<string name="revanced_hide_shorts_search_suggestions_title">Hide search suggestions</string>
|
||||||
|
<string name="revanced_hide_shorts_search_suggestions_summary_on">Search suggestions are hidden</string>
|
||||||
|
<string name="revanced_hide_shorts_search_suggestions_summary_off">Search suggestions are shown</string>
|
||||||
<string name="revanced_hide_shorts_like_button_title">Hide like button</string>
|
<string name="revanced_hide_shorts_like_button_title">Hide like button</string>
|
||||||
<string name="revanced_hide_shorts_like_button_summary_on">Like button is hidden</string>
|
<string name="revanced_hide_shorts_like_button_summary_on">Like button is hidden</string>
|
||||||
<string name="revanced_hide_shorts_like_button_summary_off">Like button is shown</string>
|
<string name="revanced_hide_shorts_like_button_summary_off">Like button is shown</string>
|
||||||
@@ -999,8 +1003,9 @@
|
|||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
|
<patch id="misc.dimensions.spoof.SpoofDeviceDimensionsPatch">
|
||||||
<string name="revanced_spoof_device_dimensions_title">Spoof device dimensions</string>
|
<string name="revanced_spoof_device_dimensions_title">Spoof device dimensions</string>
|
||||||
<string name="revanced_spoof_device_dimensions_summary_on">Device dimensions spoofed</string>
|
<string name="revanced_spoof_device_dimensions_summary_on">Device dimensions spoofed\n\nHigher video qualities might be unlocked but you may experience video playback stuttering, worse battery life, and unknown side effects</string>
|
||||||
<string name="revanced_spoof_device_dimensions_summary_off">Device dimensions not spoofed\n\nSpoofing the device dimensions can unlock higher video qualities but unknown side effects may occur</string>
|
<string name="revanced_spoof_device_dimensions_summary_off">Device dimensions not spoofed\n\nEnabling this can unlock higher video qualities</string>
|
||||||
|
<string name="revanced_spoof_device_dimensions_user_dialog_message">Enabling this can cause video playback stuttering, worse battery life, and unknown side effects.</string>
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="misc.gms.GmsCoreSupportResourcePatch">
|
<patch id="misc.gms.GmsCoreSupportResourcePatch">
|
||||||
<string name="microg_settings_title">GmsCore Settings</string>
|
<string name="microg_settings_title">GmsCore Settings</string>
|
||||||
@@ -1145,9 +1150,9 @@
|
|||||||
<string name="revanced_other_category_title">Other settings</string>
|
<string name="revanced_other_category_title">Other settings</string>
|
||||||
<string name="revanced_client_ads_category_title">Client-side ads</string>
|
<string name="revanced_client_ads_category_title">Client-side ads</string>
|
||||||
<string name="revanced_surestream_ads_category_title">Server-side surestream ads</string>
|
<string name="revanced_surestream_ads_category_title">Server-side surestream ads</string>
|
||||||
<string name="revanced_debug_title">Debug logging</string>
|
<string name="revanced_twitch_debug_title">Debug logging</string>
|
||||||
<string name="revanced_debug_summary_on">Debug logs are enabled</string>
|
<string name="revanced_twitch_debug_summary_on">Debug logs are enabled</string>
|
||||||
<string name="revanced_debug_summary_off">Debug logs are disabled</string>
|
<string name="revanced_twitch_debug_summary_off">Debug logs are disabled</string>
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1,10 +1,30 @@
|
|||||||
<vector
|
<!--
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/content_copy/materialsymbolsoutlined/content_copy_wght200gradN25_24px.xml
|
||||||
android:width="24dp"
|
The icon has been resized
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24">
|
Copyright 2022 Google
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
android:pathData="M 6.8 19.5 C 6.5 19.5 6.2 19.399 6 19.199 C 5.8 19 5.7 18.699 5.7 18.399 L 5.7 7.099 L 6.8 7.099 L 6.8 18.399 L 15.7 18.399 L 15.7 19.5 L 6.8 19.5 Z M 9 17.2 C 8.7 17.2 8.4 17.1 8.2 16.9 C 8 16.7 7.9 16.4 7.9 16.1 L 7.9 5.6 C 7.9 5.3 8 5 8.2 4.8 C 8.4 4.6 8.7 4.5 9 4.5 L 17.2 4.5 C 17.5 4.5 17.8 4.6 18 4.8 C 18.2 5 18.3 5.3 18.3 5.6 L 18.3 16.1 C 18.3 16.4 18.2 16.7 18 16.9 C 17.8 17.1 17.5 17.2 17.2 17.2 L 9 17.2 Z M 9 16.1 L 17.2 16.1 L 17.2 5.6 L 9 5.6 L 9 16.1 Z M 9 16.1 L 9 5.6 L 9 16.1 Z"
|
android:fillColor="@android:color/white"
|
||||||
android:fillColor="#ffffffff"/>
|
android:pathData="m 9.7348145,16.94238 q -0.5966913,0 -1.0062178,-0.39988 Q 8.319101,16.14259 8.319101,15.5599 V 5.88248 q 0,-0.58269 0.4094957,-0.9826 Q 9.1381232,4.5 9.7348145,4.5 h 7.1494615 q 0.596701,0 1.006218,0.39988 Q 18.3,5.29979 18.3,5.88248 v 9.67742 q 0,0.58269 -0.409506,0.9826 -0.409517,0.39988 -1.006218,0.39988 z m 0,-0.82949 h 7.1494615 q 0.212367,0 0.389322,-0.1728 0.176965,-0.17283 0.176965,-0.38019 V 5.88248 q 0,-0.20738 -0.176965,-0.38019 -0.176955,-0.1728 -0.389322,-0.1728 H 9.7348145 q -0.212336,0 -0.389322,0.1728 Q 9.1685373,5.6751 9.1685373,5.88248 v 9.67742 q 0,0.20736 0.1769552,0.38019 0.176986,0.1728 0.389322,0.1728 z M 7.1157237,19.5 Q 6.519022,19.5 6.1094957,19.10009 5.7,18.70021 5.7,18.1175 V 7.61058 H 6.5494363 V 18.1175 q 0,0.20738 0.1769552,0.38018 0.1769655,0.17281 0.3893322,0.17281 H 15.114611 V 19.5 Z M 9.1685373,16.11289 V 5.32949 Z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -1,11 +1,31 @@
|
|||||||
<vector
|
<!--
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/content_copy/materialsymbolsoutlined/content_copy_wght200gradN25_24px.xml
|
||||||
android:width="24dp"
|
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/schedule/materialsymbolsoutlined/schedule_wght300_24px.xml
|
||||||
android:height="24dp"
|
This icon is the result of a combination of "content copy" and "schedule" icons.
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24">
|
|
||||||
|
Copyright 2022 Google
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
android:name="path"
|
android:fillColor="@android:color/white"
|
||||||
android:pathData="M 6.8 19.5 C 6.5 19.5 6.2 19.4 6 19.2 C 5.8 19 5.7 18.7 5.7 18.4 L 5.7 7.1 L 6.8 7.1 L 6.8 18.4 L 15.7 18.4 L 15.7 19.5 L 6.8 19.5 Z M 9 17.2 C 8.7 17.2 8.4 17.1 8.2 16.9 C 8 16.7 7.9 16.4 7.9 16.1 L 7.9 5.6 C 7.9 5.3 8 5 8.2 4.8 C 8.4 4.6 8.7 4.5 9 4.5 L 17.2 4.5 C 17.5 4.5 17.8 4.6 18 4.8 C 18.2 5 18.3 5.3 18.3 5.6 L 18.3 16.1 C 18.3 16.4 18.2 16.7 18 16.9 C 17.8 17.1 17.5 17.2 17.2 17.2 L 9 17.2 Z M 9 16.1 L 17.2 16.1 L 17.2 5.6 L 9 5.6 L 9 16.1 Z M 9 16.1 L 9 5.6 L 9 16.1 Z M 13.1 8 C 11.5 8 10.2 9.3 10.2 10.9 C 10.2 12.5 11.5 13.8 13.1 13.8 C 14.7 13.8 16 12.5 16 10.9 C 16 9.3 14.7 8 13.1 8 Z M 13.1 13.3 C 11.8 13.3 10.7 12.2 10.7 10.9 C 10.7 9.6 11.8 8.5 13.1 8.5 C 14.4 8.5 15.5 9.6 15.5 10.9 C 15.5 12.2 14.5 13.3 13.1 13.3 Z M 14.5 12 L 14.2 12.3 L 12.9 11 L 12.9 9.4 L 13.3 9.4 L 13.3 10.8 L 14.5 12 Z"
|
android:pathData="M 9.734375 4.5 C 9.3365813 4.5 9.0015328 4.6338045 8.7285156 4.9003906 C 8.4555191 5.1669968 8.3183594 5.4943533 8.3183594 5.8828125 L 8.3183594 15.560547 C 8.3183594 15.949005 8.4555191 16.276362 8.7285156 16.542969 C 9.0015328 16.809554 9.3365813 16.941406 9.734375 16.941406 L 11.259766 16.941406 C 11.220306 16.699026 11.199219 16.450296 11.199219 16.195312 C 11.199219 16.167903 11.200672 16.140551 11.201172 16.113281 L 9.734375 16.113281 C 9.5928176 16.113281 9.4636936 16.054651 9.3457031 15.939453 C 9.2277332 15.824233 9.1679687 15.698787 9.1679688 15.560547 L 9.1679688 5.8828125 C 9.1679688 5.7445594 9.2277329 5.6171596 9.3457031 5.5019531 C 9.4636936 5.3867533 9.5928176 5.3300781 9.734375 5.3300781 L 16.884766 5.3300781 C 17.026342 5.3300781 17.155468 5.3867532 17.273438 5.5019531 C 17.391413 5.6171596 17.451172 5.7445594 17.451172 5.8828125 L 17.451172 12.052734 C 17.453072 12.053553 17.455131 12.053788 17.457031 12.054688 C 17.760014 12.185563 18.041487 12.342729 18.300781 12.525391 L 18.300781 5.8828125 C 18.300781 5.4943533 18.163629 5.1669968 17.890625 4.9003906 C 17.617573 4.6338045 17.282565 4.5 16.884766 4.5 L 9.734375 4.5 z M 5.6992188 7.6113281 L 5.6992188 18.117188 C 5.6992188 18.505659 5.8363784 18.833024 6.109375 19.099609 C 6.382392 19.366216 6.717434 19.5 7.1152344 19.5 L 12.642578 19.5 C 12.600698 19.46116 12.558138 19.42142 12.517578 19.380859 C 12.299781 19.163062 12.107686 18.926178 11.939453 18.669922 L 7.1152344 18.669922 C 6.9736568 18.669922 6.8445393 18.613252 6.7265625 18.498047 C 6.6085926 18.382847 6.5488281 18.25544 6.5488281 18.117188 L 6.5488281 7.6113281 L 5.6992188 7.6113281 z M 15.75 12.5 C 15.231251 12.5 14.743359 12.598047 14.287109 12.794922 C 13.83086 12.991797 13.435156 13.260157 13.097656 13.597656 C 12.760157 13.935156 12.491797 14.33086 12.294922 14.787109 C 12.098047 15.243359 12 15.731251 12 16.25 C 12 16.768749 12.098047 17.256641 12.294922 17.712891 C 12.491797 18.16914 12.760157 18.564844 13.097656 18.902344 C 13.435156 19.239843 13.83086 19.508203 14.287109 19.705078 C 14.743359 19.901953 15.231251 20 15.75 20 C 16.268749 20 16.756641 19.901953 17.212891 19.705078 C 17.66914 19.508203 18.064844 19.239843 18.402344 18.902344 C 18.739843 18.564844 19.008203 18.16914 19.205078 17.712891 C 19.401953 17.256641 19.5 16.768749 19.5 16.25 C 19.5 15.731251 19.401953 15.243359 19.205078 14.787109 C 19.008203 14.33086 18.739843 13.935156 18.402344 13.597656 C 18.064844 13.260157 17.66914 12.991797 17.212891 12.794922 C 16.756641 12.598047 16.268749 12.5 15.75 12.5 z M 15.75 13.25 C 16.581249 13.25 17.288672 13.542578 17.873047 14.126953 C 18.457421 14.711327 18.75 15.418751 18.75 16.25 C 18.75 17.081249 18.457421 17.788672 17.873047 18.373047 C 17.288672 18.957421 16.581249 19.25 15.75 19.25 C 14.918751 19.25 14.211327 18.957421 13.626953 18.373047 C 13.042578 17.788672 12.75 17.081249 12.75 16.25 C 12.75 15.418751 13.042578 14.711327 13.626953 14.126953 C 14.211327 13.542578 14.918751 13.25 15.75 13.25 z M 15.375 14.375 L 15.375 16.400391 L 16.988281 18.011719 L 17.511719 17.488281 L 16.125 16.099609 L 16.125 14.375 L 15.375 14.375 z"/>
|
||||||
android:fillColor="#ffffffff" />
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -1,4 +1,30 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<!--
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:tint="#FFFFFF" android:height="24dp" android:width="24dp" android:viewportWidth="24" android:viewportHeight="24">
|
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/download/materialsymbolsoutlined/download_wght200gradN25_24px.xml
|
||||||
<path android:fillColor="#FFFFFF" android:pathData="M 6.0050001,16.257111 h 0.916667 v 1.666667 H 16.088333 V 16.257111 H 17.005 v 2.777778 H 6.0050001 Z M 16.5,11.4 15.8,10.7 12,14.4 V 4 h -1 v 10.4 l -3.8,-3.8 -0.7,0.7 5,5 z"/>
|
The icon has been resized
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2022 Google
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M 12,15.834271 8.2721019,12.095857 8.9799906,11.392186 11.499655,13.91185 V 4.5 h 1.011235 v 9.41185 l 2.519663,-2.519664 0.707862,0.703671 z M 6.1825058,19.5 Q 5.4750279,19.5 4.9875002,19.0125 4.5,18.524973 4.5,17.81607 v -2.619082 h 1.0112344 v 2.617631 q 0,0.252815 0.2106659,0.46348 0.2106658,0.210666 0.4634813,0.210666 H 17.814619 q 0.252815,0 0.46348,-0.210666 0.210666,-0.210665 0.210666,-0.46348 V 15.196988 H 19.5 v 2.619082 q 0,0.708903 -0.4875,1.19643 Q 18.524973,19.5 17.817522,19.5 Z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -1,10 +1,30 @@
|
|||||||
|
<!--
|
||||||
|
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/adjust/materialsymbolsoutlined/adjust_wght200gradN25_24px.xml
|
||||||
|
The icon has been resized
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2022 Google
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:tint="#FFFFFF"
|
||||||
android:height="24dp"
|
android:width="24dp"
|
||||||
android:tint="#FFFFFF"
|
android:height="24dp"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24">
|
android:viewportHeight="24">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FFFFFF"
|
android:fillColor="@android:color/white"
|
||||||
android:pathData="M12,2C6.49,2 2,6.49 2,12s4.49,10 10,10 10,-4.49 10,-10S17.51,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM15,12c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3 1.34,-3 3,-3 3,1.34 3,3z" />
|
android:pathData="m 12,14.156532 q 0.913052,0 1.534792,-0.62174 0.62174,-0.62174 0.62174,-1.534792 0,-0.913052 -0.62174,-1.534792 Q 12.913052,9.843468 12,9.843468 q -0.913052,0 -1.534792,0.62174 -0.62174,0.62174 -0.62174,1.534792 0,0.913052 0.62174,1.534792 0.62174,0.62174 1.534792,0.62174 z M 12.0052,22 Q 9.930936,22 8.1033049,21.211917 6.2756454,20.423835 4.9237012,19.072851 3.5717572,17.721839 2.7858786,15.899494 2,14.077147 2,12.005172 2,9.930908 2.788083,8.1032766 3.576166,6.2756454 4.9271491,4.9237012 6.2781605,3.5717572 8.100507,2.7858786 9.922853,2 11.994828,2 q 2.074264,0 3.901896,0.788083 1.827631,0.788083 3.179575,2.1390661 1.351944,1.3510114 2.137823,3.1733579 Q 22,9.922853 22,11.994828 q 0,2.074264 -0.788083,3.901896 -0.788082,1.827631 -2.139066,3.179575 -1.351012,1.351944 -3.173357,2.137823 Q 14.077147,22 12.005172,22 Z m -0.0059,-1.043476 q 3.738745,0 6.347988,-2.608508 2.609242,-2.608536 2.609242,-6.347309 0,-3.7387455 -2.608508,-6.347988 -2.608536,-2.6092425 -6.347309,-2.6092425 -3.7387453,0 -6.3479878,2.6085077 -2.6092425,2.6085359 -2.6092425,6.3473088 0,3.738746 2.6085077,6.347988 2.608536,2.609243 6.3473096,2.609243 z M 12,12 Z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<!--
|
||||||
|
https://github.com/google/material-design-icons/blob/9beae745bb758f3ad56654fb377ea5cf62be4915/symbols/android/fast_forward/materialsymbolsoutlined/fast_forward_wght200gradN25_24px.xml
|
||||||
|
The icon has been mirrored and resized
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2022 Google
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:tint="#FFFFFF"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="@android:color/white"
|
||||||
|
android:pathData="M 22,17.799197 V 6.2 l -8.689607,5.799598 z m -11.310393,0 V 6.2 L 2,11.999598 Z m 10.114551,-5.799599 z m -11.3103926,0 z m 11.3103926,3.582383 -5.351233,-3.582383 5.351233,-3.582384 z m -11.3103926,0 -5.3512316,-3.582383 5.3512316,-3.582384 z"/>
|
||||||
|
</vector>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user