Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(YouTube): Add 'About' preference to settings menu #2981

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
ffe9c1e
feat(YouTube): Show about preference with the patch release version
LisoUseInAIKyrios Apr 2, 2024
8007d7c
fix: Remove timestamp text, and use release version only.
LisoUseInAIKyrios Apr 2, 2024
4681c7a
fix: Show about preference last
LisoUseInAIKyrios Apr 2, 2024
9b8bc1b
refactor: Use better fingerprint name
LisoUseInAIKyrios Apr 2, 2024
0a8462b
fix: Keep binary backwards compatibility
LisoUseInAIKyrios Apr 2, 2024
5feda1a
refactor: Move version preference to shared package
LisoUseInAIKyrios Apr 2, 2024
cbb82bd
refactor: Use string format
LisoUseInAIKyrios Apr 3, 2024
f989279
Merge remote-tracking branch 'upstream/dev' into revanced_about_screen
LisoUseInAIKyrios Apr 6, 2024
9698a9e
fix: Fetch and show social links
LisoUseInAIKyrios Apr 6, 2024
03a8667
Merge remote-tracking branch 'upstream/dev' into revanced_about_screen
LisoUseInAIKyrios Apr 6, 2024
8ae2504
fix: Adjust text
LisoUseInAIKyrios Apr 6, 2024
86c0bb9
simplify
oSumAtrIX Apr 6, 2024
80ec5f1
adjust strings and structure
oSumAtrIX Apr 6, 2024
0a85ddb
fix: Adjust disclaimer text
LisoUseInAIKyrios Apr 7, 2024
4fcf9e9
fix: Adjust text. The period at the end of the version number looks o…
LisoUseInAIKyrios Apr 7, 2024
36b355d
fix: Move About menu to root menu
LisoUseInAIKyrios Apr 7, 2024
3af452a
fix: Extract app specific light/dark mode logic and colors
LisoUseInAIKyrios Apr 7, 2024
f7d9eda
fix: Move about preference to the top
LisoUseInAIKyrios Apr 7, 2024
3e031a3
Merge remote-tracking branch 'upstream/dev' into revanced_about_screen
LisoUseInAIKyrios Apr 7, 2024
881e46d
Merge remote-tracking branch 'upstream/dev' into revanced_about_screen
LisoUseInAIKyrios Apr 10, 2024
4d4132b
Merge remote-tracking branch 'upstream/dev' into revanced_about_screen
LisoUseInAIKyrios Apr 12, 2024
23518c2
Merge remote-tracking branch 'upstream/dev' into revanced_about_screen
LisoUseInAIKyrios Apr 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions api/revanced-patches.api
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,8 @@ public final class app/revanced/patches/shared/misc/settings/preference/ListPref
}

