From f2ca0eeac0f221d4eb77bd2dec0cb4b7dfe6b8f9 Mon Sep 17 00:00:00 2001 From: Nuckyz <61953774+Nuckyz@users.noreply.github.com> Date: Thu, 5 Jun 2025 16:04:02 -0300 Subject: [PATCH] refactor(Spotify): Add extensions debug logging (#5110) --- extensions/spotify/build.gradle.kts | 2 +- .../createbutton/HideCreateButtonPatch.java | 26 ++++++- .../spotify/misc/UnlockPremiumPatch.java | 78 ++++++++++++++++--- .../privacy/SanitizeSharingLinksPatch.java | 7 +- extensions/spotify/stub/build.gradle.kts | 2 +- .../createbutton/HideCreateButtonPatch.kt | 2 +- .../spotify/layout/theme/CustomThemePatch.kt | 2 +- .../spotify/misc/UnlockPremiumPatch.kt | 6 +- .../misc/fix/login/FixFacebookLoginPatch.kt | 2 +- .../spotify/misc/widgets/Fingerprints.kt | 1 - 10 files changed, 101 insertions(+), 27 deletions(-) diff --git a/extensions/spotify/build.gradle.kts b/extensions/spotify/build.gradle.kts index f4da3ba6f..39d58a022 100644 --- a/extensions/spotify/build.gradle.kts +++ b/extensions/spotify/build.gradle.kts @@ -6,7 +6,7 @@ dependencies { android { defaultConfig { - minSdk = 24 + minSdk = 21 } compileOptions { diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/layout/hide/createbutton/HideCreateButtonPatch.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/layout/hide/createbutton/HideCreateButtonPatch.java index f3003bb31..a96ca0cb2 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/layout/hide/createbutton/HideCreateButtonPatch.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/layout/hide/createbutton/HideCreateButtonPatch.java @@ -2,6 +2,7 @@ package app.revanced.extension.spotify.layout.hide.createbutton; import java.util.List; +import app.revanced.extension.shared.Logger; import app.revanced.extension.shared.Utils; @SuppressWarnings("unused") @@ -31,10 +32,21 @@ public final class HideCreateButtonPatch { } String stringifiedNavigationBarItem = navigationBarItem.toString(); - boolean isCreateButton = CREATE_BUTTON_TITLE_RES_ID_LIST.stream() - .anyMatch(stringifiedNavigationBarItem::contains); + + boolean isCreateButton = false; + String matchedTitleResId = null; + + for (String titleResId : CREATE_BUTTON_TITLE_RES_ID_LIST) { + if (stringifiedNavigationBarItem.contains(titleResId)) { + isCreateButton = true; + matchedTitleResId = titleResId; + } + } if (isCreateButton) { + String finalMatchedTitleResId = matchedTitleResId; + Logger.printInfo(() -> "Hiding Create button because the navigation bar item " + navigationBarItem + + " matched the title resource id " + finalMatchedTitleResId); return null; } @@ -46,6 +58,14 @@ public final class HideCreateButtonPatch { * Create button. */ public static boolean isOldCreateButton(int oldNavigationBarItemTitleResId) { - return oldNavigationBarItemTitleResId == OLD_CREATE_BUTTON_TITLE_RES_ID; + boolean isCreateButton = oldNavigationBarItemTitleResId == OLD_CREATE_BUTTON_TITLE_RES_ID; + + if (isCreateButton) { + Logger.printInfo(() -> "Hiding old Create button because the navigation bar item title resource id" + + " matched " + OLD_CREATE_BUTTON_TITLE_RES_ID); + return true; + } + + return false; } } diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/UnlockPremiumPatch.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/UnlockPremiumPatch.java index f01fee831..065bbb8f9 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/UnlockPremiumPatch.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/UnlockPremiumPatch.java @@ -5,6 +5,7 @@ import static java.lang.Boolean.TRUE; import com.spotify.home.evopage.homeapi.proto.Section; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -133,17 +134,33 @@ public final class UnlockPremiumPatch { try { for (OverrideAttribute override : PREMIUM_OVERRIDES) { Object attribute = attributes.get(override.key); + if (attribute == null) { if (override.isExpected) { - Logger.printException(() -> "'" + override.key + "' expected but not found"); + Logger.printException(() -> "Attribute " + override.key + " expected but not found"); } + continue; + } + + Object overrideValue = override.overrideValue; + Object originalValue; + if (IS_SPOTIFY_LEGACY_APP_TARGET) { + originalValue = ((com.spotify.useraccount.v1.AccountAttribute) attribute).value_; } else { - Object overrideValue = override.overrideValue; - if (IS_SPOTIFY_LEGACY_APP_TARGET) { - ((com.spotify.useraccount.v1.AccountAttribute) attribute).value_ = overrideValue; - } else { - ((com.spotify.remoteconfig.internal.AccountAttribute) attribute).value_ = overrideValue; - } + originalValue = ((com.spotify.remoteconfig.internal.AccountAttribute) attribute).value_; + } + + if (overrideValue == originalValue) { + continue; + } + + Logger.printInfo(() -> "Overriding account attribute " + override.key + + " from " + originalValue + " to " + overrideValue); + + if (IS_SPOTIFY_LEGACY_APP_TARGET) { + ((com.spotify.useraccount.v1.AccountAttribute) attribute).value_ = overrideValue; + } else { + ((com.spotify.remoteconfig.internal.AccountAttribute) attribute).value_ = overrideValue; } } } catch (Exception ex) { @@ -155,7 +172,13 @@ public final class UnlockPremiumPatch { * Injection point. Remove station data from Google Assistant URI. */ public static String removeStationString(String spotifyUriOrUrl) { - return spotifyUriOrUrl.replace("spotify:station:", "spotify:"); + try { + Logger.printInfo(() -> "Removing station string from " + spotifyUriOrUrl); + return spotifyUriOrUrl.replace("spotify:station:", "spotify:"); + } catch (Exception ex) { + Logger.printException(() -> "removeStationString failure", ex); + return spotifyUriOrUrl; + } } /** @@ -164,9 +187,17 @@ public final class UnlockPremiumPatch { */ public static void removeHomeSections(List
sections) { try { - sections.removeIf(section -> REMOVED_HOME_SECTIONS.contains(section.featureTypeCase_)); + Iterator
iterator = sections.iterator(); + + while (iterator.hasNext()) { + Section section = iterator.next(); + if (REMOVED_HOME_SECTIONS.contains(section.featureTypeCase_)) { + Logger.printInfo(() -> "Removing home section with feature type id " + section.featureTypeCase_); + iterator.remove(); + } + } } catch (Exception ex) { - Logger.printException(() -> "Remove home sections failure", ex); + Logger.printException(() -> "removeHomeSections failure", ex); } } @@ -179,7 +210,30 @@ public final class UnlockPremiumPatch { } String stringifiedContextMenuItem = contextMenuItem.toString(); - return FILTERED_CONTEXT_MENU_ITEMS_BY_STRINGS.stream() - .anyMatch(filters -> filters.stream().allMatch(stringifiedContextMenuItem::contains)); + for (List stringList : FILTERED_CONTEXT_MENU_ITEMS_BY_STRINGS) { + boolean allMatch = true; + StringBuilder matchedStrings = new StringBuilder(); + + for (int i = 0; i < stringList.size(); i++) { + String string = stringList.get(i); + if (!stringifiedContextMenuItem.contains(string)) { + allMatch = false; + break; + } + + matchedStrings.append(string); + if (i < stringList.size() - 1) { + matchedStrings.append(", "); + } + } + + if (allMatch) { + Logger.printInfo(() -> "Filtering context menu item " + stringifiedContextMenuItem + + " because the following strings matched: " + matchedStrings); + return true; + } + } + + return false; } } diff --git a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/privacy/SanitizeSharingLinksPatch.java b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/privacy/SanitizeSharingLinksPatch.java index 55541ec9c..55b78933d 100644 --- a/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/privacy/SanitizeSharingLinksPatch.java +++ b/extensions/spotify/src/main/java/app/revanced/extension/spotify/misc/privacy/SanitizeSharingLinksPatch.java @@ -33,10 +33,11 @@ public final class SanitizeSharingLinksPatch { } } - return builder.build().toString(); + String sanitizedUrl = builder.build().toString(); + Logger.printInfo(() -> "Sanitized url " + url + " to " + sanitizedUrl); + return sanitizedUrl; } catch (Exception ex) { - Logger.printException(() -> "sanitizeUrl failure", ex); - + Logger.printException(() -> "sanitizeUrl failure with " + url, ex); return url; } } diff --git a/extensions/spotify/stub/build.gradle.kts b/extensions/spotify/stub/build.gradle.kts index 61a9e204a..489664c26 100644 --- a/extensions/spotify/stub/build.gradle.kts +++ b/extensions/spotify/stub/build.gradle.kts @@ -7,7 +7,7 @@ android { compileSdk = 34 defaultConfig { - minSdk = 24 + minSdk = 21 } compileOptions { diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/layout/hide/createbutton/HideCreateButtonPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/hide/createbutton/HideCreateButtonPatch.kt index 9685f0463..9bdd69be8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/layout/hide/createbutton/HideCreateButtonPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/hide/createbutton/HideCreateButtonPatch.kt @@ -72,7 +72,7 @@ val hideCreateButtonPatch = bytecodePatch( if (oldNavigationBarAddItemMethod != null) { // In case an older version of the app is being patched, hook the old method which adds navigation bar items. - // Return null early if the navigation bar item title resource id is old Create button title resource id. + // Return null early if the navigation bar item title resource id is the old Create button title resource id. oldNavigationBarAddItemFingerprint.methodOrNull?.apply { val getNavigationBarItemTitleStringIndex = indexOfFirstInstructionOrThrow { val reference = getReference() diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt index 738db4dec..61e847aa2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/layout/theme/CustomThemePatch.kt @@ -129,7 +129,7 @@ val customThemePatch = resourcePatch( val accentColorPressed by stringOption( key = "accentColorPressed", default = "#FF1ABC54", - title = "Pressed dark theme accent color", + title = "Pressed accent color", description = "The color when accented buttons are pressed, by default slightly darker than accent. " + "Can be a hex color or a resource reference.", required = true, diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt index d32ce24b3..df3615242 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/UnlockPremiumPatch.kt @@ -38,7 +38,7 @@ val unlockPremiumPatch = bytecodePatch( // so for now this is a dependent of this patch. // // FIXME: Modifying string resources (such as adding patch strings) - // is currently failing with ReVanced manager. + // is currently failing with ReVanced Manager. // checkEnvironmentPatch, ) @@ -78,7 +78,7 @@ val unlockPremiumPatch = bytecodePatch( if (IS_SPOTIFY_LEGACY_APP_TARGET) { Logger.getLogger(this::class.java.name).warning( - "Patching a legacy Spotify version. Patch functionality may be limited." + "Patching a legacy Spotify version. Patch functionality may be limited." ) return@execute } @@ -174,7 +174,7 @@ val unlockPremiumPatch = bytecodePatch( // Need to allow mutation of the list so the home ads sections can be removed. // Protobuf array list has an 'isMutable' boolean parameter that sets the mutability. // Forcing that always on breaks unrelated code in strange ways. - // Instead, return early in the method that throws an error if the list is unmutable. + // Instead, return early in the method that throws an error if the list is immutable. abstractProtobufListEnsureIsMutableFingerprint.match(abstractProtobufListClassDef) .method.returnEarly() diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/login/FixFacebookLoginPatch.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/login/FixFacebookLoginPatch.kt index dc9179854..8c415c5b5 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/login/FixFacebookLoginPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/fix/login/FixFacebookLoginPatch.kt @@ -15,7 +15,7 @@ val fixFacebookLoginPatch = bytecodePatch( // The Facebook SDK tries to handle the login using the Facebook app in case it is installed. // However, the Facebook app does signature checks with the app that is requesting the authentication, // which ends up making the Facebook server reject with an invalid key hash for the app signature. - // Override the Faceboook SDK to always handle the login using the web browser, which does not perform + // Override the Facebook SDK to always handle the login using the web browser, which does not perform // signature checks. val katanaProxyLoginMethodHandlerClass = katanaProxyLoginMethodHandlerClassFingerprint.originalClassDef diff --git a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/widgets/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/widgets/Fingerprints.kt index 0fc536047..3566512e8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/spotify/misc/widgets/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/spotify/misc/widgets/Fingerprints.kt @@ -1,7 +1,6 @@ package app.revanced.patches.spotify.misc.widgets import app.revanced.patcher.fingerprint -import app.revanced.util.indexOfFirstInstruction import com.android.tools.smali.dexlib2.Opcode internal val canBindAppWidgetPermissionFingerprint = fingerprint {