feat(YouTube Music): Add Change start page patch
Co-authored-by: ILoveOpenSourceApplications <117499019+iloveopensourceapplications@users.noreply.github.com>
This commit is contained in:
parent
f22ea5507d
commit
bc08ecf785
7 changed files with 271 additions and 11 deletions
|
|
@ -0,0 +1,98 @@
|
||||||
|
package app.revanced.extension.music.patches;
|
||||||
|
|
||||||
|
import static java.lang.Boolean.TRUE;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
import app.revanced.extension.music.settings.Settings;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class ChangeStartPagePatch {
|
||||||
|
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 String SHORTCUT_ID_SEARCH = "Eh4IBRDTnQEYmgMiEwiZn+H0r5WLAxVV5OcDHcHRBmPqpd25AQA=";
|
||||||
|
private static final int SHORTCUT_TYPE_SEARCH = 1;
|
||||||
|
|
||||||
|
|
||||||
|
public enum StartPage {
|
||||||
|
DEFAULT("", null),
|
||||||
|
CHARTS("FEmusic_charts", TRUE),
|
||||||
|
EXPLORE("FEmusic_explore", TRUE),
|
||||||
|
HISTORY("FEmusic_history", TRUE),
|
||||||
|
LIBRARY("FEmusic_library_landing", TRUE),
|
||||||
|
PLAYLISTS("FEmusic_liked_playlists", TRUE),
|
||||||
|
PODCASTS("FEmusic_non_music_audio", TRUE),
|
||||||
|
SUBSCRIPTIONS("FEmusic_library_corpus_artists", TRUE),
|
||||||
|
EPISODES_FOR_LATER("VLSE", TRUE),
|
||||||
|
LIKED_MUSIC("VLLM", TRUE),
|
||||||
|
SEARCH("", false);
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
final String id;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
final Boolean isBrowseId;
|
||||||
|
|
||||||
|
StartPage(@NonNull String id, @Nullable Boolean isBrowseId) {
|
||||||
|
this.id = id;
|
||||||
|
this.isBrowseId = isBrowseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBrowseId() {
|
||||||
|
return TRUE.equals(isBrowseId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String ACTION_MAIN = "android.intent.action.MAIN";
|
||||||
|
|
||||||
|
public static String overrideBrowseId(@Nullable String original) {
|
||||||
|
var startPage = Settings.CHANGE_START_PAGE.get();
|
||||||
|
|
||||||
|
if (!startPage.isBrowseId()) {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!"FEmusic_home".equals(original)) {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
String overrideBrowseId = startPage.id;
|
||||||
|
if (overrideBrowseId.isEmpty()) {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.printDebug(() -> "Changing browseId to: " + startPage.name());
|
||||||
|
return overrideBrowseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void overrideIntentActionOnCreate(@NonNull Activity activity,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
if (savedInstanceState != null) return;
|
||||||
|
|
||||||
|
var startPage = Settings.CHANGE_START_PAGE.get();
|
||||||
|
if (startPage != StartPage.SEARCH) return;
|
||||||
|
|
||||||
|
var originalIntent = activity.getIntent();
|
||||||
|
if (originalIntent == null) return;
|
||||||
|
|
||||||
|
if (ACTION_MAIN.equals(originalIntent.getAction())) {
|
||||||
|
Logger.printDebug(() -> "Cold start: Launching search activity directly");
|
||||||
|
var searchIntent = new Intent();
|
||||||
|
|
||||||
|
searchIntent.setAction(SHORTCUT_ACTION);
|
||||||
|
searchIntent.setClassName(activity, SHORTCUT_CLASS_DESCRIPTOR);
|
||||||
|
searchIntent.setPackage(activity.getPackageName());
|
||||||
|
searchIntent.putExtra(SHORTCUT_TYPE, SHORTCUT_TYPE_SEARCH);
|
||||||
|
searchIntent.putExtra(SHORTCUT_ACTION, SHORTCUT_ID_SEARCH);
|
||||||
|
|
||||||
|
activity.startActivity(searchIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package app.revanced.extension.music.settings;
|
||||||
import static java.lang.Boolean.FALSE;
|
import static java.lang.Boolean.FALSE;
|
||||||
import static java.lang.Boolean.TRUE;
|
import static java.lang.Boolean.TRUE;
|
||||||
import static app.revanced.extension.music.patches.ChangeHeaderPatch.*;
|
import static app.revanced.extension.music.patches.ChangeHeaderPatch.*;
|
||||||
|
import static app.revanced.extension.music.patches.ChangeStartPagePatch.*;
|
||||||
import static app.revanced.extension.shared.settings.Setting.parent;
|
import static app.revanced.extension.shared.settings.Setting.parent;
|
||||||
|
|
||||||
import app.revanced.extension.shared.settings.YouTubeAndMusicSettings;
|
import app.revanced.extension.shared.settings.YouTubeAndMusicSettings;
|
||||||
|
|
@ -17,6 +18,7 @@ public class Settings extends YouTubeAndMusicSettings {
|
||||||
public static final BooleanSetting HIDE_GET_PREMIUM_LABEL = new BooleanSetting("revanced_music_hide_get_premium_label", TRUE, true);
|
public static final BooleanSetting HIDE_GET_PREMIUM_LABEL = new BooleanSetting("revanced_music_hide_get_premium_label", TRUE, true);
|
||||||
|
|
||||||
// General
|
// General
|
||||||
|
public static final EnumSetting<StartPage> CHANGE_START_PAGE = new EnumSetting<>("revanced_change_start_page", StartPage.DEFAULT, true);
|
||||||
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_music_hide_cast_button", TRUE, true);
|
public static final BooleanSetting HIDE_CAST_BUTTON = new BooleanSetting("revanced_music_hide_cast_button", TRUE, true);
|
||||||
public static final BooleanSetting HIDE_CATEGORY_BAR = new BooleanSetting("revanced_music_hide_category_bar", FALSE, true);
|
public static final BooleanSetting HIDE_CATEGORY_BAR = new BooleanSetting("revanced_music_hide_category_bar", FALSE, true);
|
||||||
public static final BooleanSetting HIDE_HISTORY_BUTTON = new BooleanSetting("revanced_music_hide_history_button", FALSE, true);
|
public static final BooleanSetting HIDE_HISTORY_BUTTON = new BooleanSetting("revanced_music_hide_history_button", FALSE, true);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
package app.revanced.patches.music.layout.startpage
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.addInstruction
|
||||||
|
import app.revanced.patcher.extensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.fieldReference
|
||||||
|
import app.revanced.patcher.extensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.instructions
|
||||||
|
import app.revanced.patcher.extensions.string
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.all.misc.resources.addResources
|
||||||
|
import app.revanced.patches.all.misc.resources.addResourcesPatch
|
||||||
|
import app.revanced.patches.music.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.patches.music.misc.settings.PreferenceScreen
|
||||||
|
import app.revanced.patches.music.misc.settings.settingsPatch
|
||||||
|
import app.revanced.patches.music.shared.mainActivityOnCreateMethod
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.ListPreference
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceCategory
|
||||||
|
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreenPreference
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
import app.revanced.util.indexOfFirstInstructionReversed
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/extension/music/patches/ChangeStartPagePatch;"
|
||||||
|
|
||||||
|
val changeStartPagePatch = bytecodePatch(
|
||||||
|
name = "Change start page",
|
||||||
|
description = "Adds an option to set which page the app opens in instead of the homepage.",
|
||||||
|
) {
|
||||||
|
dependsOn(
|
||||||
|
sharedExtensionPatch,
|
||||||
|
settingsPatch,
|
||||||
|
addResourcesPatch
|
||||||
|
)
|
||||||
|
|
||||||
|
compatibleWith(
|
||||||
|
"com.google.android.apps.youtube.music"(
|
||||||
|
"7.29.52",
|
||||||
|
"8.10.52",
|
||||||
|
"8.37.56",
|
||||||
|
"8.40.54",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
apply {
|
||||||
|
addResources("music", "layout.startpage.changeStartPagePatch")
|
||||||
|
|
||||||
|
PreferenceScreen.GENERAL.addPreferences(
|
||||||
|
PreferenceCategory(
|
||||||
|
titleKey = null,
|
||||||
|
sorting = PreferenceScreenPreference.Sorting.UNSORTED,
|
||||||
|
tag = "app.revanced.extension.shared.settings.preference.NoTitlePreferenceCategory",
|
||||||
|
preferences = setOf(
|
||||||
|
ListPreference(
|
||||||
|
key = "revanced_change_start_page",
|
||||||
|
tag = "app.revanced.extension.shared.settings.preference.SortedListPreference"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
coldStartUpMethodMatch.let { match ->
|
||||||
|
match.method.apply {
|
||||||
|
val defaultBrowseIdIndex = match[-1]
|
||||||
|
|
||||||
|
val browseIdIndex = indexOfFirstInstructionReversed(defaultBrowseIdIndex) {
|
||||||
|
opcode == Opcode.IGET_OBJECT && fieldReference?.type == "Ljava/lang/String;"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browseIdIndex != -1) {
|
||||||
|
val browseIdRegister =
|
||||||
|
getInstruction<TwoRegisterInstruction>(browseIdIndex).registerA
|
||||||
|
addInstructions(
|
||||||
|
browseIdIndex + 1,
|
||||||
|
"""
|
||||||
|
invoke-static/range { v$browseIdRegister .. v$browseIdRegister }, $EXTENSION_CLASS_DESCRIPTOR->overrideBrowseId(Ljava/lang/String;)Ljava/lang/String;
|
||||||
|
move-result-object v$browseIdRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
instructions.mapIndexedNotNull { index, instr ->
|
||||||
|
if (instr.opcode == Opcode.RETURN_OBJECT) index else null
|
||||||
|
}.reversed().forEach { returnIndex ->
|
||||||
|
val returnRegister =
|
||||||
|
getInstruction<OneRegisterInstruction>(returnIndex).registerA
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
returnIndex,
|
||||||
|
"""
|
||||||
|
invoke-static/range { v$returnRegister .. v$returnRegister }, $EXTENSION_CLASS_DESCRIPTOR->overrideBrowseId(Ljava/lang/String;)Ljava/lang/String;
|
||||||
|
move-result-object v$returnRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mainActivityOnCreateMethod.apply {
|
||||||
|
val p0 = implementation!!.registerCount - 2
|
||||||
|
val p1 = p0 + 1
|
||||||
|
|
||||||
|
addInstruction(
|
||||||
|
0,
|
||||||
|
"invoke-static/range { v$p0 .. v$p1 }, " +
|
||||||
|
"$EXTENSION_CLASS_DESCRIPTOR->" +
|
||||||
|
"overrideIntentActionOnCreate(Landroid/app/Activity;Landroid/os/Bundle;)V"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package app.revanced.patches.music.layout.startpage
|
||||||
|
|
||||||
|
import app.revanced.patcher.composingFirstMethod
|
||||||
|
import app.revanced.patcher.instructions
|
||||||
|
import app.revanced.patcher.invoke
|
||||||
|
import app.revanced.patcher.parameterTypes
|
||||||
|
import app.revanced.patcher.patch.BytecodePatchContext
|
||||||
|
import app.revanced.patcher.returnType
|
||||||
|
|
||||||
|
internal val BytecodePatchContext.coldStartUpMethodMatch by composingFirstMethod {
|
||||||
|
returnType("Ljava/lang/String;")
|
||||||
|
parameterTypes()
|
||||||
|
instructions(
|
||||||
|
"FEmusic_library_sideloaded_tracks"(),
|
||||||
|
"FEmusic_home"()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package app.revanced.patches.music.misc.gms
|
|
||||||
|
|
||||||
import app.revanced.patcher.*
|
|
||||||
import app.revanced.patcher.patch.BytecodePatchContext
|
|
||||||
|
|
||||||
internal val BytecodePatchContext.musicActivityOnCreateMethod by gettingFirstMethodDeclaratively {
|
|
||||||
name("onCreate")
|
|
||||||
definingClass("/MusicActivity;")
|
|
||||||
returnType("V")
|
|
||||||
parameterTypes("Landroid/os/Bundle;")
|
|
||||||
}
|
|
||||||
|
|
@ -188,6 +188,32 @@
|
||||||
</patch>
|
</patch>
|
||||||
</app>
|
</app>
|
||||||
<app id="music">
|
<app id="music">
|
||||||
|
<patch id="layout.startpage.changeStartPagePatch">
|
||||||
|
<string-array name="revanced_change_start_page_entries">
|
||||||
|
<item>@string/revanced_change_start_page_entry_default</item>
|
||||||
|
<item>@string/revanced_change_start_page_entry_charts</item>
|
||||||
|
<item>@string/revanced_change_start_page_entry_episodes_for_later</item>
|
||||||
|
<item>@string/revanced_change_start_page_entry_explore</item>
|
||||||
|
<item>@string/revanced_change_start_page_entry_history</item>
|
||||||
|
<item>@string/revanced_change_start_page_entry_library</item>
|
||||||
|
<item>@string/revanced_change_start_page_entry_liked_music</item>
|
||||||
|
<item>@string/revanced_change_start_page_entry_playlists</item>
|
||||||
|
<item>@string/revanced_change_start_page_entry_search</item>
|
||||||
|
<item>@string/revanced_change_start_page_entry_subscriptions</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="revanced_change_start_page_entry_values">
|
||||||
|
<item>DEFAULT</item>
|
||||||
|
<item>CHARTS</item>
|
||||||
|
<item>EPISODES_FOR_LATER</item>
|
||||||
|
<item>EXPLORE</item>
|
||||||
|
<item>HISTORY</item>
|
||||||
|
<item>LIBRARY</item>
|
||||||
|
<item>LIKED_MUSIC</item>
|
||||||
|
<item>PLAYLISTS</item>
|
||||||
|
<item>SEARCH</item>
|
||||||
|
<item>SUBSCRIPTIONS</item>
|
||||||
|
</string-array>
|
||||||
|
</patch>
|
||||||
<patch id="layout.branding.header.changeHeaderPatch">
|
<patch id="layout.branding.header.changeHeaderPatch">
|
||||||
<string-array name="revanced_header_logo_entries">
|
<string-array name="revanced_header_logo_entries">
|
||||||
<item>@string/revanced_header_logo_entry_1</item>
|
<item>@string/revanced_header_logo_entry_1</item>
|
||||||
|
|
|
||||||
|
|
@ -1844,6 +1844,21 @@ Video playback with AV1 may stutter or drop frames."</string>
|
||||||
<string name="revanced_music_hide_search_button_summary_on">Search button is hidden</string>
|
<string name="revanced_music_hide_search_button_summary_on">Search button is hidden</string>
|
||||||
<string name="revanced_music_hide_search_button_summary_off">Search button is shown</string>
|
<string name="revanced_music_hide_search_button_summary_off">Search button is shown</string>
|
||||||
</patch>
|
</patch>
|
||||||
|
<patch id="layout.startpage.changeStartPagePatch">
|
||||||
|
<string name="revanced_change_start_page_title">Change start page</string>
|
||||||
|
<string name="revanced_change_start_page_entry_default">Default</string>
|
||||||
|
<string name="revanced_change_start_page_entry_charts">Charts</string>
|
||||||
|
<string name="revanced_change_start_page_entry_episodes_for_later">Episodes for later</string>
|
||||||
|
<string name="revanced_change_start_page_entry_explore">Explore</string>
|
||||||
|
<string name="revanced_change_start_page_entry_history">History</string>
|
||||||
|
<string name="revanced_change_start_page_entry_library">Library</string>
|
||||||
|
<string name="revanced_change_start_page_entry_liked_music">Liked music</string>
|
||||||
|
<string name="revanced_change_start_page_entry_playlists">Playlists</string>
|
||||||
|
<string name="revanced_change_start_page_entry_podcasts">Podcasts</string>
|
||||||
|
<string name="revanced_change_start_page_entry_search">Search</string>
|
||||||
|
<string name="revanced_change_start_page_entry_subscriptions">Subscriptions</string>
|
||||||
|
|
||||||
|
</patch>
|
||||||
<patch id="layout.compactheader.hideCategoryBar">
|
<patch id="layout.compactheader.hideCategoryBar">
|
||||||
<string name="revanced_music_hide_category_bar_title">Hide category bar</string>
|
<string name="revanced_music_hide_category_bar_title">Hide category bar</string>
|
||||||
<string name="revanced_music_hide_category_bar_summary_on">Category bar is hidden</string>
|
<string name="revanced_music_hide_category_bar_summary_on">Category bar is hidden</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue