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 @@