feat(YouTube Music): Add Change start page patch

Co-authored-by: ILoveOpenSourceApplications <117499019+iloveopensourceapplications@users.noreply.github.com>
This commit is contained in:
oSumAtrIX 2026-03-08 21:44:31 +01:00
parent f22ea5507d
commit bc08ecf785
No known key found for this signature in database
GPG key ID: A9B3094ACDB604B4
7 changed files with 271 additions and 11 deletions

View file

@ -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"
)
}
}
}

View file

@ -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"()
)
}

View file

@ -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;")
}

View file

@ -188,6 +188,32 @@
</patch>
</app>
<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">
<string-array name="revanced_header_logo_entries">
<item>@string/revanced_header_logo_entry_1</item>

View file

@ -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_off">Search button is shown</string>
</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">
<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>