feat(YouTube): Add Disable layout updates patch https://github.com/inotia00/ReVanced_Extended/issues/2863

This commit is contained in:
inotia00 2025-03-24 21:33:11 +09:00
parent 7609b904d4
commit e7e011667e
7 changed files with 118 additions and 0 deletions

View File

@ -106,6 +106,34 @@ public class GeneralPatch {
// endregion // endregion
// region [Disable layout updates] patch
private static final String[] REQUEST_HEADER_KEYS = {
"X-Youtube-Cold-Config-Data",
"X-Youtube-Cold-Hash-Data",
"X-Youtube-Hot-Config-Data",
"X-Youtube-Hot-Hash-Data"
};
private static final boolean DISABLE_LAYOUT_UPDATES =
Settings.DISABLE_LAYOUT_UPDATES.get();
/**
* @param key Keys to be added to the header of CronetBuilder.
* @param value Values to be added to the header of CronetBuilder.
* @return Empty value if setting is enabled.
*/
public static String disableLayoutUpdates(String key, String value) {
if (DISABLE_LAYOUT_UPDATES && StringUtils.equalsAny(key, REQUEST_HEADER_KEYS)) {
Logger.printDebug(() -> "Blocking: " + key);
return "";
}
return value;
}
// endregion
// region [Disable splash animation] patch // region [Disable splash animation] patch
public static boolean disableSplashAnimation(boolean original) { public static boolean disableSplashAnimation(boolean original) {

View File

@ -158,6 +158,7 @@ public class Settings extends BaseSettings {
public static final EnumSetting<FormFactor> CHANGE_FORM_FACTOR = new EnumSetting<>("revanced_change_form_factor", FormFactor.DEFAULT, true, "revanced_change_form_factor_user_dialog_message"); public static final EnumSetting<FormFactor> CHANGE_FORM_FACTOR = new EnumSetting<>("revanced_change_form_factor", FormFactor.DEFAULT, true, "revanced_change_form_factor_user_dialog_message");
public static final BooleanSetting CHANGE_LIVE_RING_CLICK_ACTION = new BooleanSetting("revanced_change_live_ring_click_action", FALSE, true); public static final BooleanSetting CHANGE_LIVE_RING_CLICK_ACTION = new BooleanSetting("revanced_change_live_ring_click_action", FALSE, true);
public static final BooleanSetting DISABLE_LAYOUT_UPDATES = new BooleanSetting("revanced_disable_layout_updates", false, true, "revanced_disable_layout_updates_user_dialog_message");
public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", false, true, "revanced_spoof_app_version_user_dialog_message"); public static final BooleanSetting SPOOF_APP_VERSION = new BooleanSetting("revanced_spoof_app_version", false, true, "revanced_spoof_app_version_user_dialog_message");
public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", PatchStatus.SpoofAppVersionDefaultString(), true, parent(SPOOF_APP_VERSION)); public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", PatchStatus.SpoofAppVersionDefaultString(), true, parent(SPOOF_APP_VERSION));

View File

@ -0,0 +1,17 @@
package app.revanced.patches.youtube.general.updates
import app.revanced.util.fingerprint.legacyFingerprint
import app.revanced.util.or
import com.android.tools.smali.dexlib2.AccessFlags
internal val cronetHeaderFingerprint = legacyFingerprint(
name = "cronetHeaderFingerprint",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("Ljava/lang/String;", "Ljava/lang/String;"),
strings = listOf("Accept-Encoding"),
// In YouTube 19.16.39 or earlier, there are two methods with almost the same structure.
// Check the fields of the class to identify them correctly.
customFingerprint = { _, classDef ->
classDef.fields.find { it.type == "J" } != null
}
)

View File

@ -0,0 +1,50 @@
package app.revanced.patches.youtube.general.updates
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.patch.bytecodePatch
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.patch.PatchList.DISABLE_LAYOUT_UPDATES
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
import app.revanced.patches.youtube.utils.settings.settingsPatch
import app.revanced.util.fingerprint.matchOrThrow
@Suppress("unused")
val layoutUpdatesPatch = bytecodePatch(
DISABLE_LAYOUT_UPDATES.title,
DISABLE_LAYOUT_UPDATES.summary,
) {
compatibleWith(COMPATIBLE_PACKAGE)
dependsOn(settingsPatch)
execute {
cronetHeaderFingerprint.matchOrThrow().let {
it.method.apply {
val index = it.stringMatches!!.first().index
addInstructions(
index, """
invoke-static {p1, p2}, $GENERAL_CLASS_DESCRIPTOR->disableLayoutUpdates(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
move-result-object p2
"""
)
}
}
// region add settings
addPreference(
arrayOf(
"PREFERENCE_SCREEN: GENERAL",
"PREFERENCE_CATEGORY: GENERAL_EXPERIMENTAL_FLAGS",
"SETTINGS: DISABLE_LAYOUT_UPDATES"
),
DISABLE_LAYOUT_UPDATES
)
// endregion
}
}

View File

@ -81,6 +81,10 @@ internal enum class PatchList(
"Disable haptic feedback", "Disable haptic feedback",
"Adds options to disable haptic feedback when swiping in the video player." "Adds options to disable haptic feedback when swiping in the video player."
), ),
DISABLE_LAYOUT_UPDATES(
"Disable layout updates",
"Adds an option to disable layout updates by server."
),
DISABLE_RESUMING_MINIPLAYER_ON_STARTUP( DISABLE_RESUMING_MINIPLAYER_ON_STARTUP(
"Disable resuming Miniplayer on startup", "Disable resuming Miniplayer on startup",
"Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup." "Adds an option to disable the Miniplayer 'Continue watching' from resuming on app startup."

View File

@ -518,6 +518,20 @@ Automotive layout
• Shorts open in the regular player. • Shorts open in the regular player.
• Feed is organized by topics and channels. • Feed is organized by topics and channels.
• Video description cannot be opened when 'Spoof streaming data' is turned off."</string> • Video description cannot be opened when 'Spoof streaming data' is turned off."</string>
<string name="revanced_disable_layout_updates_title">Disable layout updates</string>
<string name="revanced_disable_layout_updates_summary_on">Layout will not be updated by the server.</string>
<string name="revanced_disable_layout_updates_summary_off">Layout will be updated by the server.</string>
<string name="revanced_disable_layout_updates_user_dialog_message">"App layout reverts to the layout it was using when it was first installed.
Some server-side layouts may not revert.
Changes include:
• Components in the player flyout menu (or related settings) may not work.
• Rolling numbers are not animated.
• The Library tab is used.
• The Music section of video description may not work.
• Account switch button may not appear on the Library tab. Use the 'Enable wide search bar in You tab' setting."</string>
<string name="revanced_spoof_app_version_title">Spoof app version</string> <string name="revanced_spoof_app_version_title">Spoof app version</string>
<string name="revanced_spoof_app_version_summary_on">Version spoofed</string> <string name="revanced_spoof_app_version_summary_on">Version spoofed</string>
<string name="revanced_spoof_app_version_summary_off">Version not spoofed</string> <string name="revanced_spoof_app_version_summary_off">Version not spoofed</string>

View File

@ -275,6 +275,9 @@
<!-- SETTINGS: CHANGE_FORM_FACTOR <!-- SETTINGS: CHANGE_FORM_FACTOR
<ListPreference android:entries="@array/revanced_change_form_factor_entries" android:title="@string/revanced_change_form_factor_title" android:key="revanced_change_form_factor" android:entryValues="@array/revanced_change_form_factor_entry_values" />SETTINGS: CHANGE_FORM_FACTOR --> <ListPreference android:entries="@array/revanced_change_form_factor_entries" android:title="@string/revanced_change_form_factor_title" android:key="revanced_change_form_factor" android:entryValues="@array/revanced_change_form_factor_entry_values" />SETTINGS: CHANGE_FORM_FACTOR -->
<!-- SETTINGS: DISABLE_LAYOUT_UPDATES
<SwitchPreference android:title="@string/revanced_disable_layout_updates_title" android:key="revanced_disable_layout_updates" android:summaryOn="@string/revanced_disable_layout_updates_summary_on" android:summaryOff="@string/revanced_disable_layout_updates_summary_off" />SETTINGS: DISABLE_LAYOUT_UPDATES -->
<!-- SETTINGS: SPOOF_APP_VERSION <!-- SETTINGS: SPOOF_APP_VERSION
<SwitchPreference android:title="@string/revanced_spoof_app_version_title" android:key="revanced_spoof_app_version" android:summaryOn="@string/revanced_spoof_app_version_summary_on" android:summaryOff="@string/revanced_spoof_app_version_summary_off" /> <SwitchPreference android:title="@string/revanced_spoof_app_version_title" android:key="revanced_spoof_app_version" android:summaryOn="@string/revanced_spoof_app_version_summary_on" android:summaryOff="@string/revanced_spoof_app_version_summary_off" />
<app.revanced.extension.shared.settings.preference.WideListPreference android:title="@string/revanced_spoof_app_version_target_entry_title" android:key="revanced_spoof_app_version_target" android:entries="@array/revanced_spoof_app_version_target_entries" android:entryValues="@array/revanced_spoof_app_version_target_entry_values" /> <app.revanced.extension.shared.settings.preference.WideListPreference android:title="@string/revanced_spoof_app_version_target_entry_title" android:key="revanced_spoof_app_version_target" android:entries="@array/revanced_spoof_app_version_target_entries" android:entryValues="@array/revanced_spoof_app_version_target_entry_values" />
@ -909,6 +912,7 @@
<Preference android:title="Change start page" android:summary="@string/revanced_patches_excluded" android:selectable="false"/> <Preference android:title="Change start page" android:summary="@string/revanced_patches_excluded" android:selectable="false"/>
<Preference android:title="Disable forced auto audio tracks" android:summary="@string/revanced_patches_excluded" android:selectable="false"/> <Preference android:title="Disable forced auto audio tracks" android:summary="@string/revanced_patches_excluded" android:selectable="false"/>
<Preference android:title="Disable forced auto captions" android:summary="@string/revanced_patches_excluded" android:selectable="false"/> <Preference android:title="Disable forced auto captions" android:summary="@string/revanced_patches_excluded" android:selectable="false"/>
<Preference android:title="Disable layout updates" android:summary="@string/revanced_patches_excluded" android:selectable="false"/>
<Preference android:title="Disable splash animation" android:summary="@string/revanced_patches_excluded" android:selectable="false"/> <Preference android:title="Disable splash animation" android:summary="@string/revanced_patches_excluded" android:selectable="false"/>
<Preference android:title="Enable gradient loading screen" android:summary="@string/revanced_patches_excluded" android:selectable="false"/> <Preference android:title="Enable gradient loading screen" android:summary="@string/revanced_patches_excluded" android:selectable="false"/>
<Preference android:title="Hide layout components" android:summary="@string/revanced_patches_excluded" android:selectable="false"/> <Preference android:title="Hide layout components" android:summary="@string/revanced_patches_excluded" android:selectable="false"/>