From f7109f98151911604d3a2f83dc41c81863e146ae Mon Sep 17 00:00:00 2001 From: ILoveOpenSourceApplications <117499019+ILoveOpenSourceApplications@users.noreply.github.com> Date: Mon, 27 Jan 2025 15:23:27 +0530 Subject: [PATCH] feat(YouTube Music - Change start page): Add more start pages (#135) * feat(YouTube Music - Change start page): Add more start pages * Add more start pages * feat: Switch to `EnumSetting`, Add `Default`, `Samples` and `Search`, Remove `Home` --------- Co-authored-by: ILoveOpenSourceApplications Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com> --- .../patches/general/ChangeStartPagePatch.java | 115 ++++++++++++++++++ .../music/patches/general/GeneralPatch.java | 11 -- .../extension/music/settings/Settings.java | 3 +- .../ReVancedPreferenceFragment.java | 7 +- .../general/startpage/ChangeStartPagePatch.kt | 13 +- .../music/general/startpage/Fingerprints.kt | 16 ++- .../music/settings/host/values/arrays.xml | 28 +++-- .../music/settings/host/values/strings.xml | 12 +- 8 files changed, 175 insertions(+), 30 deletions(-) create mode 100644 extensions/shared/src/main/java/app/revanced/extension/music/patches/general/ChangeStartPagePatch.java diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/ChangeStartPagePatch.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/ChangeStartPagePatch.java new file mode 100644 index 000000000..d837c8827 --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/ChangeStartPagePatch.java @@ -0,0 +1,115 @@ +package app.revanced.extension.music.patches.general; + +import android.app.Activity; +import android.content.Intent; + +import androidx.annotation.NonNull; + +import org.apache.commons.lang3.StringUtils; + +import app.revanced.extension.music.settings.Settings; +import app.revanced.extension.shared.utils.Logger; +import app.revanced.extension.shared.utils.ResourceUtils; + +@SuppressWarnings("unused") +public final class ChangeStartPagePatch { + + public enum StartPage { + /** + * Unmodified type, and same as un-patched. + */ + ORIGINAL(""), + + /** + * Browse id. + */ + CHARTS("FEmusic_charts"), + EXPLORE("FEmusic_explore"), + HISTORY("FEmusic_history"), + LIBRARY("FEmusic_library_landing"), + PODCASTS("FEmusic_non_music_audio"), + SAMPLES("FEmusic_immersive"), + SUBSCRIPTIONS("FEmusic_library_corpus_artists"), + + /** + * Playlist id, this can be used as a browseId. + */ + EPISODES_FOR_LATER("VLSE"), + LIKED_MUSIC("VLLM"), + + /** + * Intent extra. + */ + SEARCH("", 1, "Eh4IBRDTnQEYmgMiEwiZn+H0r5WLAxVV5OcDHcHRBmPqpd25AQA="); + + @NonNull + final String browseId; + + final int shortcutType; + + /** + * Unique identifier for shortcut (Base64). + */ + @NonNull + final String shortcutId; + + StartPage(@NonNull String browseId) { + this(browseId, 0, ""); + } + + StartPage(@NonNull String browseId, int shortcutType, @NonNull String shortcutId) { + this.browseId = browseId; + this.shortcutType = shortcutType; + this.shortcutId = shortcutId; + } + } + + /** + * Intent action when YouTube is cold started from the launcher. + */ + private static final String ACTION_MAIN = "android.intent.action.MAIN"; + + private static final String SHORTCUT_ACTION = "com.google.android.youtube.music.action.shortcut"; + + private static final String SHORTCUT_CLASS_DESCRIPTOR = "com.google.android.apps.youtube.music.activities.InternalMusicActivity"; + + private static final String SHORTCUT_TYPE = "com.google.android.youtube.music.action.shortcut_type"; + + private static final StartPage START_PAGE = Settings.CHANGE_START_PAGE.get(); + + public static String overrideBrowseId(@NonNull String browseId) { + if (!browseId.equals("FEmusic_home")) { + return browseId; + } + final String overrideBrowseId = START_PAGE.browseId; + if (overrideBrowseId.isEmpty()) { + return browseId; + } + + Logger.printDebug(() -> "Changing browseId to " + START_PAGE.name()); + return overrideBrowseId; + } + + public static void overrideIntent(@NonNull Intent intent) { + if (!StringUtils.equals(intent.getAction(), ACTION_MAIN)) { + Logger.printDebug(() -> "Ignore override intent action" + + " as the current activity is not the entry point of the application"); + return; + } + final String overrideShortcutId = START_PAGE.shortcutId; + if (overrideShortcutId.isEmpty()) { + return; + } + Activity mActivity = ResourceUtils.getActivity(); + if (mActivity == null) { + return; + } + + Logger.printDebug(() -> "Changing intent action to " + START_PAGE.name()); + intent.setAction(SHORTCUT_ACTION); + intent.setClassName(mActivity, SHORTCUT_CLASS_DESCRIPTOR); + intent.setPackage(mActivity.getPackageName()); + intent.putExtra(SHORTCUT_TYPE, START_PAGE.shortcutType); + intent.putExtra(SHORTCUT_ACTION, overrideShortcutId); + } +} diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/GeneralPatch.java b/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/GeneralPatch.java index 3e0dd7afc..b47d82dd1 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/GeneralPatch.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/patches/general/GeneralPatch.java @@ -32,17 +32,6 @@ public class GeneralPatch { // endregion - // region [Change start page] patch - - public static String changeStartPage(final String browseId) { - if (!browseId.equals("FEmusic_home")) - return browseId; - - return Settings.CHANGE_START_PAGE.get(); - } - - // endregion - // region [Disable dislike redirection] patch public static boolean disableDislikeRedirection() { diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java b/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java index 43da6f9c4..175960cca 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/settings/Settings.java @@ -6,6 +6,7 @@ import static app.revanced.extension.music.sponsorblock.objects.CategoryBehaviou import androidx.annotation.NonNull; +import app.revanced.extension.music.patches.general.ChangeStartPagePatch.StartPage; import app.revanced.extension.music.patches.misc.AlbumMusicVideoPatch.RedirectType; import app.revanced.extension.music.patches.misc.client.AppClient.ClientType; import app.revanced.extension.music.patches.utils.PatchStatus; @@ -91,7 +92,7 @@ public class Settings extends BaseSettings { // PreferenceScreen: General - public static final StringSetting CHANGE_START_PAGE = new StringSetting("revanced_change_start_page", "FEmusic_home", true); + public static final EnumSetting CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.ORIGINAL, true); public static final BooleanSetting DISABLE_DISLIKE_REDIRECTION = new BooleanSetting("revanced_disable_dislike_redirection", FALSE); public static final BooleanSetting ENABLE_LANDSCAPE_MODE = new BooleanSetting("revanced_enable_landscape_mode", FALSE, true); public static final BooleanSetting CUSTOM_FILTER = new BooleanSetting("revanced_custom_filter", FALSE); diff --git a/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java b/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java index 67c442d04..ba0316daa 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java +++ b/extensions/shared/src/main/java/app/revanced/extension/music/settings/preference/ReVancedPreferenceFragment.java @@ -136,9 +136,7 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { final Setting settings = getSettingFromPath(dataString); if (settings instanceof StringSetting stringSetting) { - if (settings.equals(CHANGE_START_PAGE)) { - ResettableListPreference.showDialog(mActivity, stringSetting, 2); - } else if (settings.equals(BYPASS_IMAGE_REGION_RESTRICTIONS_DOMAIN) + if (settings.equals(BYPASS_IMAGE_REGION_RESTRICTIONS_DOMAIN) || settings.equals(CUSTOM_FILTER_STRINGS) || settings.equals(CUSTOM_PLAYBACK_SPEEDS) || settings.equals(ENABLE_CUSTOM_NAVIGATION_BAR_COLOR_VALUE) @@ -163,7 +161,8 @@ public class ReVancedPreferenceFragment extends PreferenceFragment { Logger.printDebug(() -> "Failed to find the right value: " + dataString); } } else if (settings instanceof EnumSetting enumSetting) { - if (settings.equals(DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE) + if (settings.equals(CHANGE_START_PAGE) + || settings.equals(DISABLE_MUSIC_VIDEO_IN_ALBUM_REDIRECT_TYPE) || settings.equals(RETURN_YOUTUBE_USERNAME_DISPLAY_FORMAT) || settings.equals(SPOOF_CLIENT_TYPE) || settings.equals(SPOOF_STREAMING_DATA_TYPE) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt index d9d81d9e0..92aa964c8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/ChangeStartPagePatch.kt @@ -1,10 +1,11 @@ package app.revanced.patches.music.general.startpage +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patches.music.utils.compatibility.Constants.COMPATIBLE_PACKAGE -import app.revanced.patches.music.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR +import app.revanced.patches.music.utils.extension.Constants.GENERAL_PATH import app.revanced.patches.music.utils.patch.PatchList.CHANGE_START_PAGE import app.revanced.patches.music.utils.settings.CategoryType import app.revanced.patches.music.utils.settings.ResourceUtils.updatePatchStatus @@ -18,6 +19,9 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference +private const val EXTENSION_CLASS_DESCRIPTOR = + "$GENERAL_PATH/ChangeStartPagePatch;" + @Suppress("unused") val changeStartPagePatch = bytecodePatch( CHANGE_START_PAGE.title, @@ -29,6 +33,11 @@ val changeStartPagePatch = bytecodePatch( execute { + coldStartIntentFingerprint.methodOrThrow().addInstruction( + 0, + "invoke-static {p1}, $EXTENSION_CLASS_DESCRIPTOR->overrideIntent(Landroid/content/Intent;)V" + ) + coldStartUpFingerprint.methodOrThrow().apply { val defaultBrowseIdIndex = indexOfFirstStringInstructionOrThrow(DEFAULT_BROWSE_ID) val browseIdIndex = indexOfFirstInstructionReversedOrThrow(defaultBrowseIdIndex) { @@ -39,7 +48,7 @@ val changeStartPagePatch = bytecodePatch( addInstructions( browseIdIndex + 1, """ - invoke-static {v$browseIdRegister}, $GENERAL_CLASS_DESCRIPTOR->changeStartPage(Ljava/lang/String;)Ljava/lang/String; + invoke-static {v$browseIdRegister}, $EXTENSION_CLASS_DESCRIPTOR->overrideBrowseId(Ljava/lang/String;)Ljava/lang/String; move-result-object v$browseIdRegister """ ) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt index 9da6c2b7e..136443f6b 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/general/startpage/Fingerprints.kt @@ -7,6 +7,17 @@ import com.android.tools.smali.dexlib2.Opcode const val DEFAULT_BROWSE_ID = "FEmusic_home" +internal val coldStartIntentFingerprint = legacyFingerprint( + name = "coldStartIntentFingerprint", + returnType = "L", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("Landroid/content/Intent;"), + strings = listOf( + "android.intent.action.SEARCH", + "com.google.android.youtube.music.action.shortcut_type", + ) +) + internal val coldStartUpFingerprint = legacyFingerprint( name = "coldStartUpFingerprint", returnType = "Ljava/lang/String;", @@ -16,6 +27,9 @@ internal val coldStartUpFingerprint = legacyFingerprint( Opcode.CONST_STRING, Opcode.RETURN_OBJECT ), - strings = listOf("FEmusic_library_sideloaded_tracks", DEFAULT_BROWSE_ID) + strings = listOf( + "FEmusic_library_sideloaded_tracks", + DEFAULT_BROWSE_ID + ) ) diff --git a/patches/src/main/resources/music/settings/host/values/arrays.xml b/patches/src/main/resources/music/settings/host/values/arrays.xml index c1adaccde..ad61d6c32 100644 --- a/patches/src/main/resources/music/settings/host/values/arrays.xml +++ b/patches/src/main/resources/music/settings/host/values/arrays.xml @@ -1,18 +1,30 @@ - @string/revanced_change_start_page_entry_chart + @string/revanced_change_start_page_entry_default + @string/revanced_change_start_page_entry_charts + @string/revanced_change_start_page_entry_episodes_for_later @string/revanced_change_start_page_entry_explore - @string/revanced_change_start_page_entry_home + @string/revanced_change_start_page_entry_history @string/revanced_change_start_page_entry_library - @string/revanced_change_start_page_entry_subscription + @string/revanced_change_start_page_entry_liked_music + @string/revanced_change_start_page_entry_podcasts + @string/revanced_change_start_page_entry_samples + @string/revanced_change_start_page_entry_search + @string/revanced_change_start_page_entry_subscriptions - FEmusic_charts - FEmusic_explore - FEmusic_home - FEmusic_library_landing - FEmusic_library_corpus_artists + ORIGINAL + CHARTS + EPISODES_FOR_LATER + EXPLORE + HISTORY + LIBRARY + LIKED_MUSIC + PODCASTS + SAMPLES + SEARCH + SUBSCRIPTIONS @string/revanced_disable_music_video_in_album_redirect_type_entry_redirect diff --git a/patches/src/main/resources/music/settings/host/values/strings.xml b/patches/src/main/resources/music/settings/host/values/strings.xml index 4b7216254..002e56489 100644 --- a/patches/src/main/resources/music/settings/host/values/strings.xml +++ b/patches/src/main/resources/music/settings/host/values/strings.xml @@ -138,11 +138,17 @@ Limitations: Change start page Select which page the app opens in. - Charts + Default + Charts + Episodes for Later Explore - Home + History Library - Subscriptions + Liked Music + Podcasts + Samples + Search + Subscriptions Disable dislike redirection Disables redirection to the next track when clicking the Dislike button. Disable forced auto captions