diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java
index 13be9547ca..a5b558acde 100644
--- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java
+++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java
@@ -1,12 +1,15 @@
package app.revanced.extension.shared.settings;
+import app.revanced.extension.shared.spoof.ClientType;
+import app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch;
+
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
import static app.revanced.extension.shared.settings.Setting.parent;
/**
* Settings shared across multiple apps.
- *
+ *
* To ensure this class is loaded when the UI is created, app specific setting bundles should extend
* or reference this class.
*/
@@ -16,4 +19,10 @@ public class BaseSettings {
public static final BooleanSetting DEBUG_TOAST_ON_ERROR = new BooleanSetting("revanced_debug_toast_on_error", TRUE, "revanced_debug_toast_on_error_user_dialog_message");
public static final IntegerSetting CHECK_ENVIRONMENT_WARNINGS_ISSUED = new IntegerSetting("revanced_check_environment_warnings_issued", 0, true, false);
+
+ public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true, "revanced_spoof_video_streams_user_dialog_message");
+ public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
+ "revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofVideoStreamsPatch.ForceiOSAVCAvailability());
+ public static final EnumSetting SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
+
}
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/ClientType.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java
similarity index 92%
rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/ClientType.java
rename to extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java
index b29d665b48..93a7815024 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/ClientType.java
+++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/ClientType.java
@@ -1,7 +1,7 @@
-package app.revanced.extension.youtube.patches.spoof;
+package app.revanced.extension.shared.spoof;
-import static app.revanced.extension.youtube.patches.spoof.DeviceHardwareSupport.allowAV1;
-import static app.revanced.extension.youtube.patches.spoof.DeviceHardwareSupport.allowVP9;
+import static app.revanced.extension.shared.spoof.DeviceHardwareSupport.allowAV1;
+import static app.revanced.extension.shared.spoof.DeviceHardwareSupport.allowVP9;
import android.os.Build;
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/DeviceHardwareSupport.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/DeviceHardwareSupport.java
similarity index 90%
rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/DeviceHardwareSupport.java
rename to extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/DeviceHardwareSupport.java
index 3adc6befb3..019a13eeb7 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/DeviceHardwareSupport.java
+++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/DeviceHardwareSupport.java
@@ -1,11 +1,11 @@
-package app.revanced.extension.youtube.patches.spoof;
+package app.revanced.extension.shared.spoof;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.os.Build;
import app.revanced.extension.shared.Logger;
-import app.revanced.extension.youtube.settings.Settings;
+import app.revanced.extension.shared.settings.BaseSettings;
public class DeviceHardwareSupport {
public static final boolean DEVICE_HAS_HARDWARE_DECODING_VP9;
@@ -44,7 +44,7 @@ public class DeviceHardwareSupport {
}
public static boolean allowVP9() {
- return DEVICE_HAS_HARDWARE_DECODING_VP9 && !Settings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get();
+ return DEVICE_HAS_HARDWARE_DECODING_VP9 && !BaseSettings.SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC.get();
}
public static boolean allowAV1() {
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java
similarity index 93%
rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java
rename to extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java
index b50e3f4ffa..1381a9ba51 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch.java
+++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/SpoofVideoStreamsPatch.java
@@ -1,4 +1,4 @@
-package app.revanced.extension.youtube.patches.spoof;
+package app.revanced.extension.shared.spoof;
import android.net.Uri;
@@ -12,20 +12,12 @@
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
import app.revanced.extension.shared.settings.Setting;
-import app.revanced.extension.youtube.patches.spoof.requests.StreamingDataRequest;
-import app.revanced.extension.youtube.settings.Settings;
+import app.revanced.extension.shared.spoof.requests.StreamingDataRequest;
+import app.revanced.extension.shared.settings.BaseSettings;
@SuppressWarnings("unused")
public class SpoofVideoStreamsPatch {
- public static final class ForceiOSAVCAvailability implements Setting.Availability {
- @Override
- public boolean isAvailable() {
- return Settings.SPOOF_VIDEO_STREAMS.get() && Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
- }
- }
-
- private static final boolean SPOOF_STREAMING_DATA = Settings.SPOOF_VIDEO_STREAMS.get();
-
+ private static final boolean SPOOF_STREAMING_DATA = BaseSettings.SPOOF_VIDEO_STREAMS.get();
/**
* Any unreachable ip address. Used to intentionally fail requests.
*/
@@ -165,4 +157,11 @@ public static byte[] removeVideoPlaybackPostBody(Uri uri, int method, byte[] pos
return postData;
}
+
+ public static final class ForceiOSAVCAvailability implements Setting.Availability {
+ @Override
+ public boolean isAvailable() {
+ return BaseSettings.SPOOF_VIDEO_STREAMS.get() && BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get() == ClientType.IOS;
+ }
+ }
}
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/requests/PlayerRoutes.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java
similarity index 95%
rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/requests/PlayerRoutes.java
rename to extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java
index f77288ccc3..fa5cc18558 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/requests/PlayerRoutes.java
+++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/PlayerRoutes.java
@@ -1,4 +1,4 @@
-package app.revanced.extension.youtube.patches.spoof.requests;
+package app.revanced.extension.shared.spoof.requests;
import org.json.JSONException;
import org.json.JSONObject;
@@ -10,7 +10,7 @@
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.requests.Requester;
import app.revanced.extension.shared.requests.Route;
-import app.revanced.extension.youtube.patches.spoof.ClientType;
+import app.revanced.extension.shared.spoof.ClientType;
final class PlayerRoutes {
static final Route.CompiledRoute GET_STREAMING_DATA = new Route(
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/requests/StreamingDataRequest.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/StreamingDataRequest.java
similarity index 96%
rename from extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/requests/StreamingDataRequest.java
rename to extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/StreamingDataRequest.java
index 0c09e0fa76..8853722303 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/spoof/requests/StreamingDataRequest.java
+++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/spoof/requests/StreamingDataRequest.java
@@ -1,6 +1,6 @@
-package app.revanced.extension.youtube.patches.spoof.requests;
+package app.revanced.extension.shared.spoof.requests;
-import static app.revanced.extension.youtube.patches.spoof.requests.PlayerRoutes.GET_STREAMING_DATA;
+import static app.revanced.extension.shared.spoof.requests.PlayerRoutes.GET_STREAMING_DATA;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -22,8 +22,7 @@
import app.revanced.extension.shared.Logger;
import app.revanced.extension.shared.Utils;
import app.revanced.extension.shared.settings.BaseSettings;
-import app.revanced.extension.youtube.patches.spoof.ClientType;
-import app.revanced.extension.youtube.settings.Settings;
+import app.revanced.extension.shared.spoof.ClientType;
/**
* Video streaming data. Fetching is tied to the behavior YT uses,
@@ -70,7 +69,7 @@ protected boolean removeEldestEntry(Entry eldest) {
static {
ClientType[] allClientTypes = ClientType.values();
- ClientType preferredClient = Settings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
+ ClientType preferredClient = BaseSettings.SPOOF_VIDEO_STREAMS_CLIENT_TYPE.get();
CLIENT_ORDER_TO_USE = new ClientType[allClientTypes.length];
CLIENT_ORDER_TO_USE[0] = preferredClient;
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/FullscreenPanelsRemoverPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/FullscreenPanelsRemoverPatch.java
deleted file mode 100644
index f454b361c0..0000000000
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/FullscreenPanelsRemoverPatch.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package app.revanced.extension.youtube.patches;
-
-import android.view.View;
-
-import app.revanced.extension.youtube.settings.Settings;
-
-@SuppressWarnings("unused")
-public class FullscreenPanelsRemoverPatch {
- public static int getFullscreenPanelsVisibility() {
- return Settings.HIDE_FULLSCREEN_PANELS.get() ? View.GONE : View.VISIBLE;
- }
-}
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 4f11de9284..fb3c199c98 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
@@ -2,25 +2,42 @@
import static java.lang.Boolean.FALSE;
import static java.lang.Boolean.TRUE;
-import static app.revanced.extension.shared.settings.Setting.*;
+import static app.revanced.extension.shared.settings.Setting.Availability;
+import static app.revanced.extension.shared.settings.Setting.migrateFromOldPreferences;
+import static app.revanced.extension.shared.settings.Setting.migrateOldSettingToNew;
+import static app.revanced.extension.shared.settings.Setting.parent;
+import static app.revanced.extension.shared.settings.Setting.parentsAny;
import static app.revanced.extension.youtube.patches.ChangeStartPagePatch.StartPage;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHideExpandCloseAvailability;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerHorizontalDragAvailability;
import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType;
-import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.*;
+import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MINIMAL;
+import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_1;
+import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_2;
+import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_3;
+import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.MODERN_4;
+import static app.revanced.extension.youtube.patches.MiniplayerPatch.MiniplayerType.PHONE;
import static app.revanced.extension.youtube.patches.SeekbarThumbnailsPatch.SeekbarThumbnailsHighQualityAvailability;
import static app.revanced.extension.youtube.patches.VersionCheckPatch.IS_19_17_OR_GREATER;
-import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.*;
+import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.IGNORE;
+import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.MANUAL_SKIP;
+import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY;
+import static app.revanced.extension.youtube.sponsorblock.objects.CategoryBehaviour.SKIP_AUTOMATICALLY_ONCE;
import app.revanced.extension.shared.Logger;
-import app.revanced.extension.shared.settings.*;
+import app.revanced.extension.shared.settings.BaseSettings;
+import app.revanced.extension.shared.settings.BooleanSetting;
+import app.revanced.extension.shared.settings.EnumSetting;
+import app.revanced.extension.shared.settings.FloatSetting;
+import app.revanced.extension.shared.settings.IntegerSetting;
+import app.revanced.extension.shared.settings.LongSetting;
+import app.revanced.extension.shared.settings.Setting;
+import app.revanced.extension.shared.settings.StringSetting;
import app.revanced.extension.shared.settings.preference.SharedPrefCategory;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.DeArrowAvailability;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.StillImagesAvailability;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailOption;
import app.revanced.extension.youtube.patches.AlternativeThumbnailsPatch.ThumbnailStillTime;
-import app.revanced.extension.youtube.patches.spoof.ClientType;
-import app.revanced.extension.youtube.patches.spoof.SpoofVideoStreamsPatch;
import app.revanced.extension.youtube.sponsorblock.SponsorBlockSettings;
public class Settings extends BaseSettings {
@@ -37,17 +54,17 @@ public class Settings extends BaseSettings {
"0.25\n0.5\n0.75\n0.9\n0.95\n1.0\n1.05\n1.1\n1.25\n1.5\n1.75\n2.0\n3.0\n4.0\n5.0", true);
// Ads
- public static final BooleanSetting HIDE_FULLSCREEN_ADS = new BooleanSetting("revanced_hide_fullscreen_ads", TRUE);
public static final BooleanSetting HIDE_BUTTONED_ADS = new BooleanSetting("revanced_hide_buttoned_ads", TRUE);
+ public static final BooleanSetting HIDE_FULLSCREEN_ADS = new BooleanSetting("revanced_hide_fullscreen_ads", TRUE);
public static final BooleanSetting HIDE_GENERAL_ADS = new BooleanSetting("revanced_hide_general_ads", TRUE);
public static final BooleanSetting HIDE_GET_PREMIUM = new BooleanSetting("revanced_hide_get_premium", TRUE);
public static final BooleanSetting HIDE_HIDE_LATEST_POSTS = new BooleanSetting("revanced_hide_latest_posts_ads", TRUE);
public static final BooleanSetting HIDE_MERCHANDISE_BANNERS = new BooleanSetting("revanced_hide_merchandise_banners", TRUE);
public static final BooleanSetting HIDE_PAID_PROMOTION_LABEL = new BooleanSetting("revanced_hide_paid_promotion_label", TRUE);
- public static final BooleanSetting HIDE_PRODUCTS_BANNER = new BooleanSetting("revanced_hide_products_banner", TRUE);
public static final BooleanSetting HIDE_PLAYER_STORE_SHELF = new BooleanSetting("revanced_hide_player_store_shelf", TRUE);
- public static final BooleanSetting HIDE_SHOPPING_LINKS = new BooleanSetting("revanced_hide_shopping_links", TRUE);
+ public static final BooleanSetting HIDE_PRODUCTS_BANNER = new BooleanSetting("revanced_hide_products_banner", TRUE);
public static final BooleanSetting HIDE_SELF_SPONSOR = new BooleanSetting("revanced_hide_self_sponsor_ads", TRUE);
+ public static final BooleanSetting HIDE_SHOPPING_LINKS = new BooleanSetting("revanced_hide_shopping_links", TRUE);
public static final BooleanSetting HIDE_VIDEO_ADS = new BooleanSetting("revanced_hide_video_ads", TRUE, true);
public static final BooleanSetting HIDE_VISIT_STORE_BUTTON = new BooleanSetting("revanced_hide_visit_store_button", TRUE);
public static final BooleanSetting HIDE_WEB_SEARCH_RESULTS = new BooleanSetting("revanced_hide_web_search_results", TRUE);
@@ -55,9 +72,27 @@ public class Settings extends BaseSettings {
// Feed
public static final BooleanSetting HIDE_ALBUM_CARDS = new BooleanSetting("revanced_hide_album_cards", FALSE, true);
public static final BooleanSetting HIDE_ARTIST_CARDS = new BooleanSetting("revanced_hide_artist_cards", FALSE);
- public static final BooleanSetting HIDE_EXPANDABLE_CHIP = new BooleanSetting("revanced_hide_expandable_chip", TRUE);
+ public static final BooleanSetting HIDE_CHIPS_SHELF = new BooleanSetting("revanced_hide_chips_shelf", TRUE);
+ public static final BooleanSetting HIDE_COMMUNITY_POSTS = new BooleanSetting("revanced_hide_community_posts", FALSE);
+ public static final BooleanSetting HIDE_COMPACT_BANNER = new BooleanSetting("revanced_hide_compact_banner", TRUE);
+ public static final BooleanSetting HIDE_CROWDFUNDING_BOX = new BooleanSetting("revanced_hide_crowdfunding_box", FALSE, true);
public static final BooleanSetting HIDE_DOODLES = new BooleanSetting("revanced_hide_doodles", FALSE, true, "revanced_hide_doodles_user_dialog_message");
-
+ public static final BooleanSetting HIDE_EXPANDABLE_CHIP = new BooleanSetting("revanced_hide_expandable_chip", TRUE);
+ public static final BooleanSetting HIDE_FEED_SURVEY = new BooleanSetting("revanced_hide_feed_survey", TRUE);
+ public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_FEED = new BooleanSetting("revanced_hide_filter_bar_feed_in_feed", FALSE, true);
+ public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS = new BooleanSetting("revanced_hide_filter_bar_feed_in_related_videos", FALSE, true);
+ public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_SEARCH = new BooleanSetting("revanced_hide_filter_bar_feed_in_search", FALSE, true);
+ public static final BooleanSetting HIDE_FLOATING_MICROPHONE_BUTTON = new BooleanSetting("revanced_hide_floating_microphone_button", TRUE, true);
+ public static final BooleanSetting HIDE_FOR_YOU_SHELF = new BooleanSetting("revanced_hide_for_you_shelf", TRUE);
+ public static final BooleanSetting HIDE_HORIZONTAL_SHELVES = new BooleanSetting("revanced_hide_horizontal_shelves", TRUE);
+ public static final BooleanSetting HIDE_IMAGE_SHELF = new BooleanSetting("revanced_hide_image_shelf", TRUE);
+ public static final BooleanSetting HIDE_MIX_PLAYLISTS = new BooleanSetting("revanced_hide_mix_playlists", TRUE);
+ public static final BooleanSetting HIDE_MOVIES_SECTION = new BooleanSetting("revanced_hide_movies_section", TRUE);
+ public static final BooleanSetting HIDE_NOTIFY_ME_BUTTON = new BooleanSetting("revanced_hide_notify_me_button", TRUE);
+ public static final BooleanSetting HIDE_PLAYABLES = new BooleanSetting("revanced_hide_playables", TRUE);
+ public static final BooleanSetting HIDE_SEARCH_RESULT_RECOMMENDATIONS = new BooleanSetting("revanced_hide_search_result_recommendations", TRUE);
+ public static final BooleanSetting HIDE_SEARCH_RESULT_SHELF_HEADER = new BooleanSetting("revanced_hide_search_result_shelf_header", FALSE);
+ public static final BooleanSetting HIDE_SHOW_MORE_BUTTON = new BooleanSetting("revanced_hide_show_more_button", TRUE, true);
// Alternative thumbnails
public static final EnumSetting ALT_THUMBNAIL_HOME = new EnumSetting<>("revanced_alt_thumbnail_home", ThumbnailOption.ORIGINAL);
public static final EnumSetting ALT_THUMBNAIL_SUBSCRIPTIONS = new EnumSetting<>("revanced_alt_thumbnail_subscription", ThumbnailOption.ORIGINAL);
@@ -69,7 +104,6 @@ public class Settings extends BaseSettings {
public static final BooleanSetting ALT_THUMBNAIL_DEARROW_CONNECTION_TOAST = new BooleanSetting("revanced_alt_thumbnail_dearrow_connection_toast", TRUE, new DeArrowAvailability());
public static final EnumSetting ALT_THUMBNAIL_STILLS_TIME = new EnumSetting<>("revanced_alt_thumbnail_stills_time", ThumbnailStillTime.MIDDLE, new StillImagesAvailability());
public static final BooleanSetting ALT_THUMBNAIL_STILLS_FAST = new BooleanSetting("revanced_alt_thumbnail_stills_fast", FALSE, new StillImagesAvailability());
-
// Hide keyword content
public static final BooleanSetting HIDE_KEYWORD_CONTENT_HOME = new BooleanSetting("revanced_hide_keyword_content_home", FALSE);
public static final BooleanSetting HIDE_KEYWORD_CONTENT_SUBSCRIPTIONS = new BooleanSetting("revanced_hide_keyword_content_subscriptions", FALSE);
@@ -77,61 +111,35 @@ public class Settings extends BaseSettings {
public static final StringSetting HIDE_KEYWORD_CONTENT_PHRASES = new StringSetting("revanced_hide_keyword_content_phrases", "",
parentsAny(HIDE_KEYWORD_CONTENT_HOME, HIDE_KEYWORD_CONTENT_SUBSCRIPTIONS, HIDE_KEYWORD_CONTENT_SEARCH));
- // Uncategorized layout related settings. Do not add to this section, and instead move these out and categorize them.
+ // Player
+ public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE);
+ public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE);
+ public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true);
+ public static final BooleanSetting DISABLE_LIKE_SUBSCRIBE_GLOW = new BooleanSetting("revanced_disable_like_subscribe_glow", FALSE);
+ public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
public static final BooleanSetting DISABLE_SUGGESTED_VIDEO_END_SCREEN = new BooleanSetting("revanced_disable_suggested_video_end_screen", FALSE, true);
- public static final BooleanSetting GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_gradient_loading_screen", FALSE, true);
- public static final BooleanSetting HIDE_HORIZONTAL_SHELVES = new BooleanSetting("revanced_hide_horizontal_shelves", TRUE);
+ public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true);
public static final BooleanSetting HIDE_CAPTIONS_BUTTON = new BooleanSetting("revanced_hide_captions_button", FALSE);
+ public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true);
public static final BooleanSetting HIDE_CHANNEL_BAR = new BooleanSetting("revanced_hide_channel_bar", FALSE);
public static final BooleanSetting HIDE_CHANNEL_MEMBER_SHELF = new BooleanSetting("revanced_hide_channel_member_shelf", TRUE);
- public static final BooleanSetting HIDE_CHIPS_SHELF = new BooleanSetting("revanced_hide_chips_shelf", TRUE);
public static final BooleanSetting HIDE_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_community_guidelines", TRUE);
- public static final BooleanSetting HIDE_COMMUNITY_POSTS = new BooleanSetting("revanced_hide_community_posts", FALSE);
- public static final BooleanSetting HIDE_COMPACT_BANNER = new BooleanSetting("revanced_hide_compact_banner", TRUE);
- public static final BooleanSetting HIDE_CROWDFUNDING_BOX = new BooleanSetting("revanced_hide_crowdfunding_box", FALSE, true);
public static final BooleanSetting HIDE_EMERGENCY_BOX = new BooleanSetting("revanced_hide_emergency_box", TRUE);
public static final BooleanSetting HIDE_ENDSCREEN_CARDS = new BooleanSetting("revanced_hide_endscreen_cards", FALSE);
- public static final BooleanSetting HIDE_FEED_SURVEY = new BooleanSetting("revanced_hide_feed_survey", TRUE);
- public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_FEED = new BooleanSetting("revanced_hide_filter_bar_feed_in_feed", FALSE, true);
- public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_RELATED_VIDEOS = new BooleanSetting("revanced_hide_filter_bar_feed_in_related_videos", FALSE, true);
- public static final BooleanSetting HIDE_FILTER_BAR_FEED_IN_SEARCH = new BooleanSetting("revanced_hide_filter_bar_feed_in_search", FALSE, true);
- public static final BooleanSetting HIDE_FLOATING_MICROPHONE_BUTTON = new BooleanSetting("revanced_hide_floating_microphone_button", TRUE, true);
- public static final BooleanSetting HIDE_FULLSCREEN_PANELS = new BooleanSetting("revanced_hide_fullscreen_panels", TRUE, true);
public static final BooleanSetting HIDE_HIDE_CHANNEL_GUIDELINES = new BooleanSetting("revanced_hide_channel_guidelines", TRUE);
public static final BooleanSetting HIDE_HIDE_INFO_PANELS = new BooleanSetting("revanced_hide_info_panels", TRUE);
- public static final BooleanSetting HIDE_IMAGE_SHELF = new BooleanSetting("revanced_hide_image_shelf", TRUE);
public static final BooleanSetting HIDE_INFO_CARDS = new BooleanSetting("revanced_hide_info_cards", FALSE);
public static final BooleanSetting HIDE_JOIN_MEMBERSHIP_BUTTON = new BooleanSetting("revanced_hide_join_membership_button", TRUE);
- public static final BooleanSetting HIDE_SHOW_MORE_BUTTON = new BooleanSetting("revanced_hide_show_more_button", TRUE, true);
public static final BooleanSetting HIDE_MEDICAL_PANELS = new BooleanSetting("revanced_hide_medical_panels", TRUE);
- public static final BooleanSetting HIDE_MIX_PLAYLISTS = new BooleanSetting("revanced_hide_mix_playlists", TRUE);
- public static final BooleanSetting HIDE_MOVIES_SECTION = new BooleanSetting("revanced_hide_movies_section", TRUE);
- public static final BooleanSetting HIDE_NOTIFY_ME_BUTTON = new BooleanSetting("revanced_hide_notify_me_button", TRUE);
- public static final BooleanSetting HIDE_PLAYABLES = new BooleanSetting("revanced_hide_playables", TRUE);
+ public static final BooleanSetting HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS = new BooleanSetting("revanced_hide_player_previous_next_buttons", FALSE, true);
public static final BooleanSetting HIDE_QUICK_ACTIONS = new BooleanSetting("revanced_hide_quick_actions", FALSE);
public static final BooleanSetting HIDE_RELATED_VIDEOS = new BooleanSetting("revanced_hide_related_videos", FALSE);
- public static final BooleanSetting HIDE_SEARCH_RESULT_SHELF_HEADER = new BooleanSetting("revanced_hide_search_result_shelf_header", FALSE);
public static final BooleanSetting HIDE_SUBSCRIBERS_COMMUNITY_GUIDELINES = new BooleanSetting("revanced_hide_subscribers_community_guidelines", TRUE);
public static final BooleanSetting HIDE_TIMED_REACTIONS = new BooleanSetting("revanced_hide_timed_reactions", TRUE);
- public static final BooleanSetting HIDE_TIMESTAMP = new BooleanSetting("revanced_hide_timestamp", FALSE);
public static final BooleanSetting HIDE_VIDEO_CHANNEL_WATERMARK = new BooleanSetting("revanced_hide_channel_watermark", TRUE);
- public static final BooleanSetting HIDE_FOR_YOU_SHELF = new BooleanSetting("revanced_hide_for_you_shelf", TRUE);
- public static final BooleanSetting HIDE_SEARCH_RESULT_RECOMMENDATIONS = new BooleanSetting("revanced_hide_search_result_recommendations", TRUE);
- public static final IntegerSetting PLAYER_OVERLAY_OPACITY = new IntegerSetting("revanced_player_overlay_opacity",100, true);
- public static final BooleanSetting PLAYER_POPUP_PANELS = new BooleanSetting("revanced_hide_player_popup_panels", FALSE);
-
- // Player
- public static final BooleanSetting DISABLE_FULLSCREEN_AMBIENT_MODE = new BooleanSetting("revanced_disable_fullscreen_ambient_mode", TRUE, true);
- public static final BooleanSetting DISABLE_ROLLING_NUMBER_ANIMATIONS = new BooleanSetting("revanced_disable_rolling_number_animations", FALSE);
- public static final BooleanSetting DISABLE_LIKE_SUBSCRIBE_GLOW = new BooleanSetting("revanced_disable_like_subscribe_glow", FALSE);
- public static final BooleanSetting HIDE_AUTOPLAY_BUTTON = new BooleanSetting("revanced_hide_autoplay_button", TRUE, true);
- public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_hide_cast_button", TRUE, true);
- public static final BooleanSetting HIDE_PLAYER_PREVIOUS_NEXT_BUTTONS = new BooleanSetting("revanced_hide_player_previous_next_buttons", FALSE, true);
- private static final BooleanSetting DEPRECATED_HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true);
- public static final BooleanSetting COPY_VIDEO_URL = new BooleanSetting("revanced_copy_video_url", FALSE);
- public static final BooleanSetting COPY_VIDEO_URL_TIMESTAMP = new BooleanSetting("revanced_copy_video_url_timestamp", TRUE);
public static final BooleanSetting PLAYBACK_SPEED_DIALOG_BUTTON = new BooleanSetting("revanced_playback_speed_dialog_button", FALSE);
-
+ public static final BooleanSetting PLAYER_POPUP_PANELS = new BooleanSetting("revanced_hide_player_popup_panels", FALSE);
+ public static final IntegerSetting PLAYER_OVERLAY_OPACITY = new IntegerSetting("revanced_player_overlay_opacity", 100, true);
// Miniplayer
public static final EnumSetting MINIPLAYER_TYPE = new EnumSetting<>("revanced_miniplayer_type", MiniplayerType.ORIGINAL, true);
private static final Availability MINIPLAYER_ANY_MODERN = MINIPLAYER_TYPE.availability(MODERN_1, MODERN_2, MODERN_3, MODERN_4);
@@ -144,21 +152,18 @@ public class Settings extends BaseSettings {
public static final BooleanSetting MINIPLAYER_ROUNDED_CORNERS = new BooleanSetting("revanced_miniplayer_rounded_corners", TRUE, true, MINIPLAYER_ANY_MODERN);
public static final IntegerSetting MINIPLAYER_WIDTH_DIP = new IntegerSetting("revanced_miniplayer_width_dip", 192, true, MINIPLAYER_ANY_MODERN);
public static final IntegerSetting MINIPLAYER_OPACITY = new IntegerSetting("revanced_miniplayer_opacity", 100, true, MINIPLAYER_TYPE.availability(MODERN_1));
-
// External downloader
public static final BooleanSetting EXTERNAL_DOWNLOADER = new BooleanSetting("revanced_external_downloader", FALSE);
public static final BooleanSetting EXTERNAL_DOWNLOADER_ACTION_BUTTON = new BooleanSetting("revanced_external_downloader_action_button", FALSE);
public static final StringSetting EXTERNAL_DOWNLOADER_PACKAGE_NAME = new StringSetting("revanced_external_downloader_name",
"org.schabi.newpipe" /* NewPipe */, parentsAny(EXTERNAL_DOWNLOADER, EXTERNAL_DOWNLOADER_ACTION_BUTTON));
-
// Comments
public static final BooleanSetting HIDE_COMMENTS_BY_MEMBERS_HEADER = new BooleanSetting("revanced_hide_comments_by_members_header", FALSE);
- public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE);
public static final BooleanSetting HIDE_COMMENTS_CREATE_A_SHORT_BUTTON = new BooleanSetting("revanced_hide_comments_create_a_short_button", TRUE);
public static final BooleanSetting HIDE_COMMENTS_PREVIEW_COMMENT = new BooleanSetting("revanced_hide_comments_preview_comment", FALSE);
+ public static final BooleanSetting HIDE_COMMENTS_SECTION = new BooleanSetting("revanced_hide_comments_section", FALSE);
public static final BooleanSetting HIDE_COMMENTS_THANKS_BUTTON = new BooleanSetting("revanced_hide_comments_thanks_button", TRUE);
public static final BooleanSetting HIDE_COMMENTS_TIMESTAMP_AND_EMOJI_BUTTONS = new BooleanSetting("revanced_hide_comments_timestamp_and_emoji_buttons", TRUE);
-
// Description
public static final BooleanSetting HIDE_ATTRIBUTES_SECTION = new BooleanSetting("revanced_hide_attributes_section", FALSE);
public static final BooleanSetting HIDE_CHAPTERS_SECTION = new BooleanSetting("revanced_hide_chapters_section", TRUE);
@@ -166,47 +171,43 @@ public class Settings extends BaseSettings {
public static final BooleanSetting HIDE_KEY_CONCEPTS_SECTION = new BooleanSetting("revanced_hide_key_concepts_section", FALSE);
public static final BooleanSetting HIDE_PODCAST_SECTION = new BooleanSetting("revanced_hide_podcast_section", TRUE);
public static final BooleanSetting HIDE_TRANSCRIPT_SECTION = new BooleanSetting("revanced_hide_transcript_section", TRUE);
-
// Action buttons
+ public static final BooleanSetting HIDE_CLIP_BUTTON = new BooleanSetting("revanced_hide_clip_button", TRUE);
+ public static final BooleanSetting HIDE_DOWNLOAD_BUTTON = new BooleanSetting("revanced_hide_download_button", FALSE);
public static final BooleanSetting HIDE_LIKE_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_like_dislike_button", FALSE);
- public static final BooleanSetting HIDE_SHARE_BUTTON = new BooleanSetting("revanced_hide_share_button", FALSE);
- public static final BooleanSetting HIDE_REPORT_BUTTON = new BooleanSetting("revanced_hide_report_button", FALSE);
+ public static final BooleanSetting HIDE_PLAYLIST_BUTTON = new BooleanSetting("revanced_hide_playlist_button", FALSE);
public static final BooleanSetting HIDE_REMIX_BUTTON = new BooleanSetting("revanced_hide_remix_button", TRUE);
- public static final BooleanSetting HIDE_DOWNLOAD_BUTTON = new BooleanSetting("revanced_hide_download_button", FALSE);
+ public static final BooleanSetting HIDE_REPORT_BUTTON = new BooleanSetting("revanced_hide_report_button", FALSE);
+ public static final BooleanSetting HIDE_SHARE_BUTTON = new BooleanSetting("revanced_hide_share_button", FALSE);
public static final BooleanSetting HIDE_THANKS_BUTTON = new BooleanSetting("revanced_hide_thanks_button", TRUE);
- public static final BooleanSetting HIDE_CLIP_BUTTON = new BooleanSetting("revanced_hide_clip_button", TRUE);
- public static final BooleanSetting HIDE_PLAYLIST_BUTTON = new BooleanSetting("revanced_hide_playlist_button", FALSE);
-
// Player flyout menu items
- public static final BooleanSetting HIDE_PLAYER_FLYOUT_CAPTIONS = new BooleanSetting("revanced_hide_player_flyout_captions", FALSE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_ADDITIONAL_SETTINGS = new BooleanSetting("revanced_hide_player_flyout_additional_settings", FALSE);
- public static final BooleanSetting HIDE_PLAYER_FLYOUT_LOOP_VIDEO = new BooleanSetting("revanced_hide_player_flyout_loop_video", FALSE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_AMBIENT_MODE = new BooleanSetting("revanced_hide_player_flyout_ambient_mode", FALSE);
+ public static final BooleanSetting HIDE_PLAYER_FLYOUT_AUDIO_TRACK = new BooleanSetting("revanced_hide_player_flyout_audio_track", FALSE);
+ public static final BooleanSetting HIDE_PLAYER_FLYOUT_CAPTIONS = new BooleanSetting("revanced_hide_player_flyout_captions", FALSE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_HELP = new BooleanSetting("revanced_hide_player_flyout_help", TRUE);
- public static final BooleanSetting HIDE_PLAYER_FLYOUT_SPEED = new BooleanSetting("revanced_hide_player_flyout_speed", FALSE);
- public static final BooleanSetting HIDE_PLAYER_FLYOUT_MORE_INFO = new BooleanSetting("revanced_hide_player_flyout_more_info", TRUE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_LOCK_SCREEN = new BooleanSetting("revanced_hide_player_flyout_lock_screen", FALSE);
- public static final BooleanSetting HIDE_PLAYER_FLYOUT_AUDIO_TRACK = new BooleanSetting("revanced_hide_player_flyout_audio_track", FALSE);
+ public static final BooleanSetting HIDE_PLAYER_FLYOUT_LOOP_VIDEO = new BooleanSetting("revanced_hide_player_flyout_loop_video", FALSE);
+ public static final BooleanSetting HIDE_PLAYER_FLYOUT_MORE_INFO = new BooleanSetting("revanced_hide_player_flyout_more_info", TRUE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_SLEEP_TIMER = new BooleanSetting("revanced_hide_player_flyout_sleep_timer", FALSE);
+ public static final BooleanSetting HIDE_PLAYER_FLYOUT_SPEED = new BooleanSetting("revanced_hide_player_flyout_speed", FALSE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_STABLE_VOLUME = new BooleanSetting("revanced_hide_player_flyout_stable_volume", FALSE);
- public static final BooleanSetting HIDE_PLAYER_FLYOUT_WATCH_IN_VR = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE);
- private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE);
public static final BooleanSetting HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_player_flyout_video_quality_footer", FALSE);
+ public static final BooleanSetting HIDE_PLAYER_FLYOUT_WATCH_IN_VR = new BooleanSetting("revanced_hide_player_flyout_watch_in_vr", TRUE);
// General layout
- public static final EnumSetting CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true);
- 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", IS_19_17_OR_GREATER ? "19.35.36" : "17.33.42", true, parent(SPOOF_APP_VERSION));
- public static final BooleanSetting TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_user_dialog_message");
- public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
public static final BooleanSetting BYPASS_IMAGE_REGION_RESTRICTIONS = new BooleanSetting("revanced_bypass_image_region_restrictions", FALSE, true);
+ public static final BooleanSetting GRADIENT_LOADING_SCREEN = new BooleanSetting("revanced_gradient_loading_screen", FALSE, true);
public static final BooleanSetting REMOVE_VIEWER_DISCRETION_DIALOG = new BooleanSetting("revanced_remove_viewer_discretion_dialog", FALSE,
"revanced_remove_viewer_discretion_dialog_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 TABLET_LAYOUT = new BooleanSetting("revanced_tablet_layout", FALSE, true, "revanced_tablet_layout_user_dialog_message");
+ public static final BooleanSetting WIDE_SEARCHBAR = new BooleanSetting("revanced_wide_searchbar", FALSE, true);
+ public static final EnumSetting CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true);
+ public static final StringSetting SPOOF_APP_VERSION_TARGET = new StringSetting("revanced_spoof_app_version_target", IS_19_17_OR_GREATER ? "19.35.36" : "17.33.42", true, parent(SPOOF_APP_VERSION));
// Custom filter
public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE);
public static final StringSetting CUSTOM_FILTER_STRINGS = new StringSetting("revanced_custom_filter_strings", "", true, parent(CUSTOM_FILTER));
-
// Navigation buttons
public static final BooleanSetting HIDE_HOME_BUTTON = new BooleanSetting("revanced_hide_home_button", FALSE, true);
public static final BooleanSetting HIDE_CREATE_BUTTON = new BooleanSetting("revanced_hide_create_button", TRUE, true);
@@ -216,71 +217,67 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON = new BooleanSetting("revanced_switch_create_with_notifications_button", TRUE, true);
// Shorts
- public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_shorts_disable_background_playback", FALSE);
public static final BooleanSetting DISABLE_RESUMING_SHORTS_PLAYER = new BooleanSetting("revanced_disable_resuming_shorts_player", FALSE);
+ public static final BooleanSetting DISABLE_SHORTS_BACKGROUND_PLAYBACK = new BooleanSetting("revanced_shorts_disable_background_playback", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_COMMENTS_BUTTON = new BooleanSetting("revanced_hide_shorts_comments_button", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_dislike_button", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_FULL_VIDEO_LINK_LABEL = new BooleanSetting("revanced_hide_shorts_full_video_link_label", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_GREEN_SCREEN_BUTTON = new BooleanSetting("revanced_hide_shorts_green_screen_button", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_HASHTAG_BUTTON = new BooleanSetting("revanced_hide_shorts_hashtag_button", TRUE);
public static final BooleanSetting HIDE_SHORTS_HOME = new BooleanSetting("revanced_hide_shorts_home", FALSE);
- public static final BooleanSetting HIDE_SHORTS_SUBSCRIPTIONS = new BooleanSetting("revanced_hide_shorts_subscriptions", FALSE);
- public static final BooleanSetting HIDE_SHORTS_SEARCH = new BooleanSetting("revanced_hide_shorts_search", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_INFO_PANEL = new BooleanSetting("revanced_hide_shorts_info_panel", TRUE);
public static final BooleanSetting HIDE_SHORTS_JOIN_BUTTON = new BooleanSetting("revanced_hide_shorts_join_button", TRUE);
- public static final BooleanSetting HIDE_SHORTS_SUBSCRIBE_BUTTON = new BooleanSetting("revanced_hide_shorts_subscribe_button", TRUE);
- public static final BooleanSetting HIDE_SHORTS_PAUSED_OVERLAY_BUTTONS = new BooleanSetting("revanced_hide_shorts_paused_overlay_buttons", FALSE);
- public static final BooleanSetting HIDE_SHORTS_SHOP_BUTTON = new BooleanSetting("revanced_hide_shorts_shop_button", TRUE);
- public static final BooleanSetting HIDE_SHORTS_TAGGED_PRODUCTS = new BooleanSetting("revanced_hide_shorts_tagged_products", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_LIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_like_button", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_LIKE_FOUNTAIN = new BooleanSetting("revanced_hide_shorts_like_fountain", TRUE);
public static final BooleanSetting HIDE_SHORTS_LOCATION_LABEL = new BooleanSetting("revanced_hide_shorts_location_label", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_NAVIGATION_BAR = new BooleanSetting("revanced_hide_shorts_navigation_bar", FALSE, true);
+ public static final BooleanSetting HIDE_SHORTS_PAUSED_OVERLAY_BUTTONS = new BooleanSetting("revanced_hide_shorts_paused_overlay_buttons", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_REMIX_BUTTON = new BooleanSetting("revanced_hide_shorts_remix_button", TRUE);
public static final BooleanSetting HIDE_SHORTS_SAVE_SOUND_BUTTON = new BooleanSetting("revanced_hide_shorts_save_sound_button", TRUE);
- public static final BooleanSetting HIDE_SHORTS_USE_TEMPLATE_BUTTON = new BooleanSetting("revanced_hide_shorts_use_template_button", TRUE);
- public static final BooleanSetting HIDE_SHORTS_UPCOMING_BUTTON = new BooleanSetting("revanced_hide_shorts_upcoming_button", TRUE);
- public static final BooleanSetting HIDE_SHORTS_GREEN_SCREEN_BUTTON = new BooleanSetting("revanced_hide_shorts_green_screen_button", TRUE);
- public static final BooleanSetting HIDE_SHORTS_HASHTAG_BUTTON = new BooleanSetting("revanced_hide_shorts_hashtag_button", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_SEARCH = new BooleanSetting("revanced_hide_shorts_search", FALSE);
public static final BooleanSetting HIDE_SHORTS_SEARCH_SUGGESTIONS = new BooleanSetting("revanced_hide_shorts_search_suggestions", TRUE);
- public static final BooleanSetting HIDE_SHORTS_STICKERS = new BooleanSetting("revanced_hide_shorts_stickers", TRUE);
- public static final BooleanSetting HIDE_SHORTS_SUPER_THANKS_BUTTON = new BooleanSetting("revanced_hide_shorts_super_thanks_button", TRUE);
- public static final BooleanSetting HIDE_SHORTS_LIKE_FOUNTAIN = new BooleanSetting("revanced_hide_shorts_like_fountain", TRUE);
- public static final BooleanSetting HIDE_SHORTS_LIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_like_button", FALSE);
- public static final BooleanSetting HIDE_SHORTS_DISLIKE_BUTTON = new BooleanSetting("revanced_hide_shorts_dislike_button", FALSE);
- public static final BooleanSetting HIDE_SHORTS_COMMENTS_BUTTON = new BooleanSetting("revanced_hide_shorts_comments_button", FALSE);
- public static final BooleanSetting HIDE_SHORTS_REMIX_BUTTON = new BooleanSetting("revanced_hide_shorts_remix_button", TRUE);
public static final BooleanSetting HIDE_SHORTS_SHARE_BUTTON = new BooleanSetting("revanced_hide_shorts_share_button", FALSE);
- public static final BooleanSetting HIDE_SHORTS_INFO_PANEL = new BooleanSetting("revanced_hide_shorts_info_panel", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_SHOP_BUTTON = new BooleanSetting("revanced_hide_shorts_shop_button", TRUE);
public static final BooleanSetting HIDE_SHORTS_SOUND_BUTTON = new BooleanSetting("revanced_hide_shorts_sound_button", FALSE);
- public static final BooleanSetting HIDE_SHORTS_CHANNEL_BAR = new BooleanSetting("revanced_hide_shorts_channel_bar", FALSE);
- public static final BooleanSetting HIDE_SHORTS_VIDEO_TITLE = new BooleanSetting("revanced_hide_shorts_video_title", FALSE);
public static final BooleanSetting HIDE_SHORTS_SOUND_METADATA_LABEL = new BooleanSetting("revanced_hide_shorts_sound_metadata_label", FALSE);
- public static final BooleanSetting HIDE_SHORTS_FULL_VIDEO_LINK_LABEL = new BooleanSetting("revanced_hide_shorts_full_video_link_label", FALSE);
- public static final BooleanSetting HIDE_SHORTS_NAVIGATION_BAR = new BooleanSetting("revanced_hide_shorts_navigation_bar", FALSE, true);
+ public static final BooleanSetting HIDE_SHORTS_STICKERS = new BooleanSetting("revanced_hide_shorts_stickers", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_SUBSCRIBE_BUTTON = new BooleanSetting("revanced_hide_shorts_subscribe_button", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_SUBSCRIPTIONS = new BooleanSetting("revanced_hide_shorts_subscriptions", FALSE);
+ public static final BooleanSetting HIDE_SHORTS_SUPER_THANKS_BUTTON = new BooleanSetting("revanced_hide_shorts_super_thanks_button", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_TAGGED_PRODUCTS = new BooleanSetting("revanced_hide_shorts_tagged_products", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_UPCOMING_BUTTON = new BooleanSetting("revanced_hide_shorts_upcoming_button", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_USE_TEMPLATE_BUTTON = new BooleanSetting("revanced_hide_shorts_use_template_button", TRUE);
+ public static final BooleanSetting HIDE_SHORTS_VIDEO_TITLE = new BooleanSetting("revanced_hide_shorts_video_title", FALSE);
public static final BooleanSetting SHORTS_AUTOPLAY = new BooleanSetting("revanced_shorts_autoplay", FALSE);
public static final BooleanSetting SHORTS_AUTOPLAY_BACKGROUND = new BooleanSetting("revanced_shorts_autoplay_background", TRUE);
// Seekbar
+
public static final BooleanSetting DISABLE_PRECISE_SEEKING_GESTURE = new BooleanSetting("revanced_disable_precise_seeking_gesture", TRUE);
- public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", TRUE);
- public static final BooleanSetting SLIDE_TO_SEEK = new BooleanSetting("revanced_slide_to_seek", FALSE, true);
- public static final BooleanSetting RESTORE_OLD_SEEKBAR_THUMBNAILS = new BooleanSetting("revanced_restore_old_seekbar_thumbnails", TRUE);
- public static final BooleanSetting SEEKBAR_THUMBNAILS_HIGH_QUALITY = new BooleanSetting("revanced_seekbar_thumbnails_high_quality", FALSE, true,
- "revanced_seekbar_thumbnails_high_quality_dialog_message", new SeekbarThumbnailsHighQualityAvailability());
public static final BooleanSetting HIDE_SEEKBAR = new BooleanSetting("revanced_hide_seekbar", FALSE, true);
public static final BooleanSetting HIDE_SEEKBAR_THUMBNAIL = new BooleanSetting("revanced_hide_seekbar_thumbnail", FALSE);
+ public static final BooleanSetting HIDE_TIMESTAMP = new BooleanSetting("revanced_hide_timestamp", FALSE);
+ public static final BooleanSetting RESTORE_OLD_SEEKBAR_THUMBNAILS = new BooleanSetting("revanced_restore_old_seekbar_thumbnails", TRUE);
public static final BooleanSetting SEEKBAR_CUSTOM_COLOR = new BooleanSetting("revanced_seekbar_custom_color", FALSE, true);
+ public static final BooleanSetting SEEKBAR_TAPPING = new BooleanSetting("revanced_seekbar_tapping", TRUE);
+ public static final BooleanSetting SEEKBAR_THUMBNAILS_HIGH_QUALITY = new BooleanSetting("revanced_seekbar_thumbnails_high_quality", FALSE, true,
+ "revanced_seekbar_thumbnails_high_quality_dialog_message", new SeekbarThumbnailsHighQualityAvailability());
+ public static final BooleanSetting SLIDE_TO_SEEK = new BooleanSetting("revanced_slide_to_seek", FALSE, true);
public static final StringSetting SEEKBAR_CUSTOM_COLOR_VALUE = new StringSetting("revanced_seekbar_custom_color_value", "#FF0033", true, parent(SEEKBAR_CUSTOM_COLOR));
// Misc
+ public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
+ public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1, false, false);
public static final BooleanSetting AUTO_CAPTIONS = new BooleanSetting("revanced_auto_captions", FALSE);
- public static final BooleanSetting DISABLE_ZOOM_HAPTICS = new BooleanSetting("revanced_disable_zoom_haptics", TRUE);
- public static final BooleanSetting EXTERNAL_BROWSER = new BooleanSetting("revanced_external_browser", TRUE, true);
public static final BooleanSetting AUTO_REPEAT = new BooleanSetting("revanced_auto_repeat", FALSE);
- public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true,
- "revanced_spoof_device_dimensions_user_dialog_message");
public static final BooleanSetting BYPASS_URL_REDIRECTS = new BooleanSetting("revanced_bypass_url_redirects", TRUE);
- public static final BooleanSetting ANNOUNCEMENTS = new BooleanSetting("revanced_announcements", TRUE);
- public static final BooleanSetting SPOOF_VIDEO_STREAMS = new BooleanSetting("revanced_spoof_video_streams", TRUE, true,"revanced_spoof_video_streams_user_dialog_message");
- public static final BooleanSetting SPOOF_VIDEO_STREAMS_IOS_FORCE_AVC = new BooleanSetting("revanced_spoof_video_streams_ios_force_avc", FALSE, true,
- "revanced_spoof_video_streams_ios_force_avc_user_dialog_message", new SpoofVideoStreamsPatch.ForceiOSAVCAvailability());
- public static final EnumSetting SPOOF_VIDEO_STREAMS_CLIENT_TYPE = new EnumSetting<>("revanced_spoof_video_streams_client", ClientType.ANDROID_VR, true, parent(SPOOF_VIDEO_STREAMS));
- public static final IntegerSetting ANNOUNCEMENT_LAST_ID = new IntegerSetting("revanced_announcement_last_id", -1, false, false);
public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false);
+ public static final BooleanSetting DISABLE_ZOOM_HAPTICS = new BooleanSetting("revanced_disable_zoom_haptics", TRUE);
+ public static final BooleanSetting EXTERNAL_BROWSER = new BooleanSetting("revanced_external_browser", TRUE, true);
public static final BooleanSetting REMOVE_TRACKING_QUERY_PARAMETER = new BooleanSetting("revanced_remove_tracking_query_parameter", TRUE);
-
- // Debugging
+ public static final BooleanSetting SPOOF_DEVICE_DIMENSIONS = new BooleanSetting("revanced_spoof_device_dimensions", FALSE, true,
+ "revanced_spoof_device_dimensions_user_dialog_message");
/**
* When enabled, share the debug logs with care.
* The buffer contains select user data, including the client ip address and information that could identify the end user.
@@ -298,6 +295,8 @@ public class Settings extends BaseSettings {
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final IntegerSetting SWIPE_OVERLAY_BACKGROUND_ALPHA = new IntegerSetting("revanced_swipe_overlay_background_alpha", 127, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
+
+ // Debugging
public static final IntegerSetting SWIPE_OVERLAY_TEXT_SIZE = new IntegerSetting("revanced_swipe_text_overlay_size", 22, true,
parentsAny(SWIPE_BRIGHTNESS, SWIPE_VOLUME));
public static final LongSetting SWIPE_OVERLAY_TIMEOUT = new LongSetting("revanced_swipe_overlay_timeout", 500L, true,
@@ -320,7 +319,6 @@ public class Settings extends BaseSettings {
* Do not use directly, instead use {@link SponsorBlockSettings}
*/
public static final StringSetting SB_PRIVATE_USER_ID = new StringSetting("sb_private_user_id_Do_Not_Share", "");
- public static final StringSetting DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING = new StringSetting("uuid", ""); // Delete sometime in 2024
public static final IntegerSetting SB_CREATE_NEW_SEGMENT_STEP = new IntegerSetting("sb_create_new_segment_step", 150, parent(SB_ENABLED));
public static final BooleanSetting SB_VOTING_BUTTON = new BooleanSetting("sb_voting_button", FALSE, parent(SB_ENABLED));
public static final BooleanSetting SB_CREATE_NEW_SEGMENT = new BooleanSetting("sb_create_new_segment", FALSE, parent(SB_ENABLED));
@@ -331,34 +329,38 @@ public class Settings extends BaseSettings {
public static final BooleanSetting SB_TRACK_SKIP_COUNT = new BooleanSetting("sb_track_skip_count", TRUE, parent(SB_ENABLED));
public static final FloatSetting SB_SEGMENT_MIN_DURATION = new FloatSetting("sb_min_segment_duration", 0F, parent(SB_ENABLED));
public static final BooleanSetting SB_VIDEO_LENGTH_WITHOUT_SEGMENTS = new BooleanSetting("sb_video_length_without_segments", TRUE, parent(SB_ENABLED));
- public static final StringSetting SB_API_URL = new StringSetting("sb_api_url","https://sponsor.ajay.app");
+ public static final StringSetting SB_API_URL = new StringSetting("sb_api_url", "https://sponsor.ajay.app");
public static final BooleanSetting SB_USER_IS_VIP = new BooleanSetting("sb_user_is_vip", FALSE);
public static final IntegerSetting SB_LOCAL_TIME_SAVED_NUMBER_SEGMENTS = new IntegerSetting("sb_local_time_saved_number_segments", 0);
public static final LongSetting SB_LOCAL_TIME_SAVED_MILLISECONDS = new LongSetting("sb_local_time_saved_milliseconds", 0L);
public static final LongSetting SB_LAST_VIP_CHECK = new LongSetting("sb_last_vip_check", 0L, false, false);
public static final BooleanSetting SB_HIDE_EXPORT_WARNING = new BooleanSetting("sb_hide_export_warning", FALSE, false, false);
public static final BooleanSetting SB_SEEN_GUIDELINES = new BooleanSetting("sb_seen_guidelines", FALSE, false, false);
-
public static final StringSetting SB_CATEGORY_SPONSOR = new StringSetting("sb_sponsor", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color","#00D400");
+ public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color", "#00D400");
public static final StringSetting SB_CATEGORY_SELF_PROMO = new StringSetting("sb_selfpromo", MANUAL_SKIP.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color","#FFFF00");
+ public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color", "#FFFF00");
public static final StringSetting SB_CATEGORY_INTERACTION = new StringSetting("sb_interaction", MANUAL_SKIP.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color","#CC00FF");
+ public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color", "#CC00FF");
public static final StringSetting SB_CATEGORY_HIGHLIGHT = new StringSetting("sb_highlight", MANUAL_SKIP.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color","#FF1684");
+ public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color", "#FF1684");
public static final StringSetting SB_CATEGORY_INTRO = new StringSetting("sb_intro", MANUAL_SKIP.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color","#00FFFF");
+ public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color", "#00FFFF");
public static final StringSetting SB_CATEGORY_OUTRO = new StringSetting("sb_outro", MANUAL_SKIP.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color","#0202ED");
+ public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color", "#0202ED");
public static final StringSetting SB_CATEGORY_PREVIEW = new StringSetting("sb_preview", IGNORE.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color","#008FD6");
+ public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color", "#008FD6");
public static final StringSetting SB_CATEGORY_FILLER = new StringSetting("sb_filler", IGNORE.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color","#7300FF");
+ public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color", "#7300FF");
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC = new StringSetting("sb_music_offtopic", MANUAL_SKIP.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color","#FF9900");
+ public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color", "#FF9900");
public static final StringSetting SB_CATEGORY_UNSUBMITTED = new StringSetting("sb_unsubmitted", SKIP_AUTOMATICALLY.reVancedKeyValue);
- public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color","#FFFFFF");
+ public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color", "#FFFFFF");
+
+ // Deprecated migrations
+ public static final StringSetting DEPRECATED_SB_UUID_OLD_MIGRATION_SETTING = new StringSetting("uuid", ""); // Delete sometime in 2024
+ private static final BooleanSetting DEPRECATED_HIDE_PLAYER_BUTTONS = new BooleanSetting("revanced_hide_player_buttons", FALSE, true);
+ private static final BooleanSetting DEPRECATED_HIDE_PLAYER_FLYOUT_VIDEO_QUALITY_FOOTER = new BooleanSetting("revanced_hide_video_quality_menu_footer", FALSE);
static {
// region Migration
diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceAVCSpoofingPreference.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceAVCSpoofingPreference.java
index 5581756758..b3faebf8f9 100644
--- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceAVCSpoofingPreference.java
+++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/settings/preference/ForceAVCSpoofingPreference.java
@@ -1,7 +1,7 @@
package app.revanced.extension.youtube.settings.preference;
import static app.revanced.extension.shared.StringRef.str;
-import static app.revanced.extension.youtube.patches.spoof.DeviceHardwareSupport.DEVICE_HAS_HARDWARE_DECODING_VP9;
+import static app.revanced.extension.shared.spoof.DeviceHardwareSupport.DEVICE_HAS_HARDWARE_DECODING_VP9;
import android.content.Context;
import android.preference.SwitchPreference;
@@ -18,12 +18,15 @@ public class ForceAVCSpoofingPreference extends SwitchPreference {
public ForceAVCSpoofingPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
+
public ForceAVCSpoofingPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
+
public ForceAVCSpoofingPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
+
public ForceAVCSpoofingPreference(Context context) {
super(context);
}
diff --git a/patches/api/patches.api b/patches/api/patches.api
index 1c601b5515..5e6a8c8fe4 100644
--- a/patches/api/patches.api
+++ b/patches/api/patches.api
@@ -320,6 +320,10 @@ public final class app/revanced/patches/music/misc/gms/GmsCoreSupportPatchKt {
public static final fun getGmsCoreSupportPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
+public final class app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatchKt {
+ public static final fun getSpoofVideoStreamsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
+}
+
public final class app/revanced/patches/myexpenses/misc/pro/UnlockProPatchKt {
public static final fun getUnlockProPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@@ -753,6 +757,11 @@ public final class app/revanced/patches/shared/misc/settings/preference/TextPref
public fun serialize (Lorg/w3c/dom/Document;Lkotlin/jvm/functions/Function1;)Lorg/w3c/dom/Element;
}
+public final class app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatchKt {
+ public static final fun spoofVideoStreamsPatch (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lapp/revanced/patcher/patch/BytecodePatch;
+ public static synthetic fun spoofVideoStreamsPatch$default (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lapp/revanced/patcher/patch/BytecodePatch;
+}
+
public final class app/revanced/patches/solidexplorer2/functionality/filesize/RemoveFileSizeLimitPatchKt {
public static final fun getRemoveFileSizeLimitPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
@@ -1359,6 +1368,14 @@ public final class app/revanced/patches/youtube/misc/settings/SettingsPatchKt {
public static final fun newIntent (Ljava/lang/String;)Lapp/revanced/patches/shared/misc/settings/preference/IntentPreference$Intent;
}
+public final class app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatchKt {
+ public static final fun getSpoofVideoStreamsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
+}
+
+public final class app/revanced/patches/youtube/misc/spoof/UserAgentClientSpoofPatchKt {
+ public static final fun getUserAgentClientSpoofPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
+}
+
public final class app/revanced/patches/youtube/misc/zoomhaptics/ZoomHapticsPatchKt {
public static final fun getZoomHapticsPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt
index e38ca6015c..0fa223b235 100644
--- a/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/GmsCoreSupportPatch.kt
@@ -4,6 +4,7 @@ import app.revanced.patcher.patch.Option
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME
import app.revanced.patches.music.misc.gms.Constants.REVANCED_MUSIC_PACKAGE_NAME
+import app.revanced.patches.music.misc.spoof.spoofVideoStreamsPatch
import app.revanced.patches.shared.castContextFetchFingerprint
import app.revanced.patches.shared.misc.gms.gmsCoreSupportPatch
import app.revanced.patches.shared.primeMethodFingerprint
@@ -20,6 +21,8 @@ val gmsCoreSupportPatch = gmsCoreSupportPatch(
extensionPatch = sharedExtensionPatch,
gmsCoreSupportResourcePatchFactory = ::gmsCoreSupportResourcePatch,
) {
+ dependsOn(spoofVideoStreamsPatch)
+
compatibleWith(MUSIC_PACKAGE_NAME)
}
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
new file mode 100644
index 0000000000..862bc3f227
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/spoof/SpoofVideoStreamsPatch.kt
@@ -0,0 +1,7 @@
+package app.revanced.patches.music.misc.spoof
+
+import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch
+
+val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
+ compatibleWith("com.google.android.apps.youtube.music")
+})
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt
similarity index 97%
rename from patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/Fingerprints.kt
rename to patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt
index 1862a79aa8..3976d03e7e 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/Fingerprints.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/Fingerprints.kt
@@ -1,4 +1,4 @@
-package app.revanced.patches.youtube.misc.fix.playback
+package app.revanced.patches.shared.misc.spoof
import app.revanced.patcher.fingerprint
import com.android.tools.smali.dexlib2.AccessFlags
@@ -27,7 +27,6 @@ internal val buildPlayerRequestURIFingerprint = fingerprint {
Opcode.RETURN_OBJECT,
)
strings(
- "youtubei/v1",
"key",
"asig",
)
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
new file mode 100644
index 0000000000..0e9e831261
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt
@@ -0,0 +1,206 @@
+package app.revanced.patches.shared.misc.spoof
+
+import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
+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.patch.BytecodePatchBuilder
+import app.revanced.patcher.patch.BytecodePatchContext
+import app.revanced.patcher.patch.bytecodePatch
+import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
+import app.revanced.patches.all.misc.resources.addResourcesPatch
+import app.revanced.util.getReference
+import app.revanced.util.indexOfFirstInstructionOrThrow
+import com.android.tools.smali.dexlib2.AccessFlags
+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.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
+
+private const val EXTENSION_CLASS_DESCRIPTOR =
+ "Lapp/revanced/extension/shared/spoof/SpoofVideoStreamsPatch;"
+
+fun spoofVideoStreamsPatch(
+ block: BytecodePatchBuilder.() -> Unit = {},
+ executeBlock: BytecodePatchContext.() -> Unit = {},
+) = bytecodePatch(
+ name = "Spoof video streams",
+ description = "Spoofs the client video streams to fix playback.",
+) {
+ block()
+
+ dependsOn(addResourcesPatch)
+
+ execute {
+ // region Block /initplayback requests to fall back to /get_watch requests.
+
+ val moveUriStringIndex = buildInitPlaybackRequestFingerprint.patternMatch!!.startIndex
+
+ buildInitPlaybackRequestFingerprint.method.apply {
+ val targetRegister = getInstruction(moveUriStringIndex).registerA
+
+ addInstructions(
+ moveUriStringIndex + 1,
+ """
+ invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
+ move-result-object v$targetRegister
+ """,
+ )
+ }
+
+ // endregion
+
+ // region Block /get_watch requests to fall back to /player requests.
+
+ val invokeToStringIndex = buildPlayerRequestURIFingerprint.patternMatch!!.startIndex
+
+ buildPlayerRequestURIFingerprint.method.apply {
+ val uriRegister = getInstruction(invokeToStringIndex).registerC
+
+ addInstructions(
+ invokeToStringIndex,
+ """
+ invoke-static { v$uriRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
+ move-result-object v$uriRegister
+ """,
+ )
+ }
+
+ // endregion
+
+ // 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 = getInstruction(newRequestBuilderIndex + 1).registerA
+
+ addInstructions(
+ newRequestBuilderIndex,
+ """
+ move-object v$freeRegister, p1
+ invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
+ """,
+ )
+ }
+
+ // endregion
+
+ // region Replace the streaming data with the replacement streams.
+
+ createStreamingDataFingerprint.method.apply {
+ val setStreamDataMethodName = "patch_setStreamingData"
+ val resultMethodType = createStreamingDataFingerprint.classDef.type
+ val videoDetailsIndex = createStreamingDataFingerprint.patternMatch!!.endIndex
+ val videoDetailsRegister = getInstruction(videoDetailsIndex).registerA
+ val videoDetailsClass = getInstruction(videoDetailsIndex).getReference()!!.type
+
+ addInstruction(
+ videoDetailsIndex + 1,
+ "invoke-direct { p0, v$videoDetailsRegister }, " +
+ "$resultMethodType->$setStreamDataMethodName($videoDetailsClass)V",
+ )
+
+ val protobufClass = protobufClassParseByteBufferFingerprint.method.definingClass
+ val setStreamingDataIndex = createStreamingDataFingerprint.patternMatch!!.startIndex
+
+ val playerProtoClass = getInstruction(setStreamingDataIndex + 1)
+ .getReference()!!.definingClass
+
+ val setStreamingDataField = getInstruction(setStreamingDataIndex).getReference()
+
+ val getStreamingDataField = getInstruction(
+ indexOfFirstInstructionOrThrow {
+ opcode == Opcode.IGET_OBJECT && getReference()?.definingClass == playerProtoClass
+ },
+ ).getReference()
+
+ // Use a helper method to avoid the need of picking out multiple free registers from the hooked code.
+ createStreamingDataFingerprint.classDef.methods.add(
+ ImmutableMethod(
+ resultMethodType,
+ setStreamDataMethodName,
+ listOf(ImmutableMethodParameter(videoDetailsClass, null, "videoDetails")),
+ "V",
+ AccessFlags.PRIVATE.value or AccessFlags.FINAL.value,
+ null,
+ null,
+ MutableMethodImplementation(9),
+ ).toMutable().apply {
+ addInstructionsWithLabels(
+ 0,
+ """
+ invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->isSpoofingEnabled()Z
+ move-result v0
+ if-eqz v0, :disabled
+
+ # Get video id.
+ iget-object v2, p1, $videoDetailsClass->c:Ljava/lang/String;
+ if-eqz v2, :disabled
+
+ # Get streaming data.
+ invoke-static { v2 }, $EXTENSION_CLASS_DESCRIPTOR->getStreamingData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
+ move-result-object v3
+ if-eqz v3, :disabled
+
+ # Parse streaming data.
+ sget-object v4, $playerProtoClass->a:$playerProtoClass
+ invoke-static { v4, v3 }, $protobufClass->parseFrom(${protobufClass}Ljava/nio/ByteBuffer;)$protobufClass
+ move-result-object v5
+ check-cast v5, $playerProtoClass
+
+ # Set streaming data.
+ iget-object v6, v5, $getStreamingDataField
+ if-eqz v6, :disabled
+ iput-object v6, p0, $setStreamingDataField
+
+ :disabled
+ return-void
+ """,
+ )
+ },
+ )
+ }
+
+ // 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.
+ // A proper fix may include modifying the request body to match the platforms expected body.
+
+ buildMediaDataSourceFingerprint.method.apply {
+ val targetIndex = instructions.lastIndex
+
+ // Instructions are added just before the method returns,
+ // so there's no concern of clobbering in-use registers.
+ addInstructions(
+ targetIndex,
+ """
+ # Field a: Stream uri.
+ # Field c: Http method.
+ # Field d: Post data.
+ move-object v0, p0 # method has over 15 registers and must copy p0 to a lower register.
+ iget-object v1, v0, $definingClass->a:Landroid/net/Uri;
+ iget v2, v0, $definingClass->c:I
+ iget-object v3, v0, $definingClass->d:[B
+ invoke-static { v1, v2, v3 }, $EXTENSION_CLASS_DESCRIPTOR->removeVideoPlaybackPostBody(Landroid/net/Uri;I[B)[B
+ move-result-object v1
+ iput-object v1, v0, $definingClass->d:[B
+ """,
+ )
+ }
+ // endregion
+
+ executeBlock()
+ }
+}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatch.kt
index 515536b8f5..89e7cc08f8 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/SpoofVideoStreamsPatch.kt
@@ -1,243 +1,9 @@
package app.revanced.patches.youtube.misc.fix.playback
-import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
-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.patch.bytecodePatch
-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
-import app.revanced.patches.shared.misc.settings.preference.ListPreference
-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.SwitchPreference
-import app.revanced.patches.youtube.misc.settings.PreferenceScreen
-import app.revanced.patches.youtube.misc.settings.settingsPatch
-import app.revanced.util.getReference
-import app.revanced.util.indexOfFirstInstructionOrThrow
-import com.android.tools.smali.dexlib2.AccessFlags
-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.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
-private const val EXTENSION_CLASS_DESCRIPTOR =
- "Lapp/revanced/extension/youtube/patches/spoof/SpoofVideoStreamsPatch;"
-
-val spoofVideoStreamsPatch = bytecodePatch(
- name = "Spoof video streams",
- description = "Spoofs the client video streams to allow video playback.",
-) {
- compatibleWith(
- "com.google.android.youtube"(
- "18.38.44",
- "18.49.37",
- "19.16.39",
- "19.25.37",
- "19.34.42",
- "19.43.41",
- "19.45.38",
- "19.46.42",
- ),
- )
-
- dependsOn(
- settingsPatch,
- addResourcesPatch,
- userAgentClientSpoofPatch,
- )
-
- execute {
- addResources("youtube", "misc.fix.playback.spoofVideoStreamsPatch")
-
- PreferenceScreen.MISC.addPreferences(
- PreferenceScreenPreference(
- key = "revanced_spoof_video_streams_screen",
- sorting = PreferenceScreenPreference.Sorting.UNSORTED,
- preferences = setOf(
- SwitchPreference("revanced_spoof_video_streams"),
- ListPreference(
- "revanced_spoof_video_streams_client",
- summaryKey = null,
- ),
- SwitchPreference(
- "revanced_spoof_video_streams_ios_force_avc",
- tag = "app.revanced.extension.youtube.settings.preference.ForceAVCSpoofingPreference",
- ),
- NonInteractivePreference("revanced_spoof_video_streams_about_android_vr"),
- NonInteractivePreference("revanced_spoof_video_streams_about_ios"),
- ),
- ),
- )
-
- // region Block /initplayback requests to fall back to /get_watch requests.
-
- val moveUriStringIndex = buildInitPlaybackRequestFingerprint.patternMatch!!.startIndex
-
- buildInitPlaybackRequestFingerprint.method.apply {
- val targetRegister = getInstruction(moveUriStringIndex).registerA
-
- addInstructions(
- moveUriStringIndex + 1,
- """
- invoke-static { v$targetRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockInitPlaybackRequest(Ljava/lang/String;)Ljava/lang/String;
- move-result-object v$targetRegister
- """,
- )
- }
-
- // endregion
-
- // region Block /get_watch requests to fall back to /player requests.
-
- val invokeToStringIndex = buildPlayerRequestURIFingerprint.patternMatch!!.startIndex
-
- buildPlayerRequestURIFingerprint.method.apply {
- val uriRegister = getInstruction(invokeToStringIndex).registerC
-
- addInstructions(
- invokeToStringIndex,
- """
- invoke-static { v$uriRegister }, $EXTENSION_CLASS_DESCRIPTOR->blockGetWatchRequest(Landroid/net/Uri;)Landroid/net/Uri;
- move-result-object v$uriRegister
- """,
- )
- }
-
- // endregion
-
- // 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 = getInstruction(newRequestBuilderIndex + 1).registerA
-
- addInstructions(
- newRequestBuilderIndex,
- """
- move-object v$freeRegister, p1
- invoke-static { v$urlRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->fetchStreams(Ljava/lang/String;Ljava/util/Map;)V
- """,
- )
- }
-
- // endregion
-
- // region Replace the streaming data with the replacement streams.
-
- createStreamingDataFingerprint.method.apply {
- val setStreamDataMethodName = "patch_setStreamingData"
- val resultMethodType = createStreamingDataFingerprint.classDef.type
- val videoDetailsIndex = createStreamingDataFingerprint.patternMatch!!.endIndex
- val videoDetailsRegister = getInstruction(videoDetailsIndex).registerA
- val videoDetailsClass = getInstruction(videoDetailsIndex).getReference()!!.type
-
- addInstruction(
- videoDetailsIndex + 1,
- "invoke-direct { p0, v$videoDetailsRegister }, " +
- "$resultMethodType->$setStreamDataMethodName($videoDetailsClass)V",
- )
-
- val protobufClass = protobufClassParseByteBufferFingerprint.method.definingClass
- val setStreamingDataIndex = createStreamingDataFingerprint.patternMatch!!.startIndex
-
- val playerProtoClass = getInstruction(setStreamingDataIndex + 1)
- .getReference()!!.definingClass
-
- val setStreamingDataField = getInstruction(setStreamingDataIndex).getReference()
-
- val getStreamingDataField = getInstruction(
- indexOfFirstInstructionOrThrow {
- opcode == Opcode.IGET_OBJECT && getReference()?.definingClass == playerProtoClass
- },
- ).getReference()
-
- // Use a helper method to avoid the need of picking out multiple free registers from the hooked code.
- createStreamingDataFingerprint.classDef.methods.add(
- ImmutableMethod(
- resultMethodType,
- setStreamDataMethodName,
- listOf(ImmutableMethodParameter(videoDetailsClass, null, "videoDetails")),
- "V",
- AccessFlags.PRIVATE.value or AccessFlags.FINAL.value,
- null,
- null,
- MutableMethodImplementation(9),
- ).toMutable().apply {
- addInstructionsWithLabels(
- 0,
- """
- invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->isSpoofingEnabled()Z
- move-result v0
- if-eqz v0, :disabled
-
- # Get video id.
- iget-object v2, p1, $videoDetailsClass->c:Ljava/lang/String;
- if-eqz v2, :disabled
-
- # Get streaming data.
- invoke-static { v2 }, $EXTENSION_CLASS_DESCRIPTOR->getStreamingData(Ljava/lang/String;)Ljava/nio/ByteBuffer;
- move-result-object v3
- if-eqz v3, :disabled
-
- # Parse streaming data.
- sget-object v4, $playerProtoClass->a:$playerProtoClass
- invoke-static { v4, v3 }, $protobufClass->parseFrom(${protobufClass}Ljava/nio/ByteBuffer;)$protobufClass
- move-result-object v5
- check-cast v5, $playerProtoClass
-
- # Set streaming data.
- iget-object v6, v5, $getStreamingDataField
- if-eqz v6, :disabled
- iput-object v6, p0, $setStreamingDataField
-
- :disabled
- return-void
- """,
- )
- },
- )
- }
-
- // 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.
- // A proper fix may include modifying the request body to match the platforms expected body.
-
- buildMediaDataSourceFingerprint.method.apply {
- val targetIndex = instructions.lastIndex
-
- // Instructions are added just before the method returns,
- // so there's no concern of clobbering in-use registers.
- addInstructions(
- targetIndex,
- """
- # Field a: Stream uri.
- # Field c: Http method.
- # Field d: Post data.
- move-object v0, p0 # method has over 15 registers and must copy p0 to a lower register.
- iget-object v1, v0, $definingClass->a:Landroid/net/Uri;
- iget v2, v0, $definingClass->c:I
- iget-object v3, v0, $definingClass->d:[B
- invoke-static { v1, v2, v3 }, $EXTENSION_CLASS_DESCRIPTOR->removeVideoPlaybackPostBody(Landroid/net/Uri;I[B)[B
- move-result-object v1
- iput-object v1, v0, $definingClass->d:[B
- """,
- )
- }
- // endregion
- }
+@Deprecated("Use app.revanced.patches.youtube.misc.spoof.spoofVideoStreamsPatch instead.")
+@Suppress("unused")
+val spoofVideoStreamsPatch = bytecodePatch {
+ dependsOn(app.revanced.patches.youtube.misc.spoof.spoofVideoStreamsPatch)
}
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt
index 8bbd0ec778..eb4c9492be 100644
--- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playback/UserAgentClientSpoofPatch.kt
@@ -1,82 +1,9 @@
package app.revanced.patches.youtube.misc.fix.playback
-import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
-import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
-import app.revanced.patches.all.misc.transformation.IMethodCall
-import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
-import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
-import app.revanced.util.getReference
-import app.revanced.util.indexOfFirstInstruction
-import com.android.tools.smali.dexlib2.Opcode
-import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
-import com.android.tools.smali.dexlib2.iface.reference.MethodReference
-import com.android.tools.smali.dexlib2.iface.reference.StringReference
-
-private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube"
-private const val USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE =
- "Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;"
-
-val userAgentClientSpoofPatch = transformInstructionsPatch(
- filterMap = { classDef, _, instruction, instructionIndex ->
- filterMapInstruction35c(
- "Lapp/revanced/extension",
- classDef,
- instruction,
- instructionIndex,
- )
- },
- transform = transform@{ mutableMethod, entry ->
- val (_, _, instructionIndex) = entry
-
- // Replace the result of context.getPackageName(), if it is used in a user agent string.
- mutableMethod.apply {
- // After context.getPackageName() the result is moved to a register.
- val targetRegister = (
- getInstruction(instructionIndex + 1)
- as? OneRegisterInstruction ?: return@transform
- ).registerA
-
- // IndexOutOfBoundsException is technically possible here,
- // but no such occurrences are present in the app.
- val referee = getInstruction(instructionIndex + 2).getReference()?.toString()
-
- // Only replace string builder usage.
- if (referee != USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE) {
- return@transform
- }
-
- // Do not change the package name in methods that use resources, or for methods that use GmsCore.
- // Changing these package names will result in playback limitations,
- // particularly Android VR background audio only playback.
- val resourceOrGmsStringInstructionIndex = indexOfFirstInstruction {
- val reference = getReference()
- opcode == Opcode.CONST_STRING &&
- (reference?.string == "android.resource://" || reference?.string == "gcore_")
- }
- if (resourceOrGmsStringInstructionIndex >= 0) {
- return@transform
- }
-
- // Overwrite the result of context.getPackageName() with the original package name.
- replaceInstruction(
- instructionIndex + 1,
- "const-string v$targetRegister, \"$ORIGINAL_PACKAGE_NAME\"",
- )
- }
- },
-)
+import app.revanced.patcher.patch.bytecodePatch
+@Deprecated("Use app.revanced.patches.youtube.misc.spoof.userAgentClientSpoofPatch instead.")
@Suppress("unused")
-private enum class MethodCall(
- override val definedClassName: String,
- override val methodName: String,
- override val methodParams: Array,
- override val returnType: String,
-) : IMethodCall {
- GetPackageName(
- "Landroid/content/Context;",
- "getPackageName",
- emptyArray(),
- "Ljava/lang/String;",
- ),
+val userAgentClientSpoofPatch = bytecodePatch {
+ dependsOn(app.revanced.patches.youtube.misc.spoof.userAgentClientSpoofPatch)
}
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 bb86b663f9..dc73116ebf 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
@@ -9,11 +9,11 @@ import app.revanced.patches.shared.misc.settings.preference.IntentPreference
import app.revanced.patches.shared.primeMethodFingerprint
import app.revanced.patches.youtube.layout.buttons.overlay.hidePlayerOverlayButtonsPatch
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
-import app.revanced.patches.youtube.misc.fix.playback.spoofVideoStreamsPatch
import app.revanced.patches.youtube.misc.gms.Constants.REVANCED_YOUTUBE_PACKAGE_NAME
import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
import app.revanced.patches.youtube.misc.settings.settingsPatch
+import app.revanced.patches.youtube.misc.spoof.spoofVideoStreamsPatch
import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint
@Suppress("unused")
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
new file mode 100644
index 0000000000..a6181db7e4
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/SpoofVideoStreamsPatch.kt
@@ -0,0 +1,52 @@
+package app.revanced.patches.youtube.misc.spoof
+
+import app.revanced.patches.all.misc.resources.addResources
+import app.revanced.patches.shared.misc.settings.preference.ListPreference
+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.SwitchPreference
+import app.revanced.patches.shared.misc.spoof.spoofVideoStreamsPatch
+import app.revanced.patches.youtube.misc.settings.PreferenceScreen
+import app.revanced.patches.youtube.misc.settings.settingsPatch
+
+val spoofVideoStreamsPatch = spoofVideoStreamsPatch({
+ compatibleWith(
+ "com.google.android.youtube"(
+ "18.38.44",
+ "18.49.37",
+ "19.16.39",
+ "19.25.37",
+ "19.34.42",
+ "19.43.41",
+ "19.45.38",
+ "19.46.42",
+ ),
+ )
+
+ dependsOn(
+ userAgentClientSpoofPatch,
+ settingsPatch,
+ )
+}, {
+ addResources("youtube", "misc.fix.playback.spoofVideoStreamsPatch")
+
+ PreferenceScreen.MISC.addPreferences(
+ PreferenceScreenPreference(
+ key = "revanced_spoof_video_streams_screen",
+ sorting = PreferenceScreenPreference.Sorting.UNSORTED,
+ preferences = setOf(
+ SwitchPreference("revanced_spoof_video_streams"),
+ ListPreference(
+ "revanced_spoof_video_streams_client",
+ summaryKey = null,
+ ),
+ SwitchPreference(
+ "revanced_spoof_video_streams_ios_force_avc",
+ tag = "app.revanced.extension.youtube.settings.preference.ForceAVCSpoofingPreference",
+ ),
+ NonInteractivePreference("revanced_spoof_video_streams_about_android_vr"),
+ NonInteractivePreference("revanced_spoof_video_streams_about_ios"),
+ ),
+ ),
+ )
+})
diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/UserAgentClientSpoofPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/UserAgentClientSpoofPatch.kt
new file mode 100644
index 0000000000..d9b6596138
--- /dev/null
+++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/spoof/UserAgentClientSpoofPatch.kt
@@ -0,0 +1,82 @@
+package app.revanced.patches.youtube.misc.spoof
+
+import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
+import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
+import app.revanced.patches.all.misc.transformation.IMethodCall
+import app.revanced.patches.all.misc.transformation.filterMapInstruction35c
+import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
+import app.revanced.util.getReference
+import app.revanced.util.indexOfFirstInstruction
+import com.android.tools.smali.dexlib2.Opcode
+import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
+import com.android.tools.smali.dexlib2.iface.reference.MethodReference
+import com.android.tools.smali.dexlib2.iface.reference.StringReference
+
+private const val ORIGINAL_PACKAGE_NAME = "com.google.android.youtube"
+private const val USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE =
+ "Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;"
+
+val userAgentClientSpoofPatch = transformInstructionsPatch(
+ filterMap = { classDef, _, instruction, instructionIndex ->
+ filterMapInstruction35c(
+ "Lapp/revanced/extension",
+ classDef,
+ instruction,
+ instructionIndex,
+ )
+ },
+ transform = transform@{ mutableMethod, entry ->
+ val (_, _, instructionIndex) = entry
+
+ // Replace the result of context.getPackageName(), if it is used in a user agent string.
+ mutableMethod.apply {
+ // After context.getPackageName() the result is moved to a register.
+ val targetRegister = (
+ getInstruction(instructionIndex + 1)
+ as? OneRegisterInstruction ?: return@transform
+ ).registerA
+
+ // IndexOutOfBoundsException is technically possible here,
+ // but no such occurrences are present in the app.
+ val referee = getInstruction(instructionIndex + 2).getReference()?.toString()
+
+ // Only replace string builder usage.
+ if (referee != USER_AGENT_STRING_BUILDER_APPEND_METHOD_REFERENCE) {
+ return@transform
+ }
+
+ // Do not change the package name in methods that use resources, or for methods that use GmsCore.
+ // Changing these package names will result in playback limitations,
+ // particularly Android VR background audio only playback.
+ val resourceOrGmsStringInstructionIndex = indexOfFirstInstruction {
+ val reference = getReference()
+ opcode == Opcode.CONST_STRING &&
+ (reference?.string == "android.resource://" || reference?.string == "gcore_")
+ }
+ if (resourceOrGmsStringInstructionIndex >= 0) {
+ return@transform
+ }
+
+ // Overwrite the result of context.getPackageName() with the original package name.
+ replaceInstruction(
+ instructionIndex + 1,
+ "const-string v$targetRegister, \"$ORIGINAL_PACKAGE_NAME\"",
+ )
+ }
+ },
+)
+
+@Suppress("unused")
+private enum class MethodCall(
+ override val definedClassName: String,
+ override val methodName: String,
+ override val methodParams: Array,
+ override val returnType: String,
+) : IMethodCall {
+ GetPackageName(
+ "Landroid/content/Context;",
+ "getPackageName",
+ emptyArray(),
+ "Ljava/lang/String;",
+ ),
+}