public final class app/revanced/patches/shared/misc/settings/preference/NonInteractivePreference : app/revanced/patches/shared/misc/settings/preference/BasePreference {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getSelectable ()Z
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@ package app.revanced.patches.shared.misc.integrations

import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchException
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch.IntegrationsFingerprint.IRegisterResolver
import app.revanced.patches.shared.misc.integrations.fingerprints.ReVancedUtilsPatchesVersionFingerprint
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.ClassDef
import com.android.tools.smali.dexlib2.iface.Method
import java.util.jar.JarFile

abstract class BaseIntegrationsPatch(
private val hooks: Set<IntegrationsFingerprint>,
) : BytecodePatch(hooks) {
) : BytecodePatch(hooks + setOf(ReVancedUtilsPatchesVersionFingerprint)) {

@Deprecated(
"Use the constructor without the integrationsDescriptor parameter",
Expand All @@ -34,6 +38,46 @@ abstract class BaseIntegrationsPatch(
hooks.forEach { hook ->
hook.invoke(INTEGRATIONS_CLASS_DESCRIPTOR)
}

// Modify Utils method to include the patches release version version.
ReVancedUtilsPatchesVersionFingerprint.resultOrThrow().mutableMethod.apply {
val manifestValue = getPatchesManifestEntry("Version")

addInstructions(
0,
"""
const-string v0, "$manifestValue"
return-object v0
""",
)
}
}

/**
* @return The value for the manifest entry,
* or "Unknown" if the entry does not exist or is blank.
*/
@Suppress("SameParameterValue")
private fun getPatchesManifestEntry(attributeKey: String) = JarFile(getCurrentJarFilePath()).use { jarFile ->
jarFile.manifest.mainAttributes.entries.firstOrNull { it.key.toString() == attributeKey }?.value?.toString()
?: "Unknown"
}

/**
* @return The file path for the jar this classfile is contained inside.
*/
private fun getCurrentJarFilePath(): String {
val className = object {}::class.java.enclosingClass.name.replace('.', '/') + ".class"
val classUrl = object {}::class.java.classLoader.getResource(className)
if (classUrl != null) {
val urlString = classUrl.toString()

if (urlString.startsWith("jar:file:")) {
val end = urlString.indexOf('!')
return urlString.substring("jar:file:".length, end)
}
}
throw IllegalStateException("Not running from inside a JAR file.")
}

/**
Expand All @@ -50,7 +94,7 @@ abstract class BaseIntegrationsPatch(
strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
private val insertIndexResolver: ((Method) -> Int) = object : IHookInsertIndexResolver {},
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
private val contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
) : MethodFingerprint(
returnType,
accessFlags,
Expand All @@ -59,17 +103,19 @@ abstract class BaseIntegrationsPatch(
strings,
customFingerprint,
) {
@Deprecated("Previous constructor that is missing the insert index." +
@Deprecated(
"Previous constructor that is missing the insert index." +
"Here only for binary compatibility, " +
"and this can be removed after the next major version update.")
"and this can be removed after the next major version update.",
)
constructor(
returnType: String? = null,
accessFlags: Int? = null,
parameters: Iterable<String>? = null,
opcodes: Iterable<Opcode?>? = null,
strings: Iterable<String>? = null,
customFingerprint: ((methodDef: Method, classDef: ClassDef) -> Boolean)? = null,
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {}
contextRegisterResolver: (Method) -> Int = object : IRegisterResolver {},
) : this(
returnType,
accessFlags,
Expand All @@ -78,7 +124,7 @@ abstract class BaseIntegrationsPatch(
strings,
customFingerprint,
object : IHookInsertIndexResolver {},
contextRegisterResolver
contextRegisterResolver,
)

fun invoke(integrationsDescriptor: String) {
Expand All @@ -103,7 +149,7 @@ abstract class BaseIntegrationsPatch(
}
}

private companion object {
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;"
internal companion object {
internal const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/shared/Utils;"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package app.revanced.patches.shared.misc.integrations.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.shared.misc.integrations.BaseIntegrationsPatch
import com.android.tools.smali.dexlib2.AccessFlags

internal object ReVancedUtilsPatchesVersionFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
returnType = "Ljava/lang/String;",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "getPatchesReleaseVersion" &&
classDef.type == BaseIntegrationsPatch.INTEGRATIONS_CLASS_DESCRIPTOR
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,19 @@ import org.w3c.dom.Document
@Suppress("MemberVisibilityCanBePrivate")
class NonInteractivePreference(
key: String,
titleKey: String = "${key}_title",
summaryKey: String? = "${key}_summary",
tag: String = "Preference",
val selectable: Boolean = false
) : BasePreference(null, "${key}_title", summaryKey, tag) {
) : BasePreference(key, titleKey, summaryKey, tag) {

@Deprecated("Here only for binary compatibility, and should be removed after the next major version update.")
constructor(
key: String,
summaryKey: String? = "${key}_summary",
tag: String = "Preference",
selectable: Boolean = false
) : this(key, "${key}_title", summaryKey, tag, selectable)

override fun serialize(ownerDocument: Document, resourceCallback: (BaseResource) -> Unit) =
super.serialize(ownerDocument, resourceCallback).apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ import app.revanced.patcher.patch.options.PatchOption.PatchExtensions.stringPatc
import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
import app.revanced.patches.youtube.layout.seekbar.SeekbarColorBytecodePatch
import app.revanced.patches.youtube.layout.theme.fingerprints.ThemeHelperDarkColorFingerprint
import app.revanced.patches.youtube.layout.theme.fingerprints.ThemeHelperLightColorFingerprint
import app.revanced.patches.youtube.layout.theme.fingerprints.UseGradientLoadingScreenFingerprint
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import app.revanced.util.exception
import app.revanced.util.indexOfFirstWideLiteralInstructionValue
import app.revanced.util.resultOrThrow
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction

@Patch(
Expand Down Expand Up @@ -54,7 +57,11 @@ import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
)
@Suppress("unused")
object ThemeBytecodePatch : BytecodePatch(
setOf(UseGradientLoadingScreenFingerprint)
setOf(
UseGradientLoadingScreenFingerprint,
ThemeHelperLightColorFingerprint,
ThemeHelperDarkColorFingerprint
)
) {
private const val INTEGRATIONS_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/youtube/patches/theme/ThemePatch;"
Expand Down Expand Up @@ -121,6 +128,21 @@ object ThemeBytecodePatch : BytecodePatch(
)
} ?: throw UseGradientLoadingScreenFingerprint.exception


mapOf(
ThemeHelperLightColorFingerprint to lightThemeBackgroundColor,
ThemeHelperDarkColorFingerprint to darkThemeBackgroundColor
).forEach { (fingerprint, color) ->
fingerprint.resultOrThrow().mutableMethod.apply {
addInstructions(
0, """
const-string v0, "$color"
return-object v0
"""
)
}
}

LithoColorHookPatch.lithoColorOverrideHook(INTEGRATIONS_CLASS_DESCRIPTOR, "getValue")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package app.revanced.patches.youtube.layout.theme.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import com.android.tools.smali.dexlib2.AccessFlags

internal object ThemeHelperDarkColorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
returnType = "Ljava/lang/String;",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "darkThemeResourceName" &&
classDef.type == SettingsPatch.THEME_HELPER_DESCRIPTOR
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package app.revanced.patches.youtube.layout.theme.fingerprints

import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.MethodFingerprint
import app.revanced.patches.youtube.misc.settings.SettingsPatch
import com.android.tools.smali.dexlib2.AccessFlags

internal object ThemeHelperLightColorFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
returnType = "Ljava/lang/String;",
parameters = listOf(),
customFingerprint = { methodDef, classDef ->
methodDef.name == "lightThemeResourceName" &&
classDef.type == SettingsPatch.THEME_HELPER_DESCRIPTOR
}
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import app.revanced.patches.all.misc.resources.AddResourcesPatch
import app.revanced.patches.shared.misc.settings.preference.BasePreferenceScreen
import app.revanced.patches.shared.misc.settings.preference.InputType
import app.revanced.patches.shared.misc.settings.preference.IntentPreference
import app.revanced.patches.shared.misc.settings.preference.NonInteractivePreference
import app.revanced.patches.shared.misc.settings.preference.PreferenceScreen.Sorting
import app.revanced.patches.shared.misc.settings.preference.TextPreference
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
Expand Down Expand Up @@ -39,20 +40,28 @@ object SettingsPatch :
private const val INTEGRATIONS_PACKAGE = "app/revanced/integrations/youtube"
private const val ACTIVITY_HOOK_CLASS_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/settings/LicenseActivityHook;"

private const val THEME_HELPER_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/ThemeHelper;"
internal const val THEME_HELPER_DESCRIPTOR = "L$INTEGRATIONS_PACKAGE/ThemeHelper;"
private const val SET_THEME_METHOD_NAME: String = "setTheme"

override fun execute(context: BytecodeContext) {
AddResourcesPatch(this::class)

// Add an about preference to the top.
SettingsResourcePatch += NonInteractivePreference(
key = "revanced_settings_screen_00_about",
summaryKey = null,
tag = "app.revanced.integrations.youtube.settings.preference.ReVancedYouTubeAboutPreference",
selectable = true,
)

PreferenceScreen.MISC.addPreferences(
TextPreference(
key = null,
titleKey = "revanced_pref_import_export_title",
summaryKey = "revanced_pref_import_export_summary",
inputType = InputType.TEXT_MULTI_LINE,
tag = "app.revanced.integrations.shared.settings.preference.ImportExportPreference",
),
)
)

SetThemeFingerprint.result?.mutableMethod?.let { setThemeMethod ->
Expand All @@ -69,7 +78,7 @@ object SettingsPatch :
replaceInstruction(
returnIndex,
"invoke-static { v$register }, " +
"$THEME_HELPER_DESCRIPTOR->$SET_THEME_METHOD_NAME(Ljava/lang/Object;)V",
"$THEME_HELPER_DESCRIPTOR->$SET_THEME_METHOD_NAME(Ljava/lang/Enum;)V",
)
addInstruction(returnIndex + 1, "return-object v$register")
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/addresources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,15 @@
<app id="youtube">
<patch id="misc.settings.SettingsResourcePatch">
<string name="revanced_settings">ReVanced</string>
<string name="revanced_settings_about_links_body">You are using ReVanced Patches version &lt;i>%s&lt;/i></string>
<string name="revanced_settings_about_links_dev_header">Note</string>
<string name="revanced_settings_about_links_dev_body">This version is a pre-release and you may experience unexpected issues</string>
<string name="revanced_settings_about_links_header">Official links</string>
<string name="revanced_pref_import_export_title">Import / Export</string>
<string name="revanced_pref_import_export_summary">Import / Export ReVanced settings</string>
</patch>
<patch id="misc.settings.SettingsPatch">
<string name="revanced_settings_screen_00_about_title">About</string>
<string name="revanced_settings_screen_01_ads_title">Ads</string>
<string name="revanced_settings_screen_02_alt_thumbnails_title">Alternative thumbnails</string>
<string name="revanced_settings_screen_03_feed_title">Feed</string>
Expand Down
Loading