2023-09-20 05:33:02 +02:00
|
|
|
package app.revanced.patches.youtube.misc.settings
|
2022-07-31 12:15:26 +02:00
|
|
|
|
2022-10-05 04:03:10 +02:00
|
|
|
import app.revanced.patcher.data.ResourceContext
|
2023-09-20 05:33:02 +02:00
|
|
|
import app.revanced.patcher.patch.annotation.Patch
|
2023-08-27 21:40:49 +02:00
|
|
|
import app.revanced.patcher.util.DomFileEditor
|
2023-09-20 05:33:02 +02:00
|
|
|
import app.revanced.patches.shared.mapping.misc.ResourceMappingPatch
|
|
|
|
import app.revanced.patches.shared.settings.AbstractSettingsResourcePatch
|
2022-11-28 20:13:34 +01:00
|
|
|
import app.revanced.patches.shared.settings.preference.addPreference
|
2023-05-15 09:51:43 +02:00
|
|
|
import app.revanced.patches.shared.settings.preference.impl.*
|
2023-12-02 22:35:13 +01:00
|
|
|
import app.revanced.util.ResourceGroup
|
|
|
|
import app.revanced.util.copyResources
|
|
|
|
import app.revanced.util.mergeStrings
|
2023-05-19 22:45:12 +02:00
|
|
|
import org.w3c.dom.Element
|
2022-08-22 01:59:43 +02:00
|
|
|
import org.w3c.dom.Node
|
2022-07-31 12:15:26 +02:00
|
|
|
|
2023-09-20 05:33:02 +02:00
|
|
|
@Patch(
|
|
|
|
dependencies = [ResourceMappingPatch::class]
|
|
|
|
)
|
|
|
|
object SettingsResourcePatch : AbstractSettingsResourcePatch(
|
2022-11-28 20:13:34 +01:00
|
|
|
"revanced_prefs",
|
|
|
|
"settings"
|
|
|
|
) {
|
2023-09-20 05:33:02 +02:00
|
|
|
// Used for a fingerprint from SettingsPatch.
|
|
|
|
internal var appearanceStringId = -1L
|
|
|
|
|
|
|
|
// if this is not null, all intents will be renamed to this
|
|
|
|
internal var overrideIntentsTargetPackage: String? = null
|
|
|
|
|
|
|
|
private var preferencesNode: Node? = null
|
|
|
|
|
|
|
|
private var preferencesEditor: DomFileEditor? = null
|
|
|
|
set(value) {
|
|
|
|
field = value
|
|
|
|
preferencesNode = value.getNode("PreferenceScreen")
|
|
|
|
}
|
|
|
|
|
2023-08-27 21:40:49 +02:00
|
|
|
override fun execute(context: ResourceContext) {
|
2022-11-28 20:13:34 +01:00
|
|
|
super.execute(context)
|
|
|
|
|
2023-05-18 02:57:50 +02:00
|
|
|
// Used for a fingerprint from SettingsPatch.
|
2022-11-20 23:08:51 +01:00
|
|
|
appearanceStringId = ResourceMappingPatch.resourceMappings.find {
|
2022-10-25 08:36:59 +02:00
|
|
|
it.type == "string" && it.name == "app_theme_appearance_dark"
|
|
|
|
}!!.id
|
|
|
|
|
2023-05-19 22:45:12 +02:00
|
|
|
/*
|
|
|
|
* copy layout resources
|
|
|
|
*/
|
2022-07-31 12:15:26 +02:00
|
|
|
arrayOf(
|
2023-12-02 22:35:13 +01:00
|
|
|
ResourceGroup("layout", "revanced_settings_with_toolbar.xml")
|
2022-07-31 12:15:26 +02:00
|
|
|
).forEach { resourceGroup ->
|
2022-10-05 04:03:10 +02:00
|
|
|
context.copyResources("settings", resourceGroup)
|
2022-07-31 12:15:26 +02:00
|
|
|
}
|
|
|
|
|
2022-10-05 04:03:10 +02:00
|
|
|
preferencesEditor = context.xmlEditor["res/xml/settings_fragment.xml"]
|
2022-08-22 01:59:43 +02:00
|
|
|
|
2023-05-19 22:45:12 +02:00
|
|
|
// Modify the manifest and add an data intent filter to the LicenseActivity.
|
|
|
|
// Some devices freak out if undeclared data is passed to an intent,
|
|
|
|
// and this change appears to fix the issue.
|
|
|
|
context.xmlEditor["AndroidManifest.xml"].use { editor ->
|
|
|
|
// An xml regular expression would probably work better than this manual searching.
|
|
|
|
val manifestNodes = editor.file.getElementsByTagName("manifest").item(0).childNodes
|
|
|
|
for (i in 0..manifestNodes.length) {
|
|
|
|
val node = manifestNodes.item(i)
|
|
|
|
if (node != null && node.nodeName == "application") {
|
|
|
|
val applicationNodes = node.childNodes
|
|
|
|
for (j in 0..applicationNodes.length) {
|
|
|
|
val applicationChild = applicationNodes.item(j)
|
|
|
|
if (applicationChild is Element && applicationChild.nodeName == "activity"
|
|
|
|
&& applicationChild.getAttribute("android:name") == "com.google.android.libraries.social.licenses.LicenseActivity"
|
|
|
|
) {
|
|
|
|
val intentFilter = editor.file.createElement("intent-filter")
|
|
|
|
val mimeType = editor.file.createElement("data")
|
|
|
|
mimeType.setAttribute("android:mimeType", "text/plain")
|
|
|
|
intentFilter.appendChild(mimeType)
|
|
|
|
applicationChild.appendChild(intentFilter)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Add the ReVanced settings to the YouTube settings
|
2022-08-22 01:59:43 +02:00
|
|
|
SettingsPatch.addPreference(
|
|
|
|
Preference(
|
|
|
|
StringResource("revanced_settings", "ReVanced"),
|
2023-05-15 09:51:43 +02:00
|
|
|
StringResource("revanced_settings_summary", "ReVanced specific settings"),
|
2023-05-19 22:45:12 +02:00
|
|
|
SettingsPatch.createReVancedSettingsIntent("revanced_settings")
|
2023-05-15 09:51:43 +02:00
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
SettingsPatch.PreferenceScreen.MISC.addPreferences(
|
|
|
|
TextPreference(
|
|
|
|
key = null,
|
|
|
|
title = StringResource("revanced_pref_import_export_title", "Import / Export"),
|
|
|
|
summary = StringResource("revanced_pref_import_export_summary", "Import / Export ReVanced settings"),
|
|
|
|
inputType = InputType.TEXT_MULTI_LINE,
|
2024-01-01 16:33:07 +01:00
|
|
|
tag = "app.revanced.integrations.shared.settings.preference.ImportExportPreference"
|
2022-08-22 01:59:43 +02:00
|
|
|
)
|
|
|
|
)
|
2022-07-31 12:15:26 +02:00
|
|
|
}
|
2022-08-22 01:59:43 +02:00
|
|
|
|
|
|
|
override fun close() {
|
2022-11-28 20:13:34 +01:00
|
|
|
super.close()
|
2022-08-22 01:59:43 +02:00
|
|
|
|
|
|
|
// rename the intent package names if it was set
|
|
|
|
overrideIntentsTargetPackage?.let { packageName ->
|
|
|
|
val preferences = preferencesEditor!!.getNode("PreferenceScreen").childNodes
|
|
|
|
for (i in 1 until preferences.length) {
|
|
|
|
val preferenceNode = preferences.item(i)
|
|
|
|
// preferences have a child node with the intent tag, skip over every other node
|
|
|
|
if (preferenceNode.childNodes.length == 0) continue
|
|
|
|
|
|
|
|
val intentNode = preferenceNode.firstChild
|
|
|
|
|
|
|
|
// if the node doesn't have a target package attribute, skip it
|
|
|
|
val targetPackageAttribute = intentNode.attributes.getNamedItem("android:targetPackage") ?: continue
|
|
|
|
|
|
|
|
// do not replace intent target package if the package name is not from YouTube
|
|
|
|
val youtubePackage = "com.google.android.youtube"
|
|
|
|
if (targetPackageAttribute.nodeValue != youtubePackage) continue
|
|
|
|
|
|
|
|
// replace the target package name
|
|
|
|
intentNode.attributes.setNamedItem(preferenceNode.ownerDocument.createAttribute("android:targetPackage")
|
|
|
|
.also { attribute ->
|
|
|
|
attribute.value = packageName
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
preferencesEditor?.close()
|
|
|
|
}
|
2023-09-20 05:33:02 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a preference fragment to the main preferences.
|
|
|
|
*
|
|
|
|
* @param preference The preference to add.
|
|
|
|
*/
|
|
|
|
internal fun addPreference(preference: Preference) =
|
|
|
|
preferencesNode!!.addPreference(preference) { it.include() }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a new string to the resources.
|
|
|
|
*
|
|
|
|
* @param identifier The key of the string.
|
|
|
|
* @param value The value of the string.
|
|
|
|
* @throws IllegalArgumentException if the string already exists.
|
|
|
|
*/
|
|
|
|
internal fun addString(identifier: String, value: String, formatted: Boolean) =
|
|
|
|
AbstractSettingsResourcePatch.addString(identifier, value, formatted)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add an array to the resources.
|
|
|
|
*
|
|
|
|
* @param arrayResource The array resource to add.
|
|
|
|
*/
|
|
|
|
internal fun addArray(arrayResource: ArrayResource) = AbstractSettingsResourcePatch.addArray(arrayResource)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a preference to the settings.
|
|
|
|
*
|
|
|
|
* @param preferenceScreen The name of the preference screen.
|
|
|
|
*/
|
|
|
|
internal fun addPreferenceScreen(preferenceScreen: PreferenceScreen) = addPreference(preferenceScreen)
|
2022-07-31 12:15:26 +02:00
|
|
|
}
|