From 723fa2b97ceeb4c42f353adddd1cbe224828c614 Mon Sep 17 00:00:00 2001 From: inotia00 Date: Sat, 18 Feb 2023 01:53:18 +0900 Subject: [PATCH] refactor: better method is used for `settings-framework` --- .../ad/video/patch/MusicVideoAdsPatch.kt | 2 + .../audio/codecs/patch/CodecsUnlockPatch.kt | 2 + .../blacknavbar/patch/BlackNavbarPatch.kt | 2 + .../castbutton/patch/HideCastButtonPatch.kt | 2 + .../compactheader/patch/CompactHeaderPatch.kt | 2 + .../patch/MinimizedPlayerPatch.kt | 2 + .../patch/MiniplayerColorPatch.kt | 2 + .../shuffle/patch/EnforceShufflePatch.kt | 2 + .../tabletmode/patch/TabletModePatch.kt | 2 + .../layout/zenmode/patch/ZenModePatch.kt | 2 + .../misc/settings/patch/MusicSettingsPatch.kt | 45 +++--- .../util/resources/MusicResourceHelper.kt | 129 ++++++++++++++++++ .../music/settings/host/values/strings.xml | 3 +- .../settings/host/xml/settings_headers.xml | 24 ---- .../host/xml/settings_prefs_compat.xml | 23 ---- 15 files changed, 176 insertions(+), 68 deletions(-) create mode 100644 src/main/kotlin/app/revanced/util/resources/MusicResourceHelper.kt delete mode 100644 src/main/resources/music/settings/host/xml/settings_headers.xml delete mode 100644 src/main/resources/music/settings/host/xml/settings_prefs_compat.xml diff --git a/src/main/kotlin/app/revanced/patches/music/ad/video/patch/MusicVideoAdsPatch.kt b/src/main/kotlin/app/revanced/patches/music/ad/video/patch/MusicVideoAdsPatch.kt index 18e346eb9..8cb9d9b0f 100644 --- a/src/main/kotlin/app/revanced/patches/music/ad/video/patch/MusicVideoAdsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/ad/video/patch/MusicVideoAdsPatch.kt @@ -32,6 +32,8 @@ class MusicVideoAdsPatch : BytecodePatch() { GeneralVideoAdsPatch.injectMainstreamAds(INTEGRATIONS_CLASS_DESCRIPTOR) + MusicSettingsPatch.addMusicPreference("ads", "revanced_hide_music_ads", "true") + return PatchResultSuccess() } private companion object { diff --git a/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt b/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt index bebd6b13e..62d222cf8 100644 --- a/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/audio/codecs/patch/CodecsUnlockPatch.kt @@ -63,6 +63,8 @@ class CodecsUnlockPatch : BytecodePatch( } } ?: return CodecsLockFingerprint.toErrorResult() + MusicSettingsPatch.addMusicPreference("listening", "revanced_enable_opus_codec", "true") + return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/blacknavbar/patch/BlackNavbarPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/blacknavbar/patch/BlackNavbarPatch.kt index 4e0e2c811..5928956b3 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/blacknavbar/patch/BlackNavbarPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/blacknavbar/patch/BlackNavbarPatch.kt @@ -59,6 +59,8 @@ class BlackNavbarPatch : BytecodePatch( } } ?: return TabLayoutFingerprint.toErrorResult() + MusicSettingsPatch.addMusicPreference("design", "revanced_enable_black_navbar", "true") + return PatchResultSuccess() } } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/castbutton/patch/HideCastButtonPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/castbutton/patch/HideCastButtonPatch.kt index a8444513b..3542c796b 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/castbutton/patch/HideCastButtonPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/castbutton/patch/HideCastButtonPatch.kt @@ -40,6 +40,8 @@ class HideCastButtonPatch : BytecodePatch( ) ?: return HideCastButtonFingerprint.toErrorResult() } ?: return HideCastButtonParentFingerprint.toErrorResult() + MusicSettingsPatch.addMusicPreference("navigation", "revanced_hide_cast_button", "true") + return PatchResultSuccess() } } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/patch/CompactHeaderPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/patch/CompactHeaderPatch.kt index b732dfa3b..6e7e6be9a 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/compactheader/patch/CompactHeaderPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/compactheader/patch/CompactHeaderPatch.kt @@ -64,6 +64,8 @@ class CompactHeaderPatch : BytecodePatch() { "invoke-static { v$register }, $MUSIC_SETTINGS_PATH->hideCompactHeader(Landroid/view/View;)V" ) + MusicSettingsPatch.addMusicPreference("navigation", "revanced_hide_compact_header", "true") + patchSuccessArray[0] = true; } } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayer/patch/MinimizedPlayerPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayer/patch/MinimizedPlayerPatch.kt index 22cc1f69b..29874ab50 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayer/patch/MinimizedPlayerPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/minimizedplayer/patch/MinimizedPlayerPatch.kt @@ -48,6 +48,8 @@ class MinimizedPlayerPatch : BytecodePatch( } } ?: return MinimizedPlayerFingerprint.toErrorResult() + MusicSettingsPatch.addMusicPreference("listening", "revanced_enable_force_minimized_player", "true") + return PatchResultSuccess() } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/patch/MiniplayerColorPatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/patch/MiniplayerColorPatch.kt index 165d9ca42..68dc9026a 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/patch/MiniplayerColorPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/miniplayercolor/patch/MiniplayerColorPatch.kt @@ -92,6 +92,8 @@ class MiniplayerColorPatch : BytecodePatch( } ?: return MiniplayerColorFingerprint.toErrorResult() } ?: return MiniplayerColorParentFingerprint.toErrorResult() + MusicSettingsPatch.addMusicPreference("design", "revanced_enable_color_match_player", "true") + return PatchResultSuccess() } private companion object { diff --git a/src/main/kotlin/app/revanced/patches/music/layout/shuffle/patch/EnforceShufflePatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/shuffle/patch/EnforceShufflePatch.kt index 99bc2472c..d7e8ff86f 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/shuffle/patch/EnforceShufflePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/shuffle/patch/EnforceShufflePatch.kt @@ -158,6 +158,8 @@ class EnforceShufflePatch : BytecodePatch( ) } ?: return MusicPlaybackControlsFingerprint.toErrorResult() + MusicSettingsPatch.addMusicPreference("listening", "revanced_enable_force_shuffle", "true") + return PatchResultSuccess() } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/tabletmode/patch/TabletModePatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/tabletmode/patch/TabletModePatch.kt index c70c8a131..b94ddecd6 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/tabletmode/patch/TabletModePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/tabletmode/patch/TabletModePatch.kt @@ -43,6 +43,8 @@ class TabletModePatch : BytecodePatch( ) } ?: return TabletLayoutFingerprint.toErrorResult() + MusicSettingsPatch.addMusicPreference("navigation", "revanced_enable_tablet_mode", "true") + return PatchResultSuccess() } } diff --git a/src/main/kotlin/app/revanced/patches/music/layout/zenmode/patch/ZenModePatch.kt b/src/main/kotlin/app/revanced/patches/music/layout/zenmode/patch/ZenModePatch.kt index 72f99f992..038e26e2f 100644 --- a/src/main/kotlin/app/revanced/patches/music/layout/zenmode/patch/ZenModePatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/layout/zenmode/patch/ZenModePatch.kt @@ -67,6 +67,8 @@ class ZenModePatch : BytecodePatch( } ?: return ZenModeFingerprint.toErrorResult() } ?: return MiniplayerColorParentFingerprint.toErrorResult() + MusicSettingsPatch.addMusicPreference("design", "revanced_enable_zen_mode", "false") + return PatchResultSuccess() } } \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/patches/music/misc/settings/patch/MusicSettingsPatch.kt b/src/main/kotlin/app/revanced/patches/music/misc/settings/patch/MusicSettingsPatch.kt index ed16848af..39e73e45f 100644 --- a/src/main/kotlin/app/revanced/patches/music/misc/settings/patch/MusicSettingsPatch.kt +++ b/src/main/kotlin/app/revanced/patches/music/misc/settings/patch/MusicSettingsPatch.kt @@ -6,12 +6,15 @@ import app.revanced.patcher.annotation.Version import app.revanced.patcher.data.ResourceContext import app.revanced.patcher.patch.PatchResult import app.revanced.patcher.patch.PatchResultSuccess -import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.annotations.DependsOn import app.revanced.patcher.patch.annotations.Patch import app.revanced.patches.music.misc.integrations.patch.MusicIntegrationsPatch import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility -import app.revanced.util.resources.ResourceUtils.copyXmlNode +import app.revanced.patches.shared.patch.settings.AbstractSettingsResourcePatch +import app.revanced.util.resources.MusicResourceHelper.addMusicPreference +import app.revanced.util.resources.MusicResourceHelper.addMusicPreferenceCategory +import app.revanced.util.resources.MusicResourceHelper.addReVancedMusicPreference +import app.revanced.util.resources.MusicResourceHelper.sortMusicPreferenceCategory import org.w3c.dom.Element @Patch @@ -20,14 +23,14 @@ import org.w3c.dom.Element @DependsOn([MusicIntegrationsPatch::class]) @YouTubeMusicCompatibility @Version("0.0.1") -class MusicSettingsPatch : ResourcePatch { +class MusicSettingsPatch : AbstractSettingsResourcePatch( + "music/settings", + "music/settings/host", + false +) { override fun execute(context: ResourceContext): PatchResult { - - /* - * Copy strings - */ - - context.copyXmlNode("music/settings/host", "values/strings.xml", "resources") + super.execute(context) + contexts = context /* * Copy colors @@ -47,19 +50,21 @@ class MusicSettingsPatch : ResourcePatch { } } - /* - * Copy preference fragments - */ - - context.copyXmlNode("music/settings/host", "xml/settings_headers.xml", "PreferenceScreen") - - // Removed since YouTube Music v5.38.xx - - try { - context.copyXmlNode("music/settings/host", "xml/settings_prefs_compat.xml", "com.google.android.apps.youtube.music.ui.preference.PreferenceCategoryCompat") - } catch (_: Exception) {} + context.addReVancedMusicPreference() return PatchResultSuccess() } + companion object { + private lateinit var contexts: ResourceContext + internal fun addMusicPreference( + category: String, + key: String, + defaultValue: String + ) { + contexts.addMusicPreferenceCategory(category) + contexts.sortMusicPreferenceCategory() + contexts.addMusicPreference(category, key, defaultValue) + } + } } diff --git a/src/main/kotlin/app/revanced/util/resources/MusicResourceHelper.kt b/src/main/kotlin/app/revanced/util/resources/MusicResourceHelper.kt new file mode 100644 index 000000000..86698e309 --- /dev/null +++ b/src/main/kotlin/app/revanced/util/resources/MusicResourceHelper.kt @@ -0,0 +1,129 @@ +package app.revanced.util.resources + +import app.revanced.extensions.doRecursively +import app.revanced.patcher.data.ResourceContext +import org.w3c.dom.Element +import org.w3c.dom.Node + +private fun Node.adoptChild(tagName: String, block: Element.() -> Unit) { + val child = ownerDocument.createElement(tagName) + child.block() + appendChild(child) +} + +private fun Node.cloneNodes(parent: Node) { + val node = cloneNode(true) + parent.appendChild(node) + parent.removeChild(this) +} + +private fun Node.insertNode(tagName: String, targetNode: Node, block: Element.() -> Unit) { + val child = ownerDocument.createElement(tagName) + child.block() + parentNode.insertBefore(child, targetNode) +} + + +internal object MusicResourceHelper { + + private const val YOUTUBE_MUSIC_SETTINGS_PATH = "res/xml/settings_headers.xml" + + private const val YOUTUBE_MUSIC_SETTINGS_KEY = "revanced_extended_settings" + + private const val YOUTUBE_MUSIC_CATEGORY_TAG_NAME = "com.google.android.apps.youtube.music.ui.preference.PreferenceCategoryCompat" + + private const val YOUTUBE_MUSIC_PREFERENCE_TAG_NAME = "com.google.android.apps.youtube.music.ui.preference.SwitchCompatPreference" + + private var currentMusicPreferenceCategory = emptyArray() + + private fun setMusicPreferenceCategory (newCategory: String) { + currentMusicPreferenceCategory += listOf(newCategory) + } + + internal fun ResourceContext.addMusicPreferenceCategory( + category: String + ) { + this.xmlEditor[YOUTUBE_MUSIC_SETTINGS_PATH].use { editor -> + val tags = editor.file.getElementsByTagName("PreferenceScreen") + List(tags.length) { tags.item(it) as Element } + .filter { it.getAttribute("android:key").contains(YOUTUBE_MUSIC_SETTINGS_KEY) } + .forEach { + if (!currentMusicPreferenceCategory.contains(category)) { + it.adoptChild(YOUTUBE_MUSIC_CATEGORY_TAG_NAME) { + setAttribute("android:title", "@string/revanced_category_$category") + setAttribute("android:key", "revanced_settings_$category") + } + setMusicPreferenceCategory(category) + } + } + } + } + + internal fun ResourceContext.sortMusicPreferenceCategory() { + this.xmlEditor[YOUTUBE_MUSIC_SETTINGS_PATH].use { editor -> + editor.file.doRecursively loop@{ + if (it !is Element) return@loop + + currentMusicPreferenceCategory.forEach { category -> + it.getAttributeNode("android:key")?.let { attribute -> + if (attribute.textContent == "revanced_settings_$category") { + it.cloneNodes(it.parentNode) + } + } + } + } + } + } + + internal fun ResourceContext.addMusicPreference( + category: String, + key: String, + defaultValue: String + ) { + this.xmlEditor[YOUTUBE_MUSIC_SETTINGS_PATH].use { editor -> + val tags = editor.file.getElementsByTagName(YOUTUBE_MUSIC_CATEGORY_TAG_NAME) + List(tags.length) { tags.item(it) as Element } + .filter { it.getAttribute("android:key").contains("revanced_settings_$category") } + .forEach { + it.adoptChild(YOUTUBE_MUSIC_PREFERENCE_TAG_NAME) { + setAttribute("android:title", "@string/$key" + "_title") + setAttribute("android:summary", "@string/$key" + "_summary") + setAttribute("android:key", key) + setAttribute("android:defaultValue", defaultValue) + } + } + } + } + + internal fun ResourceContext.addReVancedMusicPreference() { + this.xmlEditor[YOUTUBE_MUSIC_SETTINGS_PATH].use { editor -> + with (editor.file) { + doRecursively loop@{ + if (it !is Element) return@loop + it.getAttributeNode("android:key")?.let { attribute -> + if (attribute.textContent == "settings_header_about_youtube_music" && it.getAttributeNode("app:allowDividerBelow").textContent == "false") { + it.insertNode("PreferenceScreen", it) { + setAttribute("android:title", "@string/" + YOUTUBE_MUSIC_SETTINGS_KEY + "_title") + setAttribute("android:summary", "@string/" + YOUTUBE_MUSIC_SETTINGS_KEY + "_summary") + setAttribute("android:key", YOUTUBE_MUSIC_SETTINGS_KEY) + } + it.getAttributeNode("app:allowDividerBelow").textContent = "true" + return@loop + } + } + } + + doRecursively loop@{ + if (it !is Element) return@loop + + it.getAttributeNode("app:allowDividerBelow")?.let { attribute -> + if (attribute.textContent == "true") { + attribute.textContent = "false" + } + } + } + } + } + } + +} \ No newline at end of file diff --git a/src/main/resources/music/settings/host/values/strings.xml b/src/main/resources/music/settings/host/values/strings.xml index 0747e716b..15da64399 100644 --- a/src/main/resources/music/settings/host/values/strings.xml +++ b/src/main/resources/music/settings/host/values/strings.xml @@ -21,6 +21,8 @@ Enable tablet mode Adds a grey tint to the video player to reduce eye strain. Enable zen mode + ReVanced Extended specific settings + ReVanced Extended settings Hides the cast button at the top of the homepage and at the top of the player. Hide cast button "Hides the music category bar at the top of the homepage. @@ -29,5 +31,4 @@ "Hide ads before playing a track. (requires an app restart)" Hide music ads - ReVanced settings diff --git a/src/main/resources/music/settings/host/xml/settings_headers.xml b/src/main/resources/music/settings/host/xml/settings_headers.xml deleted file mode 100644 index 6a29eca85..000000000 --- a/src/main/resources/music/settings/host/xml/settings_headers.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/music/settings/host/xml/settings_prefs_compat.xml b/src/main/resources/music/settings/host/xml/settings_prefs_compat.xml deleted file mode 100644 index fc27ac159..000000000 --- a/src/main/resources/music/settings/host/xml/settings_prefs_compat.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file