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
// 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
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 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 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",
"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",
"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.
• Feed is organized by topics and channels.
• 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_summary_on">Version spoofed</string>
<string name="revanced_spoof_app_version_summary_off">Version not spoofed</string>

View File

@ -275,6 +275,9 @@
<!-- 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
<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" />
@ -909,6 +912,7 @@
<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 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="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"/>