availableClients, ClientType client) {
preferredClient = Objects.requireNonNull(client);
+ StreamingDataRequest.setClientOrderToUse(availableClients, client);
}
public static boolean spoofingToClientWithNoMultiAudioStreams() {
@@ -95,6 +97,35 @@ public class SpoofVideoStreamsPatch {
return playerRequestUri;
}
+ /**
+ * Injection point.
+ *
+ * Blocks /get_watch requests by returning an unreachable URI.
+ * /att/get requests are used to obtain a PoToken challenge.
+ * See: botGuardScript.js#L15
+ *
+ * Since the Spoof streaming data patch was implemented because a valid PoToken cannot be obtained,
+ * Blocking /att/get requests are not a problem.
+ */
+ public static String blockGetAttRequest(String originalUrlString) {
+ if (SPOOF_STREAMING_DATA) {
+ try {
+ var originalUri = Uri.parse(originalUrlString);
+ String path = originalUri.getPath();
+
+ if (path != null && path.contains("att/get")) {
+ Logger.printDebug(() -> "Blocking 'att/get' by returning internet connection check uri");
+
+ return INTERNET_CONNECTION_CHECK_URI_STRING;
+ }
+ } catch (Exception ex) {
+ Logger.printException(() -> "blockGetAttRequest failure", ex);
+ }
+ }
+
+ return originalUrlString;
+ }
+
/**
* Injection point.
*
@@ -128,7 +159,7 @@ public class SpoofVideoStreamsPatch {
/**
* Injection point.
- * Only invoked when playing a livestream on an iOS client.
+ * Only invoked when playing a livestream on an Apple client.
*/
public static boolean fixHLSCurrentTime(boolean original) {
if (!SPOOF_STREAMING_DATA) {
@@ -137,6 +168,14 @@ public class SpoofVideoStreamsPatch {
return false;
}
+ /*
+ * Injection point.
+ * Fix audio stuttering in YouTube Music.
+ */
+ public static boolean disableSABR() {
+ return SPOOF_STREAMING_DATA;
+ }
+
/**
* Injection point.
* Turns off a feature flag that interferes with spoofing.
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ButtonsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ButtonsFilter.java
index 5a61dfc82..12775ed5f 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ButtonsFilter.java
+++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/ButtonsFilter.java
@@ -7,6 +7,10 @@ final class ButtonsFilter extends Filter {
private static final String COMPACT_CHANNEL_BAR_PATH_PREFIX = "compact_channel_bar.eml";
private static final String VIDEO_ACTION_BAR_PATH_PREFIX = "video_action_bar.eml";
private static final String VIDEO_ACTION_BAR_PATH = "video_action_bar.eml";
+ /**
+ * Video bar path when the video information is collapsed. Seems to shown only with 20.14+
+ */
+ private static final String COMPACTIFY_VIDEO_ACTION_BAR_PATH = "compactify_video_action_bar.eml";
private static final String ANIMATED_VECTOR_TYPE_PATH = "AnimatedVectorType";
private final StringFilterGroup likeSubscribeGlow;
@@ -82,6 +86,10 @@ final class ButtonsFilter extends Filter {
Settings.HIDE_STOP_ADS_BUTTON,
"yt_outline_slash_circle_left"
),
+ new ByteArrayFilterGroup(
+ Settings.HIDE_COMMENTS_BUTTON,
+ "yt_outline_message_bubble_right"
+ ),
// Check for clip button both here and using a path filter,
// as there's a chance the path is a generic action button and won't contain 'clip_button'
new ByteArrayFilterGroup(
@@ -124,9 +132,8 @@ final class ButtonsFilter extends Filter {
}
if (matchedGroup == bufferFilterPathGroup) {
- // Make sure the current path is the right one
- // to avoid false positives.
- return path.startsWith(VIDEO_ACTION_BAR_PATH)
+ // Make sure the current path is the right one to avoid false positives.
+ return (path.startsWith(VIDEO_ACTION_BAR_PATH) || path.startsWith(COMPACTIFY_VIDEO_ACTION_BAR_PATH))
&& bufferButtonsGroupList.check(buffer).isFiltered();
}
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java
index 45e49919c..2af74b2a0 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java
+++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java
@@ -9,7 +9,6 @@ import static app.revanced.extension.shared.spoof.ClientType.VISIONOS;
import java.util.List;
import app.revanced.extension.shared.spoof.ClientType;
-import app.revanced.extension.shared.spoof.requests.StreamingDataRequest;
import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings("unused")
@@ -27,8 +26,7 @@ public class SpoofVideoStreamsPatch {
IPADOS
);
- ClientType client = Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
- app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.setPreferredClient(client);
- StreamingDataRequest.setClientOrderToUse(availableClients, client);
+ app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.setClientsToUse(
+ availableClients, Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get());
}
}
\ No newline at end of file
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java
index d7e1bf67e..461ac3fe6 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java
+++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/Settings.java
@@ -32,6 +32,7 @@ import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehavi
import android.graphics.Color;
import app.revanced.extension.shared.Logger;
+import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.BooleanSetting;
import app.revanced.extension.shared.settings.EnumSetting;
@@ -222,6 +223,7 @@ public class Settings extends BaseSettings {
public static final BooleanSetting DISABLE_LIKE_SUBSCRIBE_GLOW = new BooleanSetting("revanced_disable_like_subscribe_glow", FALSE);
public static final BooleanSetting HIDE_ASK_BUTTON = new BooleanSetting("revanced_hide_ask_button", FALSE);
public static final BooleanSetting HIDE_CLIP_BUTTON = new BooleanSetting("revanced_hide_clip_button", TRUE);
+ public static final BooleanSetting HIDE_COMMENTS_BUTTON = new BooleanSetting("revanced_hide_comments_button", TRUE);
public static final BooleanSetting HIDE_DOWNLOAD_BUTTON = new BooleanSetting("revanced_hide_download_button", FALSE);
public static final BooleanSetting HIDE_HYPE_BUTTON = new BooleanSetting("revanced_hide_hype_button", FALSE);
public static final BooleanSetting HIDE_LIKE_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_like_dislike_button", FALSE);
@@ -513,10 +515,14 @@ public class Settings extends BaseSettings {
DEPRECATED_SWIPE_OVERLAY_BACKGROUND_ALPHA.resetToDefault();
}
- // Old spoof versions that no longer work.
- if (SPOOF_APP_VERSION_TARGET.get().compareTo(SPOOF_APP_VERSION_TARGET.defaultValue) < 0) {
- Logger.printInfo(() -> "Resetting spoof app version target");
+ // Old spoof versions that no longer work,
+ // or is spoofing to a version the same or newer than this app.
+ if (!SPOOF_APP_VERSION_TARGET.isSetToDefault() &&
+ (SPOOF_APP_VERSION_TARGET.get().compareTo(SPOOF_APP_VERSION_TARGET.defaultValue) < 0
+ || (Utils.getAppVersionName().compareTo(SPOOF_APP_VERSION_TARGET.get()) <= 0))) {
+ Logger.printInfo(() -> "Resetting spoof app version");
SPOOF_APP_VERSION_TARGET.resetToDefault();
+ SPOOF_APP_VERSION.resetToDefault();
}
// RYD requires manually migrating old settings since the lack of
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceOriginalAudioSwitchPreference.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceOriginalAudioSwitchPreference.java
new file mode 100644
index 000000000..b6be1b893
--- /dev/null
+++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceOriginalAudioSwitchPreference.java
@@ -0,0 +1,63 @@
+package app.revanced.extension.youtube.settings.preference;
+
+import static app.revanced.extension.shared.StringRef.str;
+
+import android.content.Context;
+import android.preference.SwitchPreference;
+import android.util.AttributeSet;
+
+import app.revanced.extension.shared.spoof.ClientType;
+import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch;
+import app.revanced.extension.youtube.settings.Settings;
+
+@SuppressWarnings({"deprecation", "unused"})
+public class ForceOriginalAudioSwitchPreference extends SwitchPreference {
+
+ // Spoof stream patch is not included, or is not currently spoofing to Android Studio.
+ private static final boolean available = !SpoofVideoStreamsPatch.isPatchIncluded()
+ || !(Settings.SPOOF_VIDEO_STREAMS.get()
+ && Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.ANDROID_CREATOR);
+
+ {
+ if (!available) {
+ // Show why force audio is not available.
+ String summary = str("revanced_force_original_audio_not_available");
+ super.setSummary(summary);
+ super.setSummaryOn(summary);
+ super.setSummaryOff(summary);
+ super.setEnabled(false);
+ }
+ }
+
+ public ForceOriginalAudioSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+ public ForceOriginalAudioSwitchPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+ public ForceOriginalAudioSwitchPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+ public ForceOriginalAudioSwitchPreference(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ if (!available) {
+ return;
+ }
+
+ super.setEnabled(enabled);
+ }
+
+ @Override
+ public void setSummary(CharSequence summary) {
+ if (!available) {
+ return;
+ }
+
+ super.setSummary(summary);
+ }
+}
+
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofAudioSelectorListPreference.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofAudioSelectorListPreference.java
index d27230421..00c3f2007 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofAudioSelectorListPreference.java
+++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofAudioSelectorListPreference.java
@@ -6,7 +6,9 @@ import android.content.Context;
import android.util.AttributeSet;
import app.revanced.extension.shared.settings.preference.SortedListPreference;
+import app.revanced.extension.shared.spoof.ClientType;
import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch;
+import app.revanced.extension.youtube.settings.Settings;
@SuppressWarnings({"deprecation", "unused"})
public class SpoofAudioSelectorListPreference extends SortedListPreference {
@@ -14,10 +16,14 @@ public class SpoofAudioSelectorListPreference extends SortedListPreference {
private final boolean available;
{
- if (SpoofVideoStreamsPatch.getLanguageOverride() != null) {
+ final boolean isAndroidStudio = Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.ANDROID_CREATOR;
+
+ if (isAndroidStudio || SpoofVideoStreamsPatch.getLanguageOverride() != null) {
available = false;
super.setEnabled(false);
- super.setSummary(str("revanced_spoof_video_streams_language_not_available"));
+ super.setSummary(str(isAndroidStudio
+ ? "revanced_spoof_video_streams_language_android_studio"
+ : "revanced_spoof_video_streams_language_not_available"));
} else {
available = true;
}
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofStreamingDataSideEffectsPreference.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofStreamingDataSideEffectsPreference.java
index ae84c9dc2..ddc4d23da 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofStreamingDataSideEffectsPreference.java
+++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/SpoofStreamingDataSideEffectsPreference.java
@@ -95,6 +95,7 @@ public class SpoofStreamingDataSideEffectsPreference extends Preference {
+ '\n' + str("revanced_spoof_video_streams_about_kids_videos");
} else if (clientType == ClientType.ANDROID_CREATOR) {
summary += '\n' + str("revanced_spoof_video_streams_about_no_av1")
+ + '\n' + str("revanced_spoof_video_streams_about_no_force_original_audio")
+ '\n' + str("revanced_spoof_video_streams_about_kids_videos");
}
diff --git a/gradle.properties b/gradle.properties
index c1e74974b..53e5677b3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M
org.gradle.parallel = true
android.useAndroidX = true
kotlin.code.style = official
-version = 5.39.0
+version = 5.40.0-dev.11
diff --git a/patches/api/patches.api b/patches/api/patches.api
index 00b58e88e..aeaab90db 100644
--- a/patches/api/patches.api
+++ b/patches/api/patches.api
@@ -264,6 +264,10 @@ public final class app/revanced/patches/instagram/ads/HideAdsPatchKt {
public static final fun getHideAdsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
+public final class app/revanced/patches/instagram/feed/LimitFeedToFollowedProfilesKt {
+ public static final fun getLimitFeedToFollowedProfiles ()Lapp/revanced/patcher/patch/BytecodePatch;
+}
+
public final class app/revanced/patches/instagram/hide/explore/HideExploreFeedKt {
public static final fun getHideExportFeedPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@@ -276,6 +280,10 @@ public final class app/revanced/patches/instagram/hide/stories/HideStoriesKt {
public static final fun getHideStoriesPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
+public final class app/revanced/patches/instagram/misc/extension/SharedExtensionPatchKt {
+ public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
+}
+
public final class app/revanced/patches/instagram/misc/signature/SignatureCheckPatchKt {
public static final fun getSignatureCheckPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@@ -364,10 +372,18 @@ public final class app/revanced/patches/music/interaction/permanentshuffle/Perma
public static final fun getPermanentShufflePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
+public final class app/revanced/patches/music/layout/castbutton/HideCastButtonKt {
+ public static final fun getHideCastButton ()Lapp/revanced/patcher/patch/BytecodePatch;
+}
+
public final class app/revanced/patches/music/layout/compactheader/HideCategoryBarKt {
public static final fun getHideCategoryBar ()Lapp/revanced/patcher/patch/BytecodePatch;
}
+public final class app/revanced/patches/music/layout/navigationbar/NavigationBarPatchKt {
+ public static final fun getNavigationBarPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
+}
+
public final class app/revanced/patches/music/layout/premium/HideGetPremiumPatchKt {
public static final fun getHideGetPremiumPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@@ -385,6 +401,10 @@ public final class app/revanced/patches/music/misc/backgroundplayback/Background
public static final fun getBackgroundPlaybackPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
+public final class app/revanced/patches/music/misc/debugging/EnableDebuggingPatchKt {
+ public static final fun getEnableDebuggingPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
+}
+
public final class app/revanced/patches/music/misc/extension/SharedExtensionPatchKt {
public static final fun getSharedExtensionPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/feed/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/feed/Fingerprints.kt
new file mode 100644
index 000000000..cf8c61118
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/feed/Fingerprints.kt
@@ -0,0 +1,20 @@
+package app.revanced.patches.instagram.feed
+
+import app.revanced.patcher.fingerprint
+import app.revanced.patcher.patch.BytecodePatchContext
+
+internal val mainFeedRequestClassFingerprint = fingerprint {
+ strings("Request{mReason=", ", mInstanceNumber=")
+}
+
+context(BytecodePatchContext)
+internal val initMainFeedRequestFingerprint get() = fingerprint {
+ custom { method, classDef ->
+ method.name == "" &&
+ classDef == mainFeedRequestClassFingerprint.classDef
+ }
+}
+
+internal val mainFeedHeaderMapFinderFingerprint = fingerprint {
+ strings("pagination_source", "FEED_REQUEST_SENT")
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/feed/LimitFeedToFollowedProfiles.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/feed/LimitFeedToFollowedProfiles.kt
new file mode 100644
index 000000000..e7af0466c
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/feed/LimitFeedToFollowedProfiles.kt
@@ -0,0 +1,64 @@
+package app.revanced.patches.instagram.feed
+
+import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
+import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
+import app.revanced.patcher.patch.bytecodePatch
+import app.revanced.patches.instagram.misc.extension.sharedExtensionPatch
+import app.revanced.util.getReference
+import app.revanced.util.indexOfFirstInstructionOrThrow
+import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
+import com.android.tools.smali.dexlib2.iface.reference.FieldReference
+
+internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/instagram/feed/LimitFeedToFollowedProfiles;"
+
+@Suppress("unused")
+val limitFeedToFollowedProfiles = bytecodePatch(
+ name = "Limit feed to followed profiles",
+ description = "Filters the home feed to display only content from profiles you follow.",
+ use = false
+) {
+ compatibleWith("com.instagram.android")
+
+ dependsOn(sharedExtensionPatch)
+
+ execute {
+ /**
+ * Since the header field is obfuscated and there is no easy way to identify it among all the class fields,
+ * an additional method is fingerprinted.
+ * This method uses the map, so we can get the field name of the map field using this.
+ */
+ val mainFeedRequestHeaderFieldName: String
+
+ with(mainFeedHeaderMapFinderFingerprint.method) {
+ mainFeedRequestHeaderFieldName = indexOfFirstInstructionOrThrow {
+ getReference().let { ref ->
+ ref?.type == "Ljava/util/Map;" &&
+ ref.definingClass == mainFeedRequestClassFingerprint.classDef.toString()
+
+ }
+ }.let { instructionIndex ->
+ getInstruction(instructionIndex).getReference()!!.name
+ }
+ }
+
+ initMainFeedRequestFingerprint.method.apply {
+ // Finds the instruction where the map is being initialized in the constructor
+ val getHeaderIndex = indexOfFirstInstructionOrThrow {
+ getReference().let {
+ it?.name == mainFeedRequestHeaderFieldName
+ }
+ }
+
+ val paramHeaderRegister = getInstruction(getHeaderIndex).registerA
+
+ // Replace the `pagination_source` header value with `following` in the feed/timeline request.
+ addInstructions(
+ getHeaderIndex,
+ """
+ invoke-static { v$paramHeaderRegister }, $EXTENSION_CLASS_DESCRIPTOR->setFollowingHeader(Ljava/util/Map;)Ljava/util/Map;
+ move-result-object v$paramHeaderRegister
+ """
+ )
+ }
+ }
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt
index ee68c4fe1..cac9c35c3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/hide/navigation/HideNavigationButtons.kt
@@ -49,7 +49,7 @@ val hideNavigationButtonsPatch = bytecodePatch(
val freeRegister = findFreeRegister(insertIndex, loopIndexRegister)
val instruction = getInstruction(endIndex - 1)
- var instructions = buildString {
+ val instructions = buildString {
if (hideCreate!!) {
appendLine(
"""
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/extension/SharedExtensionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/extension/SharedExtensionPatch.kt
new file mode 100644
index 000000000..351b641a4
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/extension/SharedExtensionPatch.kt
@@ -0,0 +1,9 @@
+package app.revanced.patches.instagram.misc.extension
+
+import app.revanced.patches.instagram.misc.extension.hooks.applicationInitHook
+import app.revanced.patches.shared.misc.extension.sharedExtensionPatch
+
+val sharedExtensionPatch = sharedExtensionPatch(
+ "instagram",
+ applicationInitHook,
+)
diff --git a/patches/src/main/kotlin/app/revanced/patches/instagram/misc/extension/hooks/ApplicationInitHook.kt b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/extension/hooks/ApplicationInitHook.kt
new file mode 100644
index 000000000..eca0a885f
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/instagram/misc/extension/hooks/ApplicationInitHook.kt
@@ -0,0 +1,9 @@
+package app.revanced.patches.instagram.misc.extension.hooks
+
+import app.revanced.patches.shared.misc.extension.extensionHook
+
+internal val applicationInitHook = extensionHook {
+ custom { method, classDef ->
+ method.name == "onCreate" && classDef.endsWith("/InstagramAppShell;")
+ }
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt
index fd417bb5d..cd5150c16 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/ad/video/HideVideoAds.kt
@@ -24,7 +24,8 @@ val hideVideoAdsPatch = bytecodePatch(
compatibleWith(
"com.google.android.apps.youtube.music"(
- "7.29.52"
+ "7.29.52",
+ "8.10.52"
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt b/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt
index 4d598e402..f0b1974c3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/audio/exclusiveaudio/EnableExclusiveAudioPlayback.kt
@@ -17,7 +17,8 @@ val enableExclusiveAudioPlaybackPatch = bytecodePatch(
compatibleWith(
"com.google.android.apps.youtube.music"(
- "7.29.52"
+ "7.29.52",
+ "8.10.52"
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt
index 559bacc39..addf737f8 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentrepeat/PermanentRepeatPatch.kt
@@ -27,7 +27,8 @@ val permanentRepeatPatch = bytecodePatch(
compatibleWith(
"com.google.android.apps.youtube.music"(
- "7.29.52"
+ "7.29.52",
+ "8.10.52"
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt
index 39ffa319a..359ede662 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/interaction/permanentshuffle/PermanentShufflePatch.kt
@@ -11,7 +11,8 @@ val permanentShufflePatch = bytecodePatch(
) {
compatibleWith(
"com.google.android.apps.youtube.music"(
- "7.29.52"
+ "7.29.52",
+ "8.10.52"
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/castbutton/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/castbutton/Fingerprints.kt
new file mode 100644
index 000000000..718d49479
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/castbutton/Fingerprints.kt
@@ -0,0 +1,17 @@
+package app.revanced.patches.music.layout.castbutton
+
+import com.android.tools.smali.dexlib2.AccessFlags
+import app.revanced.patcher.fingerprint
+import app.revanced.util.literal
+
+internal val mediaRouteButtonFingerprint = fingerprint {
+ accessFlags(AccessFlags.PRIVATE, AccessFlags.FINAL)
+ returns("Z")
+ strings("MediaRouteButton")
+}
+
+internal val playerOverlayChipFingerprint = fingerprint {
+ accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
+ returns("L")
+ literal { playerOverlayChip }
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/castbutton/HideCastButton.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/castbutton/HideCastButton.kt
new file mode 100644
index 000000000..2c1fbdea8
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/castbutton/HideCastButton.kt
@@ -0,0 +1,71 @@
+package app.revanced.patches.music.layout.castbutton
+
+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.patch.bytecodePatch
+import app.revanced.patches.all.misc.resources.addResources
+import app.revanced.patches.all.misc.resources.addResourcesPatch
+import app.revanced.patches.music.misc.extension.sharedExtensionPatch
+import app.revanced.patches.music.misc.settings.PreferenceScreen
+import app.revanced.patches.music.misc.settings.settingsPatch
+import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
+import app.revanced.util.indexOfFirstInstructionOrThrow
+import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
+import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
+
+internal var playerOverlayChip = -1L
+ private set
+
+private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/HideCastButtonPatch;"
+
+@Suppress("unused")
+val hideCastButton = bytecodePatch(
+ name = "Hide cast button",
+ description = "Adds an option to hide the cast button."
+) {
+ dependsOn(
+ sharedExtensionPatch,
+ settingsPatch,
+ addResourcesPatch,
+ )
+
+ compatibleWith(
+ "com.google.android.apps.youtube.music"(
+ "7.29.52",
+ "8.10.52"
+ )
+ )
+
+ execute {
+ addResources("music", "layout.castbutton.hideCastButton")
+
+ PreferenceScreen.GENERAL.addPreferences(
+ SwitchPreference("revanced_music_hide_cast_button"),
+ )
+
+ mediaRouteButtonFingerprint.classDef.apply {
+ val setVisibilityMethod = methods.first { method -> method.name == "setVisibility" }
+
+ setVisibilityMethod.addInstructions(
+ 0,
+ """
+ invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->hideCastButton(I)I
+ move-result p1
+ """
+ )
+ }
+
+ playerOverlayChipFingerprint.method.apply {
+ val resourceIndex = indexOfFirstLiteralInstructionOrThrow(playerOverlayChip)
+ val targetIndex = indexOfFirstInstructionOrThrow(resourceIndex, Opcode.MOVE_RESULT)
+ val targetRegister = getInstruction(targetIndex).registerA
+
+ addInstruction(
+ targetIndex + 1,
+ "invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->hideCastButton(Landroid/view/View;)V"
+ )
+ }
+ }
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt
index 883be02a6..7668c9dc7 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/compactheader/HideCategoryBar.kt
@@ -1,6 +1,5 @@
package app.revanced.patches.music.layout.compactheader
-import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.patch.bytecodePatch
@@ -10,7 +9,6 @@ import app.revanced.patches.music.misc.extension.sharedExtensionPatch
import app.revanced.patches.music.misc.settings.PreferenceScreen
import app.revanced.patches.music.misc.settings.settingsPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
-import app.revanced.util.addInstructionsAtControlFlowLabel
import app.revanced.util.findFreeRegister
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@@ -29,7 +27,8 @@ val hideCategoryBar = bytecodePatch(
compatibleWith(
"com.google.android.apps.youtube.music"(
- "7.29.52"
+ "7.29.52",
+ "8.10.52"
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/Fingerprints.kt
new file mode 100644
index 000000000..df5dbe68d
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/Fingerprints.kt
@@ -0,0 +1,36 @@
+package app.revanced.patches.music.layout.navigationbar
+
+import app.revanced.patcher.fingerprint
+import app.revanced.util.containsLiteralInstruction
+import app.revanced.util.getReference
+import app.revanced.util.indexOfFirstInstruction
+import com.android.tools.smali.dexlib2.AccessFlags
+import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.Method
+import com.android.tools.smali.dexlib2.iface.reference.MethodReference
+
+internal val tabLayoutTextFingerprint = fingerprint {
+ accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
+ returns("V")
+ parameters("L")
+ opcodes(
+ Opcode.IGET,
+ Opcode.INVOKE_STATIC,
+ Opcode.MOVE_RESULT_OBJECT,
+ Opcode.IF_NEZ,
+ Opcode.SGET_OBJECT,
+ Opcode.INVOKE_INTERFACE,
+ Opcode.MOVE_RESULT
+ )
+ strings("FEmusic_search")
+ custom { method, _ ->
+ method.containsLiteralInstruction(text1)
+ && indexOfGetVisibilityInstruction(method) >= 0
+ }
+}
+
+internal fun indexOfGetVisibilityInstruction(method: Method) =
+ method.indexOfFirstInstruction {
+ opcode == Opcode.INVOKE_VIRTUAL &&
+ getReference()?.name == "getVisibility"
+ }
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/NavigationBarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/NavigationBarPatch.kt
new file mode 100644
index 000000000..e9598f576
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/navigationbar/NavigationBarPatch.kt
@@ -0,0 +1,111 @@
+package app.revanced.patches.music.layout.navigationbar
+
+import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
+import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
+import app.revanced.patcher.patch.PatchException
+import app.revanced.patcher.patch.bytecodePatch
+import app.revanced.patches.all.misc.resources.addResources
+import app.revanced.patches.all.misc.resources.addResourcesPatch
+import app.revanced.patches.music.misc.extension.sharedExtensionPatch
+import app.revanced.patches.music.misc.settings.PreferenceScreen
+import app.revanced.patches.music.misc.settings.settingsPatch
+import app.revanced.patches.shared.misc.mapping.get
+import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
+import app.revanced.patches.shared.misc.mapping.resourceMappings
+import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
+import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
+import app.revanced.util.indexOfFirstInstructionOrThrow
+import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
+import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
+import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
+import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
+
+internal var text1 = -1L
+ private set
+
+private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/NavigationBarPatch;"
+
+@Suppress("unused")
+val navigationBarPatch = bytecodePatch(
+ name = "Navigation bar",
+ description = "Adds options to hide navigation bar, labels and buttons."
+) {
+ dependsOn(
+ resourceMappingPatch,
+ sharedExtensionPatch,
+ settingsPatch,
+ addResourcesPatch
+ )
+
+ compatibleWith(
+ "com.google.android.apps.youtube.music"(
+ "7.29.52",
+ "8.10.52"
+ )
+ )
+
+ execute {
+ text1 = resourceMappings[
+ "id",
+ "text1",
+ ]
+
+ addResources("music", "layout.navigationbar.navigationBarPatch")
+
+ PreferenceScreen.GENERAL.addPreferences(
+ PreferenceScreenPreference(
+ key = "revanced_music_navigation_bar_screen",
+ sorting = PreferenceScreenPreference.Sorting.UNSORTED,
+ preferences = setOf(
+ SwitchPreference("revanced_music_hide_navigation_bar_home_button"),
+ SwitchPreference("revanced_music_hide_navigation_bar_samples_button"),
+ SwitchPreference("revanced_music_hide_navigation_bar_explore_button"),
+ SwitchPreference("revanced_music_hide_navigation_bar_library_button"),
+ SwitchPreference("revanced_music_hide_navigation_bar_upgrade_button"),
+
+ SwitchPreference("revanced_music_hide_navigation_bar"),
+ SwitchPreference("revanced_music_hide_navigation_bar_labels"),
+ )
+ )
+ )
+
+ tabLayoutTextFingerprint.method.apply {
+ /**
+ * Hide navigation labels.
+ */
+ val constIndex = indexOfFirstLiteralInstructionOrThrow(text1)
+ val targetIndex = indexOfFirstInstructionOrThrow(constIndex, Opcode.CHECK_CAST)
+ val targetParameter = getInstruction(targetIndex).reference
+ val targetRegister = getInstruction(targetIndex).registerA
+
+ if (!targetParameter.toString().endsWith("Landroid/widget/TextView;"))
+ throw PatchException("Method signature parameter did not match: $targetParameter")
+
+ addInstruction(
+ targetIndex + 1,
+ "invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationLabel(Landroid/widget/TextView;)V"
+ )
+
+ /**
+ * Set navigation enum and hide navigation buttons.
+ */
+ val enumIndex = tabLayoutTextFingerprint.patternMatch!!.startIndex + 3
+ val enumRegister = getInstruction(enumIndex).registerA
+ val insertEnumIndex = indexOfFirstInstructionOrThrow(Opcode.AND_INT_LIT8) - 2
+
+ val pivotTabIndex = indexOfGetVisibilityInstruction(this)
+ val pivotTabRegister = getInstruction(pivotTabIndex).registerC
+
+ addInstruction(
+ pivotTabIndex,
+ "invoke-static { v$pivotTabRegister }, $EXTENSION_CLASS_DESCRIPTOR->hideNavigationButton(Landroid/view/View;)V"
+ )
+
+ addInstruction(
+ insertEnumIndex,
+ "invoke-static { v$enumRegister }, $EXTENSION_CLASS_DESCRIPTOR->setLastAppNavigationEnum(Ljava/lang/Enum;)V"
+ )
+ }
+ }
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt
index beea72673..13a50c54f 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/premium/HideGetPremiumPatch.kt
@@ -28,7 +28,8 @@ val hideGetPremiumPatch = bytecodePatch(
compatibleWith(
"com.google.android.apps.youtube.music"(
- "7.29.52"
+ "7.29.52",
+ "8.10.52"
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/Fingerprints.kt
deleted file mode 100644
index f3c96dc44..000000000
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/Fingerprints.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package app.revanced.patches.music.layout.upgradebutton
-
-import com.android.tools.smali.dexlib2.Opcode
-import com.android.tools.smali.dexlib2.AccessFlags
-import app.revanced.patcher.fingerprint
-
-internal val pivotBarConstructorFingerprint = fingerprint {
- accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
- returns("V")
- parameters("L", "Z")
- opcodes(
- Opcode.CHECK_CAST,
- Opcode.INVOKE_INTERFACE,
- Opcode.GOTO,
- Opcode.IPUT_OBJECT,
- Opcode.RETURN_VOID
- )
-}
\ No newline at end of file
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/HideUpgradeButtonPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/HideUpgradeButtonPatch.kt
index b54e4f2b6..0b0f24497 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/HideUpgradeButtonPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/upgradebutton/HideUpgradeButtonPatch.kt
@@ -1,104 +1,12 @@
package app.revanced.patches.music.layout.upgradebutton
-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.replaceInstruction
-import app.revanced.patcher.extensions.newLabel
import app.revanced.patcher.patch.bytecodePatch
-import app.revanced.patcher.util.smali.toInstructions
-import app.revanced.patches.all.misc.resources.addResources
-import app.revanced.patches.all.misc.resources.addResourcesPatch
-import app.revanced.patches.music.misc.extension.sharedExtensionPatch
-import app.revanced.patches.music.misc.settings.PreferenceScreen
-import app.revanced.patches.music.misc.settings.settingsPatch
-import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
-import app.revanced.util.getReference
-import com.android.tools.smali.dexlib2.Opcode
-import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction22t
-import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
-import com.android.tools.smali.dexlib2.iface.reference.FieldReference
-
-private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/music/patches/HideUpgradeButtonPatch;"
+import app.revanced.patches.music.layout.navigationbar.navigationBarPatch
+@Deprecated("Patch is obsolete and was replaced by navigation bar patch", ReplaceWith("navigationBarPatch"))
@Suppress("unused")
-val hideUpgradeButton = bytecodePatch(
- name = "Hide upgrade button",
- description = "Hides the upgrade tab from the pivot bar.",
-) {
- dependsOn(
- sharedExtensionPatch,
- settingsPatch,
- addResourcesPatch,
- )
-
- compatibleWith(
- "com.google.android.apps.youtube.music"(
- "7.29.52"
- )
- )
-
- execute {
- addResources("music", "layout.upgradebutton.hideUpgradeButtonPatch")
-
- // TODO: Add an extension patch to allow this to be enabled/disabled in app.
- if (false) {
- PreferenceScreen.ADS.addPreferences(
- SwitchPreference("revanced_music_hide_upgrade_button")
- )
- }
-
- pivotBarConstructorFingerprint.method.apply {
- val pivotBarElementFieldReference =
- getInstruction(pivotBarConstructorFingerprint.patternMatch!!.endIndex - 1)
- .getReference()
-
- val register = getInstruction(0).registerC
-
- // First compile all the needed instructions.
- val instructionList = """
- invoke-interface { v0 }, Ljava/util/List;->size()I
- move-result v1
- const/4 v2, 0x4
- invoke-interface {v0, v2}, Ljava/util/List;->remove(I)Ljava/lang/Object;
- iput-object v0, v$register, $pivotBarElementFieldReference
- """.toInstructions().toMutableList()
-
- val endIndex = pivotBarConstructorFingerprint.patternMatch!!.endIndex
-
- // Replace the instruction to retain the label at given index.
- replaceInstruction(
- endIndex - 1,
- instructionList[0], // invoke-interface.
- )
- // Do not forget to remove this instruction since we added it already.
- instructionList.removeFirst()
-
- val exitInstruction = instructionList.last() // iput-object
- addInstruction(
- endIndex,
- exitInstruction,
- )
- // Do not forget to remove this instruction since we added it already.
- instructionList.removeLast()
-
- // Add the necessary if statement to remove the upgrade tab button in case it exists.
- instructionList.add(
- 2, // if-le.
- BuilderInstruction22t(
- Opcode.IF_LE,
- 1,
- 2,
- newLabel(endIndex),
- ),
- )
-
- addInstructions(
- endIndex,
- instructionList,
- )
- }
- }
+val hideUpgradeButton = bytecodePatch{
+ dependsOn(navigationBarPatch)
}
@Deprecated("Patch was renamed", ReplaceWith("hideUpgradeButton"))
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/BypassCertificateChecksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/BypassCertificateChecksPatch.kt
index 70e707fbb..245569d9e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/BypassCertificateChecksPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/androidauto/BypassCertificateChecksPatch.kt
@@ -17,7 +17,8 @@ val bypassCertificateChecksPatch = bytecodePatch(
compatibleWith(
"com.google.android.apps.youtube.music"(
- "7.29.52"
+ "7.29.52",
+ "8.10.52"
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt
index 3d81296a7..bf35b24d5 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/backgroundplayback/BackgroundPlaybackPatch.kt
@@ -17,7 +17,8 @@ val backgroundPlaybackPatch = bytecodePatch(
compatibleWith(
"com.google.android.apps.youtube.music"(
- "7.29.52"
+ "7.29.52",
+ "8.10.52"
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/debugging/EnableDebuggingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/debugging/EnableDebuggingPatch.kt
new file mode 100644
index 000000000..76ee0e060
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/debugging/EnableDebuggingPatch.kt
@@ -0,0 +1,26 @@
+package app.revanced.patches.music.misc.debugging
+
+import app.revanced.patches.music.misc.extension.sharedExtensionPatch
+import app.revanced.patches.music.misc.settings.PreferenceScreen
+import app.revanced.patches.music.misc.settings.settingsPatch
+import app.revanced.patches.shared.misc.debugging.enableDebuggingPatch
+
+@Suppress("unused")
+val enableDebuggingPatch = enableDebuggingPatch(
+ block = {
+ dependsOn(
+ sharedExtensionPatch,
+ settingsPatch,
+ )
+
+ compatibleWith(
+ "com.google.android.apps.youtube.music"(
+ "7.29.52",
+ "8.10.52"
+ )
+ )
+ },
+ // String feature flag does not appear to be present with YT Music.
+ hookStringFeatureFlag = false,
+ preferenceScreen = PreferenceScreen.MISC
+)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt
index 09fab446b..5d282b715 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/settings/SettingsPatch.kt
@@ -8,12 +8,16 @@ import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
import app.revanced.patches.shared.misc.mapping.resourceMappingPatch
-import app.revanced.patches.shared.misc.settings.preference.*
+import app.revanced.patches.shared.misc.settings.preference.BasePreference
+import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
+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.PreferenceScreenPreference
-import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
-import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.shared.misc.settings.settingsPatch
-import app.revanced.util.*
+import app.revanced.util.ResourceGroup
+import app.revanced.util.copyResources
+import app.revanced.util.copyXmlNode
+import app.revanced.util.inputStreamFromBundledResource
import com.android.tools.smali.dexlib2.util.MethodUtil
private const val BASE_ACTIVITY_HOOK_CLASS_DESCRIPTOR =
@@ -23,7 +27,6 @@ private const val GOOGLE_API_ACTIVITY_HOOK_CLASS_DESCRIPTOR =
private val preferences = mutableSetOf()
-
private val settingsResourcePatch = resourcePatch {
dependsOn(
resourceMappingPatch,
@@ -87,27 +90,6 @@ val settingsPatch = bytecodePatch(
addResources("music", "misc.settings.settingsPatch")
addResources("shared", "misc.debugging.enableDebuggingPatch")
- // Should make a separate debugging patch, but for now include it with all installations.
- PreferenceScreen.MISC.addPreferences(
- PreferenceScreenPreference(
- key = "revanced_debug_screen",
- sorting = Sorting.UNSORTED,
- preferences = setOf(
- SwitchPreference("revanced_debug"),
- NonInteractivePreference(
- "revanced_debug_export_logs_to_clipboard",
- tag = "app.revanced.extension.shared.settings.preference.ExportLogToClipboardPreference",
- selectable = true
- ),
- NonInteractivePreference(
- "revanced_debug_logs_clear_buffer",
- tag = "app.revanced.extension.shared.settings.preference.ClearLogBufferPreference",
- selectable = true
- )
- )
- )
- )
-
// Add an "About" preference to the top.
preferences += NonInteractivePreference(
key = "revanced_settings_music_screen_0_about",
@@ -154,19 +136,19 @@ fun newIntent(settingsName: String) = IntentPreference.Intent(
object PreferenceScreen : BasePreferenceScreen() {
val ADS = Screen(
- "revanced_settings_music_screen_1_ads",
+ key = "revanced_settings_music_screen_1_ads",
summaryKey = null
)
val GENERAL = Screen(
- "revanced_settings_music_screen_2_general",
+ key = "revanced_settings_music_screen_2_general",
summaryKey = null
)
val PLAYER = Screen(
- "revanced_settings_music_screen_3_player",
+ key = "revanced_settings_music_screen_3_player",
summaryKey = null
)
val MISC = Screen(
- "revanced_settings_music_screen_4_misc",
+ key = "revanced_settings_music_screen_4_misc",
summaryKey = null
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt
index 0452bc3cf..b01f74cca 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt
@@ -33,7 +33,8 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch(
compatibleWith(
"com.google.android.apps.youtube.music"(
- "7.29.52"
+ "7.29.52",
+ "8.10.52"
)
)
},
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/EnableDebuggingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/EnableDebuggingPatch.kt
new file mode 100644
index 000000000..85cf53bd0
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/EnableDebuggingPatch.kt
@@ -0,0 +1,147 @@
+package app.revanced.patches.shared.misc.debugging
+
+import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
+import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
+import app.revanced.patcher.patch.BytecodePatchBuilder
+import app.revanced.patcher.patch.BytecodePatchContext
+import app.revanced.patcher.patch.bytecodePatch
+import app.revanced.patches.all.misc.resources.addResources
+import app.revanced.patches.all.misc.resources.addResourcesPatch
+import app.revanced.patches.shared.misc.settings.preference.BasePreference
+import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
+import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
+import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
+import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
+import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
+import app.revanced.util.findInstructionIndicesReversedOrThrow
+import app.revanced.util.indexOfFirstInstructionOrThrow
+import app.revanced.util.indexOfFirstInstructionReversedOrThrow
+import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
+
+private const val EXTENSION_CLASS_DESCRIPTOR =
+ "Lapp/revanced/extension/shared/patches/EnableDebuggingPatch;"
+
+/**
+ * Patch shared with YouTube and YT Music.
+ */
+internal fun enableDebuggingPatch(
+ block: BytecodePatchBuilder.() -> Unit = {},
+ executeBlock: BytecodePatchContext.() -> Unit = {},
+ hookStringFeatureFlag: Boolean,
+ preferenceScreen: BasePreferenceScreen.Screen,
+ additionalDebugPreferences: List = emptyList()
+) = bytecodePatch(
+ name = "Enable debugging",
+ description = "Adds options for debugging and exporting ReVanced logs to the clipboard.",
+) {
+
+ dependsOn(addResourcesPatch)
+
+ block()
+
+ execute {
+ executeBlock()
+
+ addResources("shared", "misc.debugging.enableDebuggingPatch")
+
+ val preferences = mutableSetOf(
+ SwitchPreference("revanced_debug"),
+ )
+
+ preferences.addAll(additionalDebugPreferences)
+
+ preferences.addAll(
+ listOf(
+ SwitchPreference("revanced_debug_stacktrace"),
+ SwitchPreference("revanced_debug_toast_on_error"),
+ NonInteractivePreference(
+ "revanced_debug_export_logs_to_clipboard",
+ tag = "app.revanced.extension.shared.settings.preference.ExportLogToClipboardPreference",
+ selectable = true
+ ),
+ NonInteractivePreference(
+ "revanced_debug_logs_clear_buffer",
+ tag = "app.revanced.extension.shared.settings.preference.ClearLogBufferPreference",
+ selectable = true
+ )
+ )
+ )
+
+ preferenceScreen.addPreferences(
+ PreferenceScreenPreference(
+ key = "revanced_debug_screen",
+ sorting = Sorting.UNSORTED,
+ preferences = preferences,
+ )
+ )
+
+ // Hook the methods that look up if a feature flag is active.
+ experimentalBooleanFeatureFlagFingerprint.match(
+ experimentalFeatureFlagParentFingerprint.originalClassDef
+ ).method.apply {
+ findInstructionIndicesReversedOrThrow(Opcode.RETURN).forEach { index ->
+ val register = getInstruction(index).registerA
+
+ addInstructions(
+ index,
+ """
+ invoke-static { v$register, p1 }, $EXTENSION_CLASS_DESCRIPTOR->isBooleanFeatureFlagEnabled(ZLjava/lang/Long;)Z
+ move-result v$register
+ """
+ )
+ }
+ }
+
+ experimentalDoubleFeatureFlagFingerprint.match(
+ experimentalFeatureFlagParentFingerprint.originalClassDef
+ ).method.apply {
+ val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
+
+ addInstructions(
+ insertIndex,
+ """
+ move-result-wide v0 # Also clobbers v1 (p0) since result is wide.
+ invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isDoubleFeatureFlagEnabled(DJD)D
+ move-result-wide v0
+ return-wide v0
+ """
+ )
+ }
+
+ experimentalLongFeatureFlagFingerprint.match(
+ experimentalFeatureFlagParentFingerprint.originalClassDef
+ ).method.apply {
+ val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
+
+ addInstructions(
+ insertIndex,
+ """
+ move-result-wide v0
+ invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isLongFeatureFlagEnabled(JJJ)J
+ move-result-wide v0
+ return-wide v0
+ """
+ )
+ }
+
+ if (hookStringFeatureFlag) experimentalStringFeatureFlagFingerprint.match(
+ experimentalFeatureFlagParentFingerprint.originalClassDef
+ ).method.apply {
+ val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT)
+
+ addInstructions(
+ insertIndex,
+ """
+ move-result-object v0
+ invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String;
+ move-result-object v0
+ return-object v0
+ """
+ )
+ }
+
+ // There exists other experimental accessor methods for byte[]
+ // and wrappers for obfuscated classes, but currently none of those are hooked.
+ }
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/Fingerprints.kt
new file mode 100644
index 000000000..6f183dd08
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/debugging/Fingerprints.kt
@@ -0,0 +1,35 @@
+package app.revanced.patches.shared.misc.debugging
+
+import app.revanced.patcher.fingerprint
+import com.android.tools.smali.dexlib2.AccessFlags
+
+internal val experimentalFeatureFlagParentFingerprint = fingerprint {
+ accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
+ returns("L")
+ parameters("L", "J", "[B")
+ strings("Unable to parse proto typed experiment flag: ")
+}
+
+internal val experimentalBooleanFeatureFlagFingerprint = fingerprint {
+ accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
+ returns("Z")
+ parameters("L", "J", "Z")
+}
+
+internal val experimentalDoubleFeatureFlagFingerprint = fingerprint {
+ accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
+ returns("D")
+ parameters("J", "D")
+}
+
+internal val experimentalLongFeatureFlagFingerprint = fingerprint {
+ accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
+ returns("J")
+ parameters("J", "J")
+}
+
+internal val experimentalStringFeatureFlagFingerprint = fingerprint {
+ accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
+ returns("Ljava/lang/String;")
+ parameters("J", "Ljava/lang/String;")
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt
index 67ba7c80c..5ea7a0b71 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt
@@ -6,6 +6,7 @@ import app.revanced.util.indexOfFirstInstruction
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal val buildInitPlaybackRequestFingerprint = fingerprint {
@@ -40,13 +41,6 @@ internal val buildRequestFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Lorg/chromium/net/UrlRequest") // UrlRequest; or UrlRequest$Builder;
custom { methodDef, _ ->
- if (methodDef.indexOfFirstInstruction {
- val reference = getReference()
- reference?.name == "newUrlRequestBuilder"
- } < 0) {
- return@custom false
- }
-
// Different targets have slightly different parameters
// Earlier targets have parameters:
@@ -80,10 +74,10 @@ internal val buildRequestFingerprint = fingerprint {
val parameterTypesSize = parameterTypes.size
(parameterTypesSize == 6 || parameterTypesSize == 7 || parameterTypesSize == 8) &&
parameterTypes[1] == "Ljava/util/Map;" // URL headers.
+ && indexOfNewUrlRequestBuilderInstruction(methodDef) >= 0
}
}
-
internal val protobufClassParseByteBufferFingerprint = fingerprint {
accessFlags(AccessFlags.PROTECTED, AccessFlags.STATIC)
returns("L")
@@ -142,6 +136,17 @@ internal val hlsCurrentTimeFingerprint = fingerprint {
}
}
+internal const val DISABLED_BY_SABR_STREAMING_URI_STRING = "DISABLED_BY_SABR_STREAMING_URI"
+
+internal val mediaFetchEnumConstructorFingerprint = fingerprint {
+ returns("V")
+ strings(
+ "ENABLED",
+ "DISABLED_FOR_PLAYBACK",
+ DISABLED_BY_SABR_STREAMING_URI_STRING
+ )
+}
+
internal val nerdsStatsVideoFormatBuilderFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Ljava/lang/String;")
@@ -150,7 +155,6 @@ internal val nerdsStatsVideoFormatBuilderFingerprint = fingerprint {
}
internal val patchIncludedExtensionMethodFingerprint = fingerprint {
- accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC)
returns("Z")
parameters()
custom { method, classDef ->
@@ -187,3 +191,13 @@ internal val playbackStartDescriptorFeatureFlagFingerprint = fingerprint {
returns("Z")
literal { PLAYBACK_START_CHECK_ENDPOINT_USED_FEATURE_FLAG }
}
+
+internal fun indexOfNewUrlRequestBuilderInstruction(method: Method) = method.indexOfFirstInstruction {
+ val reference = getReference()
+ opcode == Opcode.INVOKE_VIRTUAL && reference?.definingClass == "Lorg/chromium/net/CronetEngine;"
+ && reference.name == "newUrlRequestBuilder"
+ && reference.parameterTypes.size == 3
+ && reference.parameterTypes[0] == "Ljava/lang/String;"
+ && reference.parameterTypes[1] == "Lorg/chromium/net/UrlRequest\$Callback;"
+ && reference.parameterTypes[2] == "Ljava/util/concurrent/Executor;"
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt
index 26b80a2f9..c03e8022c 100644
--- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt
@@ -5,9 +5,11 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
import app.revanced.patcher.extensions.InstructionExtensions.instructions
+import app.revanced.patcher.fingerprint
import app.revanced.patcher.patch.BytecodePatchBuilder
import app.revanced.patcher.patch.BytecodePatchContext
import app.revanced.patcher.patch.bytecodePatch
+import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patches.all.misc.resources.addResources
import app.revanced.patches.all.misc.resources.addResourcesPatch
@@ -22,15 +24,18 @@ import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
+import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
-import com.android.tools.smali.dexlib2.iface.reference.MethodReference
import com.android.tools.smali.dexlib2.immutable.ImmutableMethod
import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter
internal const val EXTENSION_CLASS_DESCRIPTOR =
"Lapp/revanced/extension/shared/spoof/SpoofVideoStreamsPatch;"
+private lateinit var buildRequestMethod: MutableMethod
+private var buildRequestMethodUrlRegister = -1
+
fun spoofVideoStreamsPatch(
block: BytecodePatchBuilder.() -> Unit = {},
fixMediaFetchHotConfigChanges: BytecodePatchBuilder.() -> Boolean = { false },
@@ -91,18 +96,17 @@ fun spoofVideoStreamsPatch(
// region Get replacement streams at player requests.
buildRequestFingerprint.method.apply {
- val newRequestBuilderIndex = indexOfFirstInstructionOrThrow {
- opcode == Opcode.INVOKE_VIRTUAL &&
- getReference()?.name == "newUrlRequestBuilder"
- }
- val urlRegister = getInstruction(newRequestBuilderIndex).registerD
- val freeRegister = findFreeRegister(newRequestBuilderIndex, urlRegister)
+ buildRequestMethod = this
+
+ val newRequestBuilderIndex = indexOfNewUrlRequestBuilderInstruction(this)
+ buildRequestMethodUrlRegister = getInstruction(newRequestBuilderIndex).registerD
+ val freeRegister = findFreeRegister(newRequestBuilderIndex, buildRequestMethodUrlRegister)
addInstructions(
newRequestBuilderIndex,
"""
move-object v$freeRegister, p1
- invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
+ invoke-static { v$buildRequestMethodUrlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
"""
)
}
@@ -187,6 +191,21 @@ fun spoofVideoStreamsPatch(
// endregion
+ // region block getAtt request
+
+ buildRequestMethod.apply {
+ val insertIndex = indexOfNewUrlRequestBuilderInstruction(this)
+
+ addInstructions(
+ insertIndex, """
+ invoke-static { v$buildRequestMethodUrlRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetAttRequest(Ljava/lang/String;)Ljava/lang/String;
+ move-result-object v$buildRequestMethodUrlRegister
+ """
+ )
+ }
+
+ // endregion
+
// region Remove /videoplayback request body to fix playback.
// It is assumed, YouTube makes a request with a body tuned for Android.
// Requesting streams intended for other platforms with a body tuned for Android could be the cause of 400 errors.
@@ -243,6 +262,50 @@ fun spoofVideoStreamsPatch(
// endregion
+ // region Disable SABR playback.
+ // If SABR is disabled, it seems 'MediaFetchHotConfig' may no longer need an override (not confirmed).
+
+ val (mediaFetchEnumClass, sabrFieldReference) = with(mediaFetchEnumConstructorFingerprint.method) {
+ val stringIndex = mediaFetchEnumConstructorFingerprint.stringMatches!!.first {
+ it.string == DISABLED_BY_SABR_STREAMING_URI_STRING
+ }.index
+
+ val mediaFetchEnumClass = definingClass
+ val sabrFieldIndex = indexOfFirstInstructionOrThrow(stringIndex) {
+ opcode == Opcode.SPUT_OBJECT &&
+ getReference()?.type == mediaFetchEnumClass
+ }
+
+ Pair(
+ mediaFetchEnumClass,
+ getInstruction(sabrFieldIndex).reference
+ )
+ }
+
+ fingerprint {
+ returns(mediaFetchEnumClass)
+ opcodes(
+ Opcode.SGET_OBJECT,
+ Opcode.RETURN_OBJECT,
+ )
+ custom { method, _ ->
+ !method.parameterTypes.isEmpty()
+ }
+ }.method.addInstructionsWithLabels(
+ 0,
+ """
+ invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->disableSABR()Z
+ move-result v0
+ if-eqz v0, :ignore
+ sget-object v0, $sabrFieldReference
+ return-object v0
+ :ignore
+ nop
+ """
+ )
+
+ // endregion
+
// region turn off stream config replacement feature flag.
if (fixMediaFetchHotConfigChanges()) {
diff --git a/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt
index 11ebe0d11..29b752cf8 100644
--- a/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/viber/ads/Fingerprints.kt
@@ -2,12 +2,6 @@ package app.revanced.patches.viber.ads
import app.revanced.patcher.fingerprint
-internal val adsFreeFingerprint = fingerprint {
- returns("I")
- parameters()
- custom { method, classDef ->
- classDef.type.contains("com/viber/voip/feature/viberplus") &&
- classDef.superclass?.contains("com/viber/voip/core/feature") == true && // Must extend com.viber.voip.core.feature.?
- classDef.methods.count() == 1
- }
+internal val findAdStringFingerprint = fingerprint {
+ strings("viber_plus_debug_ads_free_flag")
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt
index 91bff02c6..0ec31e376 100644
--- a/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/viber/ads/HideAdsPatch.kt
@@ -1,17 +1,41 @@
package app.revanced.patches.viber.ads
+import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
+import app.revanced.patcher.fingerprint
+import app.revanced.patcher.patch.PatchException
import app.revanced.patcher.patch.bytecodePatch
+import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.returnEarly
+import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
+import com.android.tools.smali.dexlib2.iface.reference.TypeReference
@Suppress("unused")
val hideAdsPatch = bytecodePatch(
name = "Hide Ads",
description = "Hides ad banners between chats.",
) {
- compatibleWith("com.viber.voip"("25.9.2.0"))
+ compatibleWith("com.viber.voip"("25.9.2.0", "26.1.2.0"))
execute {
- // Return 1 (true) indicating ads should be disabled.
- adsFreeFingerprint.method.returnEarly(1)
+ val method = findAdStringFingerprint.method
+
+ // Find the ads free string index
+ val stringIndex = findAdStringFingerprint.stringMatches!!.first().index
+
+ // Search backwards from the string to find the `new-instance` (TypeReference) instruction
+ val typeRefIndex = method.indexOfFirstInstructionReversedOrThrow(stringIndex) { this.opcode == Opcode.NEW_INSTANCE }
+
+ // Get the class name from the TypeReference
+ val targetClass = method.getInstruction(typeRefIndex).reference as TypeReference
+
+ // Patch the ads-free method to always return true
+ fingerprint {
+ returns("I")
+ parameters()
+ custom { method, classDef ->
+ classDef == targetClass
+ }
+ }.method.returnEarly(1)
}
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt
index e1d326610..d2175db4c 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/general/HideAdsPatch.kt
@@ -78,10 +78,9 @@ val hideAdsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt
index bed7dba99..9e7095e30 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/getpremium/HideGetPremiumPatch.kt
@@ -27,10 +27,9 @@ val hideGetPremiumPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt
index 81d19d698..aad7f8cc3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/ad/video/VideoAdsPatch.kt
@@ -25,10 +25,9 @@ val videoAdsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlPatch.kt
index 047950331..5c46810fc 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/copyvideourl/CopyVideoUrlPatch.kt
@@ -55,10 +55,9 @@ val copyVideoUrlPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt
index 8c366e58b..6aaf0e3ad 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/dialog/RemoveViewerDiscretionDialogPatch.kt
@@ -26,10 +26,9 @@ val removeViewerDiscretionDialogPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/DisableChapterSkipDoubleTapPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/DisableChapterSkipDoubleTapPatch.kt
index 9672ef9a2..fbf153507 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/DisableChapterSkipDoubleTapPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/doubletap/DisableChapterSkipDoubleTapPatch.kt
@@ -29,8 +29,8 @@ val disableDoubleTapActionsPatch = bytecodePatch(
compatibleWith(
"com.google.android.youtube"(
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt
index ed2f7f043..b48148655 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/downloads/DownloadsPatch.kt
@@ -76,10 +76,9 @@ val downloadsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarPatch.kt
index fc2b9b998..e0fb2ea61 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/seekbar/SeekbarPatch.kt
@@ -22,10 +22,9 @@ val seekbarPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt
index dd83a9549..83a553aef 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/interaction/swipecontrols/SwipeControlsPatch.kt
@@ -90,10 +90,9 @@ val swipeControlsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt
index ff7ee248f..8a6e216dc 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/autocaptions/AutoCaptionsPatch.kt
@@ -26,10 +26,9 @@ val autoCaptionsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt
index 1eac1fb6c..816fa5de2 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt
@@ -45,10 +45,9 @@ val customBrandingPatch = resourcePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt
index cd2045550..a8d0b2d38 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt
@@ -95,10 +95,9 @@ val changeHeaderPatch = resourcePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt
index 0881c499a..1186188f7 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/action/HideButtonsPatch.kt
@@ -24,10 +24,9 @@ val hideButtonsPatch = resourcePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
@@ -41,6 +40,7 @@ val hideButtonsPatch = resourcePatch(
SwitchPreference("revanced_disable_like_subscribe_glow"),
SwitchPreference("revanced_hide_ask_button"),
SwitchPreference("revanced_hide_clip_button"),
+ SwitchPreference("revanced_hide_comments_button"),
SwitchPreference("revanced_hide_download_button"),
SwitchPreference("revanced_hide_hype_button"),
SwitchPreference("revanced_hide_like_dislike_button"),
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
index b59ec3f38..03210d5ee 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/navigation/NavigationButtonsPatch.kt
@@ -42,10 +42,9 @@ val navigationButtonsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt
index a890cf2be..c8bd12f4b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/buttons/overlay/HidePlayerOverlayButtonsPatch.kt
@@ -60,10 +60,9 @@ val hidePlayerOverlayButtonsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt
index 6e9672cf9..c6412ec66 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/formfactor/ChangeFormFactorPatch.kt
@@ -35,10 +35,9 @@ val changeFormFactorPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt
index 458801631..889c32462 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreencards/HideEndscreenCardsPatch.kt
@@ -61,10 +61,9 @@ val hideEndscreenCardsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/HideEndScreenSuggestedVideoPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/HideEndScreenSuggestedVideoPatch.kt
index db5115207..498051829 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/HideEndScreenSuggestedVideoPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/endscreensuggestion/HideEndScreenSuggestedVideoPatch.kt
@@ -33,10 +33,9 @@ val hideEndScreenSuggestedVideoPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt
index f2b87d5be..f75bd9cbd 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/fullscreenambientmode/DisableFullscreenAmbientModePatch.kt
@@ -31,10 +31,9 @@ val disableFullscreenAmbientModePatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
index 4c9bac27c..affb18b81 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/general/HideLayoutComponentsPatch.kt
@@ -128,10 +128,9 @@ val hideLayoutComponentsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt
index cac5c169b..a53af02af 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/infocards/HideInfoCardsPatch.kt
@@ -59,10 +59,9 @@ val hideInfoCardsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt
index b18525c4c..f8f32b8e8 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/player/flyoutmenupanel/HidePlayerFlyoutMenuPatch.kt
@@ -26,10 +26,9 @@ val hidePlayerFlyoutMenuPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/relatedvideooverlay/HideRelatedVideoOverlayPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/relatedvideooverlay/HideRelatedVideoOverlayPatch.kt
index fa8fa9f04..537ae6aa5 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/relatedvideooverlay/HideRelatedVideoOverlayPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/relatedvideooverlay/HideRelatedVideoOverlayPatch.kt
@@ -50,10 +50,9 @@ val hideRelatedVideoOverlayPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt
index b81cab1cb..b251253ac 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/rollingnumber/DisableRollingNumberAnimationPatch.kt
@@ -31,10 +31,9 @@ val disableRollingNumberAnimationPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt
index 1faab015e..723005d67 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt
@@ -174,10 +174,9 @@ val hideShortsComponentsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/signintotvpopup/DisableSignInToTvPatchPopup.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/signintotvpopup/DisableSignInToTvPatchPopup.kt
index 1a591c315..3f7229432 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/signintotvpopup/DisableSignInToTvPatchPopup.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/signintotvpopup/DisableSignInToTvPatchPopup.kt
@@ -33,10 +33,9 @@ val disableSignInToTvPopupPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt
index 6d9bfb567..ab85861c4 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/time/HideTimestampPatch.kt
@@ -23,10 +23,9 @@ val hideTimestampPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt
index 08f78f9dc..34ce1e1ff 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/miniplayer/MiniplayerPatch.kt
@@ -155,10 +155,9 @@ val miniplayerPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt
index 56bdac659..b95e81ba1 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/panels/popup/PlayerPopupPanelsPatch.kt
@@ -23,10 +23,9 @@ val playerPopupPanelsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/ExitFullscreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/ExitFullscreenPatch.kt
index 2c61ce596..148427a95 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/ExitFullscreenPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/ExitFullscreenPatch.kt
@@ -23,10 +23,9 @@ internal val exitFullscreenPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt
index 1c76b56e4..a0b513f3e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/fullscreen/OpenVideosFullscreenPatch.kt
@@ -25,10 +25,9 @@ val openVideosFullscreenPatch = bytecodePatch(
compatibleWith(
"com.google.android.youtube"(
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt
index 35f81a643..21ffbe853 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/player/overlay/CustomPlayerOverlayOpacityPatch.kt
@@ -54,10 +54,9 @@ val customPlayerOverlayOpacityPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt
index b65b8f6c4..7e063aca2 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/returnyoutubedislike/ReturnYouTubeDislikePatch.kt
@@ -63,10 +63,9 @@ val returnYouTubeDislikePatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt
index 4f06635d1..ad9ffb6c1 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/searchbar/WideSearchbarPatch.kt
@@ -68,10 +68,9 @@ val wideSearchbarPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt
index bf63a2191..17b20a913 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsautoplay/ShortsAutoplayPatch.kt
@@ -46,10 +46,9 @@ val shortsAutoplayPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt
index aa9aa1954..1f4b58278 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/shortsplayer/OpenShortsInRegularPlayerPatch.kt
@@ -66,10 +66,9 @@ val openShortsInRegularPlayerPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt
index 80cbfe041..8ada0c07a 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/sponsorblock/SponsorBlockPatch.kt
@@ -128,10 +128,9 @@ val sponsorBlockPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt
index 0d6b6c89c..c60250949 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/spoofappversion/SpoofAppVersionPatch.kt
@@ -17,6 +17,7 @@ import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPref
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
import app.revanced.patches.youtube.misc.playservice.is_19_43_or_greater
+import app.revanced.patches.youtube.misc.playservice.is_20_14_or_greater
import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
@@ -60,10 +61,9 @@ val spoofAppVersionPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
@@ -79,17 +79,21 @@ val spoofAppVersionPatch = bytecodePatch(
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
preferences = setOf(
SwitchPreference("revanced_spoof_app_version"),
- if (is_19_43_or_greater) {
+ if (is_20_14_or_greater) {
+ ListPreference("revanced_spoof_app_version_target")
+ } else if (is_19_43_or_greater) {
ListPreference(
key = "revanced_spoof_app_version_target",
- summaryKey = null
+ summaryKey = null,
+ entriesKey = "revanced_spoof_app_version_target_legacy_20_13_entries",
+ entryValuesKey = "revanced_spoof_app_version_target_legacy_20_13_entry_values"
)
} else {
ListPreference(
key = "revanced_spoof_app_version_target",
summaryKey = null,
- entriesKey = "revanced_spoof_app_version_target_legacy_entries",
- entryValuesKey = "revanced_spoof_app_version_target_legacy_entry_values"
+ entriesKey = "revanced_spoof_app_version_target_legacy_19_34_entries",
+ entryValuesKey = "revanced_spoof_app_version_target_legacy_19_34_entry_values"
)
}
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt
index e54d13e79..fd61679c3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startpage/ChangeStartPagePatch.kt
@@ -34,10 +34,9 @@ val changeStartPagePatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt
index 4a8737fa4..f65b85732 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/startupshortsreset/DisableResumingShortsOnStartupPatch.kt
@@ -36,10 +36,9 @@ val disableResumingShortsOnStartupPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt
index 04d7a3d79..ca8709871 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/theme/ThemePatch.kt
@@ -206,10 +206,9 @@ val themePatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt
index bd883935e..4b3ebf9ad 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/AlternativeThumbnailsPatch.kt
@@ -35,10 +35,9 @@ val alternativeThumbnailsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictionsPatch.kt
index 1f2547720..65b95b7a6 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictionsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/thumbnails/BypassImageRegionRestrictionsPatch.kt
@@ -29,10 +29,9 @@ val bypassImageRegionRestrictionsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt
index 5a7d976df..26a74c5b9 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/announcements/AnnouncementsPatch.kt
@@ -25,10 +25,9 @@ val announcementsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt
index e90fc619a..324006c05 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/autorepeat/AutoRepeatPatch.kt
@@ -26,10 +26,9 @@ val autoRepeatPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt
index a0e44d4d5..cd5830462 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/backgroundplayback/BackgroundPlaybackPatch.kt
@@ -53,10 +53,9 @@ val backgroundPlaybackPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt
index ab8c54afb..21a7c048b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/EnableDebuggingPatch.kt
@@ -1,144 +1,34 @@
package app.revanced.patches.youtube.misc.debugging
-import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
-import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
-import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.all.misc.resources.addResources
-import app.revanced.patches.all.misc.resources.addResourcesPatch
-import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
-import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
-import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference.Sorting
+import app.revanced.patches.shared.misc.debugging.enableDebuggingPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
-import app.revanced.patches.youtube.misc.playservice.versionCheckPatch
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
-import app.revanced.util.findInstructionIndicesReversedOrThrow
-import app.revanced.util.indexOfFirstInstructionOrThrow
-import app.revanced.util.indexOfFirstInstructionReversedOrThrow
-import com.android.tools.smali.dexlib2.Opcode
-import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
-private const val EXTENSION_CLASS_DESCRIPTOR =
- "Lapp/revanced/extension/youtube/patches/EnableDebuggingPatch;"
-
-// TODO: Refactor this into a shared patch that can be used by both YT and YT Music.
-// Almost all of the feature flag hooks are the same between both apps.
-val enableDebuggingPatch = bytecodePatch(
- name = "Enable debugging",
- description = "Adds options for debugging and exporting ReVanced logs to the clipboard.",
-) {
- dependsOn(
- sharedExtensionPatch,
- settingsPatch,
- addResourcesPatch,
- versionCheckPatch
- )
-
- compatibleWith(
- "com.google.android.youtube"(
- "19.34.42",
- "19.43.41",
- "19.47.53",
- "20.07.39",
- "20.12.46",
- "20.13.41",
+@Suppress("unused")
+val enableDebuggingPatch = enableDebuggingPatch(
+ block = {
+ dependsOn(
+ sharedExtensionPatch,
+ settingsPatch,
)
- )
- execute {
- addResources("shared", "misc.debugging.enableDebuggingPatch")
+ compatibleWith(
+ "com.google.android.youtube"(
+ "19.34.42",
+ "19.43.41",
+ "20.07.39",
+ "20.13.41",
+ "20.14.43",
+ )
+ )
+ },
+ executeBlock = {
addResources("youtube", "misc.debugging.enableDebuggingPatch")
-
- PreferenceScreen.MISC.addPreferences(
- PreferenceScreenPreference(
- key = "revanced_debug_screen",
- sorting = Sorting.UNSORTED,
- preferences = setOf(
- SwitchPreference("revanced_debug"),
- SwitchPreference("revanced_debug_protobuffer"),
- SwitchPreference("revanced_debug_stacktrace"),
- SwitchPreference("revanced_debug_toast_on_error"),
- NonInteractivePreference(
- "revanced_debug_export_logs_to_clipboard",
- tag = "app.revanced.extension.shared.settings.preference.ExportLogToClipboardPreference",
- selectable = true
- ),
- NonInteractivePreference(
- "revanced_debug_logs_clear_buffer",
- tag = "app.revanced.extension.shared.settings.preference.ClearLogBufferPreference",
- selectable = true
- ),
- ),
- ),
- )
-
- // Hook the methods that look up if a feature flag is active.
- experimentalBooleanFeatureFlagFingerprint.match(
- experimentalFeatureFlagParentFingerprint.originalClassDef
- ).method.apply {
- findInstructionIndicesReversedOrThrow(Opcode.RETURN).forEach { index ->
- val register = getInstruction(index).registerA
-
- addInstructions(
- index,
- """
- invoke-static { v$register, p1 }, $EXTENSION_CLASS_DESCRIPTOR->isBooleanFeatureFlagEnabled(ZLjava/lang/Long;)Z
- move-result v$register
- """
- )
- }
- }
-
- experimentalDoubleFeatureFlagFingerprint.match(
- experimentalFeatureFlagParentFingerprint.originalClassDef
- ).method.apply {
- val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
-
- addInstructions(
- insertIndex,
- """
- move-result-wide v0 # Also clobbers v1 (p0) since result is wide.
- invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isDoubleFeatureFlagEnabled(DJD)D
- move-result-wide v0
- return-wide v0
- """
- )
- }
-
- experimentalLongFeatureFlagFingerprint.match(
- experimentalFeatureFlagParentFingerprint.originalClassDef
- ).method.apply {
- val insertIndex = indexOfFirstInstructionOrThrow(Opcode.MOVE_RESULT_WIDE)
-
- addInstructions(
- insertIndex,
- """
- move-result-wide v0
- invoke-static/range { v0 .. v5 }, $EXTENSION_CLASS_DESCRIPTOR->isLongFeatureFlagEnabled(JJJ)J
- move-result-wide v0
- return-wide v0
- """
- )
- }
-
- experimentalStringFeatureFlagFingerprint.match(
- experimentalFeatureFlagParentFingerprint.originalClassDef
- ).method.apply {
- val insertIndex = indexOfFirstInstructionReversedOrThrow(Opcode.MOVE_RESULT_OBJECT)
-
- addInstructions(
- insertIndex,
- """
- move-result-object v0
- invoke-static { v0, p1, p2, p3 }, $EXTENSION_CLASS_DESCRIPTOR->isStringFeatureFlagEnabled(Ljava/lang/String;JLjava/lang/String;)Ljava/lang/String;
- move-result-object v0
- return-object v0
- """
- )
- }
-
- // There exists other experimental accessor methods for byte[]
- // and wrappers for obfuscated classes, but currently none of those are hooked.
- }
-}
+ },
+ hookStringFeatureFlag = true,
+ preferenceScreen = PreferenceScreen.MISC,
+ additionalDebugPreferences = listOf(SwitchPreference("revanced_debug_protobuffer"))
+)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt
index 5de171637..5982114de 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dimensions/spoof/SpoofDeviceDimensionsPatch.kt
@@ -26,10 +26,9 @@ val spoofDeviceDimensionsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt
index f9ee7849b..dc2aaf258 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/dns/CheckWatchHistoryDomainNameResolutionPatch.kt
@@ -23,10 +23,9 @@ val checkWatchHistoryDomainNameResolutionPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt
index 3de2e836a..7877ce7db 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/Fingerprints.kt
@@ -1,8 +1,8 @@
package app.revanced.patches.youtube.misc.fix.backtoexitgesture
-import com.android.tools.smali.dexlib2.Opcode
-import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.patcher.fingerprint
+import com.android.tools.smali.dexlib2.AccessFlags
+import com.android.tools.smali.dexlib2.Opcode
internal val scrollPositionFingerprint = fingerprint {
accessFlags(AccessFlags.PROTECTED, AccessFlags.FINAL)
@@ -24,30 +24,18 @@ internal val recyclerViewTopScrollingFingerprint = fingerprint {
returns("V")
parameters()
opcodes(
- Opcode.IGET_OBJECT,
- Opcode.IF_EQZ,
- Opcode.IGET_OBJECT,
- Opcode.INVOKE_INTERFACE,
- Opcode.MOVE_RESULT_OBJECT,
- Opcode.INVOKE_INTERFACE,
- Opcode.MOVE_RESULT,
- Opcode.IF_EQZ,
- Opcode.INVOKE_INTERFACE,
- Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.GOTO,
Opcode.IGET_OBJECT,
- Opcode.INVOKE_INTERFACE,
+ Opcode.INVOKE_INTERFACE
)
}
internal val recyclerViewTopScrollingParentFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
- parameters("L", "L", "Landroid/view/ViewGroup;", "Landroid/view/ViewGroup;")
opcodes(
- Opcode.INVOKE_DIRECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
Opcode.IPUT_OBJECT,
@@ -55,5 +43,8 @@ internal val recyclerViewTopScrollingParentFingerprint = fingerprint {
Opcode.CONST_16,
Opcode.INVOKE_VIRTUAL,
Opcode.NEW_INSTANCE,
+ Opcode.INVOKE_DIRECT,
+ Opcode.IPUT_OBJECT,
+ Opcode.RETURN_VOID
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt
index d64857769..cf55ed6b5 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/backtoexitgesture/FixBackToExitGesturePatch.kt
@@ -15,13 +15,14 @@ internal val fixBackToExitGesturePatch = bytecodePatch(
) {
execute {
- recyclerViewTopScrollingFingerprint.match(recyclerViewTopScrollingParentFingerprint.originalClassDef)
- .let {
- it.method.addInstruction(
- it.patternMatch!!.endIndex,
- "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->onTopView()V"
- )
- }
+ recyclerViewTopScrollingFingerprint.match(
+ recyclerViewTopScrollingParentFingerprint.originalClassDef
+ ).let {
+ it.method.addInstruction(
+ it.patternMatch!!.endIndex,
+ "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->onTopView()V"
+ )
+ }
scrollPositionFingerprint.let {
navigate(it.originalMethod)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt
index 5ffd49cb4..5dc87ad94 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/GmsCoreSupportPatch.kt
@@ -37,10 +37,9 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
YOUTUBE_PACKAGE_NAME(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/DisableHapticFeedbackPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/DisableHapticFeedbackPatch.kt
index 363fea9c2..cd50847fd 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/DisableHapticFeedbackPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/hapticfeedback/DisableHapticFeedbackPatch.kt
@@ -28,10 +28,9 @@ val disableHapticFeedbackPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt
index 6f0b94ece..2b1b2fc8e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/BypassURLRedirectsPatch.kt
@@ -34,10 +34,9 @@ val bypassURLRedirectsPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt
index 428b606ff..70e5b8dbc 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/links/OpenLinksExternallyPatch.kt
@@ -43,10 +43,9 @@ val openLinksExternallyPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt
index 235572eaa..7e99f0177 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/privacy/RemoveTrackingQueryParameterPatch.kt
@@ -32,10 +32,9 @@ val removeTrackingQueryParameterPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt
index 3981e7db1..9981a8fe6 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt
@@ -24,10 +24,9 @@ val spoofVideoStreamsPatch = spoofVideoStreamsPatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt
index b17d1c96c..3aec4a62e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/audio/ForceOriginalAudioPatch.kt
@@ -46,10 +46,9 @@ val forceOriginalAudioPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
@@ -57,7 +56,10 @@ val forceOriginalAudioPatch = bytecodePatch(
addResources("youtube", "video.audio.forceOriginalAudioPatch")
PreferenceScreen.VIDEO.addPreferences(
- SwitchPreference("revanced_force_original_audio")
+ SwitchPreference(
+ key = "revanced_force_original_audio",
+ tag = "app.revanced.extension.youtube.settings.preference.ForceOriginalAudioSwitchPreference"
+ )
)
mainActivityOnCreateFingerprint.method.addInstruction(
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/DisableHdrPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/DisableHdrPatch.kt
index abea2c22c..96192517b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/DisableHdrPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/hdr/DisableHdrPatch.kt
@@ -56,10 +56,9 @@ val disableHdrPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt
index 55a449647..ca51614b3 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/quality/VideoQualityPatch.kt
@@ -26,10 +26,9 @@ val videoQualityPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt
index 7ab9d2e0b..3da73226b 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/video/speed/PlaybackSpeedPatch.kt
@@ -30,10 +30,9 @@ val playbackSpeedPatch = bytecodePatch(
"com.google.android.youtube"(
"19.34.42",
"19.43.41",
- "19.47.53",
"20.07.39",
- "20.12.46",
"20.13.41",
+ "20.14.43",
)
)
diff --git a/patches/src/main/resources/addresources/values-af-rZA/strings.xml b/patches/src/main/resources/addresources/values-af-rZA/strings.xml
index 98a3659f6..f697cddf7 100644
--- a/patches/src/main/resources/addresources/values-af-rZA/strings.xml
+++ b/patches/src/main/resources/addresources/values-af-rZA/strings.xml
@@ -89,6 +89,7 @@ Second \"item\" text"