From 5255c7eca8fa646f565e6cc9eb9b9ba3cb33f41f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ho=C3=A0ng=20Gia=20B=E1=BA=A3o?= <70064328+YT-Advanced@users.noreply.github.com> Date: Mon, 27 Jan 2025 17:02:38 +0700 Subject: [PATCH] feat(YouTube - Change start page): Add more start pages (#136) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Revert "fix(YouTube - Change start page): Use correct browseId for `Podcasts`…" This reverts commit 66b7761e7760ac9444dbba431cdba3bd8186a0c6. * feat(YouTube - Change start page): Update start pages * Update strings.xml * Fix * feat: Fix typo, Switch to Kotlin, Add `Podcasts` and `Virtual Reality` --------- Co-authored-by: inotia00 <108592928+inotia00@users.noreply.github.com> --- .../patches/general/ChangeStartPagePatch.java | 141 ---------------- .../patches/general/ChangeStartPagePatch.kt | 150 ++++++++++++++++++ .../general/startpage/ChangeStartPagePatch.kt | 4 +- .../youtube/general/startpage/Fingerprints.kt | 4 +- .../youtube/settings/host/values/arrays.xml | 6 + .../youtube/settings/host/values/strings.xml | 3 + 6 files changed, 163 insertions(+), 145 deletions(-) delete mode 100644 extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.java create mode 100644 extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.kt diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.java deleted file mode 100644 index 7ef55d606..000000000 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.java +++ /dev/null @@ -1,141 +0,0 @@ -package app.revanced.extension.youtube.patches.general; - -import static java.lang.Boolean.FALSE; -import static java.lang.Boolean.TRUE; - -import android.content.Intent; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.apache.commons.lang3.BooleanUtils; -import org.apache.commons.lang3.StringUtils; - -import app.revanced.extension.shared.settings.Setting; -import app.revanced.extension.shared.utils.Logger; -import app.revanced.extension.youtube.settings.Settings; - -@SuppressWarnings("unused") -public final class ChangeStartPagePatch { - - public enum StartPage { - /** - * Unmodified type, and same as un-patched. - */ - ORIGINAL("", null), - - /** - * Browse id. - */ - BROWSE("FEguide_builder", TRUE), - EXPLORE("FEexplore", TRUE), - HISTORY("FEhistory", TRUE), - LIBRARY("FElibrary", TRUE), - MOVIE("FEstorefront", TRUE), - NOTIFICATIONS("FEactivity", TRUE), - SUBSCRIPTIONS("FEsubscriptions", TRUE), - TRENDING("FEtrending", TRUE), - YOUR_CLIPS("FEclips", TRUE), - - /** - * Channel id, this can be used as a browseId. - */ - COURSES("UCtFRv9O2AHqOZjjynzrv-xg", TRUE), - FASHION("UCrpQ4p1Ql_hG8rKXIKM1MOQ", TRUE), - GAMING("UCOpNcN46UbXVtpKMrmU4Abg", TRUE), - LIVE("UC4R8DWoMoI7CAwX8_LjQHig", TRUE), - MUSIC("UC-9-kyTW8ZkZNDHQJ6FgpwQ", TRUE), - NEWS("UCYfdidRxbB8Qhf0Nx7ioOYw", TRUE), - PODCASTS("UCNVkxRPqsBNejO6B9thG9Xw", TRUE), - SHOPPING("UCkYQyvc_i9hXEo4xic9Hh2g", TRUE), - SPORTS("UCEgdi0XIXXZ-qJOFPf4JSKw", TRUE), - - /** - * Playlist id, this can be used as a browseId. - */ - LIKED_VIDEO("VLLL", TRUE), - WATCH_LATER("VLWL", TRUE), - - /** - * Intent action. - */ - SEARCH("com.google.android.youtube.action.open.search", FALSE), - SHORTS("com.google.android.youtube.action.open.shorts", FALSE); - - @Nullable - final Boolean isBrowseId; - - @NonNull - final String id; - - StartPage(@NonNull String id, @Nullable Boolean isBrowseId) { - this.id = id; - this.isBrowseId = isBrowseId; - } - - private boolean isBrowseId() { - return BooleanUtils.isTrue(isBrowseId); - } - - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - private boolean isIntentAction() { - return BooleanUtils.isFalse(isBrowseId); - } - } - - /** - * Intent action when YouTube is cold started from the launcher. - *

- * If you don't check this, the hooking will also apply in the following cases: - * Case 1. The user clicked Shorts button on the YouTube shortcut. - * Case 2. The user clicked Shorts button on the YouTube widget. - * In this case, instead of opening Shorts, the start page specified by the user is opened. - */ - private static final String ACTION_MAIN = "android.intent.action.MAIN"; - - private static final StartPage START_PAGE = Settings.CHANGE_START_PAGE.get(); - private static final boolean ALWAYS_CHANGE_START_PAGE = Settings.CHANGE_START_PAGE_TYPE.get(); - - /** - * There is an issue where the back button on the toolbar doesn't work properly. - * As a workaround for this issue, instead of overriding the browserId multiple times, just override it once. - */ - private static boolean appLaunched = false; - - public static String overrideBrowseId(@NonNull String original) { - if (!START_PAGE.isBrowseId()) { - return original; - } - if (!ALWAYS_CHANGE_START_PAGE && appLaunched) { - Logger.printDebug(() -> "Ignore override browseId as the app already launched"); - return original; - } - appLaunched = true; - - final String browseId = START_PAGE.id; - Logger.printDebug(() -> "Changing browseId to " + browseId); - return browseId; - } - - public static void overrideIntentAction(@NonNull Intent intent) { - if (!START_PAGE.isIntentAction()) { - return; - } - 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 intentAction = START_PAGE.id; - Logger.printDebug(() -> "Changing intent action to " + intentAction); - intent.setAction(intentAction); - } - - public static final class ChangeStartPageTypeAvailability implements Setting.Availability { - @Override - public boolean isAvailable() { - return Settings.CHANGE_START_PAGE.get() != StartPage.ORIGINAL; - } - } -} diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.kt b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.kt new file mode 100644 index 000000000..5625e07d3 --- /dev/null +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/patches/general/ChangeStartPagePatch.kt @@ -0,0 +1,150 @@ +package app.revanced.extension.youtube.patches.general + +import android.content.Intent +import android.net.Uri +import app.revanced.extension.shared.settings.Setting.Availability +import app.revanced.extension.shared.utils.Logger +import app.revanced.extension.youtube.settings.Settings +import org.apache.commons.lang3.StringUtils +import kotlin.Boolean + +@Suppress("unused") +object ChangeStartPagePatch { + /** + * Intent action when YouTube is cold started from the launcher. + * + * If you don't check this, the hooking will also apply in the following cases: + * Case 1. The user clicked Shorts button on the YouTube shortcut. + * Case 2. The user clicked Shorts button on the YouTube widget. + * In this case, instead of opening Shorts, the start page specified by the user is opened. + */ + private const val ACTION_MAIN = "android.intent.action.MAIN" + + private const val URL_ACTIVITY_CLASS_DESCRIPTOR = + "com.google.android.apps.youtube.app.application.Shell_UrlActivity" + + private var START_PAGE = Settings.CHANGE_START_PAGE.get() + private val ALWAYS_CHANGE_START_PAGE = Settings.CHANGE_START_PAGE_TYPE.get() + + /** + * There is an issue where the back button on the toolbar doesn't work properly. + * As a workaround for this issue, instead of overriding the browserId multiple times, just override it once. + */ + private var appLaunched = false + + @JvmStatic + fun overrideBrowseId(original: String): String { + val browseId = START_PAGE.browseId + if (browseId == null) { + return original + } + if (!ALWAYS_CHANGE_START_PAGE && appLaunched) { + Logger.printDebug { "Ignore override browseId as the app already launched" } + return original + } + appLaunched = true + + Logger.printDebug{ "Changing browseId to $browseId" } + return browseId + } + + @JvmStatic + fun overrideIntent(intent: Intent) { + val action = START_PAGE.action + val url = START_PAGE.url + if (action == null && url == null) { + return + } + if (!StringUtils.equals(intent.action, ACTION_MAIN)) { + Logger.printDebug { + "Ignore override intent action" + + " as the current activity is not the entry point of the application" + } + return + } + if (!ALWAYS_CHANGE_START_PAGE && appLaunched) { + Logger.printDebug { "Ignore override intent as the app already launched" } + return + } + appLaunched = true + + if (action != null) { + Logger.printDebug { "Changing intent action to $action" } + intent.setAction(action) + } else if (url != null) { + Logger.printDebug { "Changing url to $url" } + intent.setAction("android.intent.action.VIEW") + intent.setData(Uri.parse(url)) + intent.putExtra("alias", URL_ACTIVITY_CLASS_DESCRIPTOR) + } else { + START_PAGE = Settings.CHANGE_START_PAGE.defaultValue + Settings.CHANGE_START_PAGE.resetToDefault() + Logger.printException { "Unknown start page: $START_PAGE" } // Should never happen + } + } + + enum class StartPage( + val action: String? = null, + val browseId: String? = null, + val url: String? = null, + ) { + /** + * Unmodified type, and same as un-patched. + */ + ORIGINAL, + + /** + * Browse id. + */ + ALL_SUBSCRIPTIONS(browseId = "FEchannels"), + BROWSE(browseId = "FEguide_builder"), + EXPLORE(browseId = "FEexplore"), + HISTORY(browseId = "FEhistory"), + LIBRARY(browseId = "FElibrary"), + MOVIE(browseId = "FEstorefront"), + NOTIFICATIONS(browseId = "FEactivity"), + PLAYLISTS(browseId = "FEplaylist_aggregation"), + SUBSCRIPTIONS(browseId = "FEsubscriptions"), + TRENDING(browseId = "FEtrending"), + YOUR_CLIPS(browseId = "FEclips"), + + /** + * Channel id, this can be used as a browseId. + */ + COURSES(browseId = "UCtFRv9O2AHqOZjjynzrv-xg"), + FASHION(browseId = "UCrpQ4p1Ql_hG8rKXIKM1MOQ"), + GAMING(browseId = "UCOpNcN46UbXVtpKMrmU4Abg"), + LIVE(browseId = "UC4R8DWoMoI7CAwX8_LjQHig"), + MUSIC(browseId = "UC-9-kyTW8ZkZNDHQJ6FgpwQ"), + NEWS(browseId = "UCYfdidRxbB8Qhf0Nx7ioOYw"), + SHOPPING(browseId = "UCkYQyvc_i9hXEo4xic9Hh2g"), + SPORTS(browseId = "UCEgdi0XIXXZ-qJOFPf4JSKw"), + VIRTUAL_REALITY(browseId = "UCzuqhhs6NWbgTzMuM09WKDQ"), + + /** + * Playlist id, this can be used as a browseId. + */ + LIKED_VIDEO(browseId = "VLLL"), + WATCH_LATER(browseId = "VLWL"), + + /** + * Intent action. + */ + SEARCH(action = "com.google.android.youtube.action.open.search"), + SHORTS(action = "com.google.android.youtube.action.open.shorts"), + + /** + * URL. + * + * URL opens after the home feed is opened. + * Use this only if browseId cannot be used. + */ + PODCASTS(url = "www.youtube.com/podcasts"); + } + + class ChangeStartPageTypeAvailability : Availability { + override fun isAvailable(): Boolean { + return Settings.CHANGE_START_PAGE.get() != StartPage.ORIGINAL + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/startpage/ChangeStartPagePatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/startpage/ChangeStartPagePatch.kt index d83f96fa2..b4cc929cf 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/startpage/ChangeStartPagePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/startpage/ChangeStartPagePatch.kt @@ -48,9 +48,9 @@ val changeStartPagePatch = bytecodePatch( // There is no browseId assigned to Shorts and Search. // Just hook the Intent action. - intentActionFingerprint.methodOrThrow().addInstruction( + intentFingerprint.methodOrThrow().addInstruction( 0, - "invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->overrideIntentAction(Landroid/content/Intent;)V" + "invoke-static { p1 }, $EXTENSION_CLASS_DESCRIPTOR->overrideIntent(Landroid/content/Intent;)V" ) // region add settings diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/general/startpage/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/general/startpage/Fingerprints.kt index e67f99af3..c62420265 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/general/startpage/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/general/startpage/Fingerprints.kt @@ -15,8 +15,8 @@ internal val browseIdFingerprint = legacyFingerprint( strings = listOf("FEwhat_to_watch"), ) -internal val intentActionFingerprint = legacyFingerprint( - name = "intentActionFingerprint", +internal val intentFingerprint = legacyFingerprint( + name = "intentFingerprint", parameters = listOf("Landroid/content/Intent;"), strings = listOf("has_handled_intent"), ) diff --git a/patches/src/main/resources/youtube/settings/host/values/arrays.xml b/patches/src/main/resources/youtube/settings/host/values/arrays.xml index 7b65a3b73..777c1fc90 100644 --- a/patches/src/main/resources/youtube/settings/host/values/arrays.xml +++ b/patches/src/main/resources/youtube/settings/host/values/arrays.xml @@ -38,6 +38,7 @@ @string/revanced_change_start_page_entry_default + @string/revanced_change_start_page_entry_all_subscriptions @string/revanced_change_start_page_entry_browse @string/revanced_change_start_page_entry_courses @string/revanced_change_start_page_entry_explore @@ -51,6 +52,7 @@ @string/revanced_change_start_page_entry_music @string/revanced_change_start_page_entry_news @string/revanced_change_start_page_entry_notifications + @string/revanced_change_start_page_entry_playlists @string/revanced_change_start_page_entry_podcasts @string/revanced_change_start_page_entry_search @string/revanced_change_start_page_entry_shopping @@ -58,11 +60,13 @@ @string/revanced_change_start_page_entry_sports @string/revanced_change_start_page_entry_subscriptions @string/revanced_change_start_page_entry_trending + @string/revanced_change_start_page_entry_virtual_reality @string/revanced_change_start_page_entry_watch_later @string/revanced_change_start_page_entry_your_clips ORIGINAL + ALL_SUBSCRIPTIONS BROWSE COURSES EXPLORE @@ -76,6 +80,7 @@ MUSIC NEWS NOTIFICATIONS + PLAYLISTS PODCASTS SEARCH SHOPPING @@ -83,6 +88,7 @@ SPORTS SUBSCRIPTIONS TRENDING + VIRTUAL_REALITY WATCH_LATER YOUR_CLIPS diff --git a/patches/src/main/resources/youtube/settings/host/values/strings.xml b/patches/src/main/resources/youtube/settings/host/values/strings.xml index ae042b980..3f525b0d6 100644 --- a/patches/src/main/resources/youtube/settings/host/values/strings.xml +++ b/patches/src/main/resources/youtube/settings/host/values/strings.xml @@ -376,6 +376,7 @@ If the layout of the player screen changes due to server-side changes, unintende Change start page Default + All subscriptions Browse channels Courses / Learning Explore @@ -389,6 +390,7 @@ If the layout of the player screen changes due to server-side changes, unintende Music News Notifications + Playlists Podcasts Search Shopping @@ -396,6 +398,7 @@ If the layout of the player screen changes due to server-side changes, unintende Sports Subscriptions Trending + Virtual Reality Watch later Your clips Change start page type