diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/GmsCoreSupport.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/GmsCoreSupport.java index 978ee7131a..993634eaba 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/GmsCoreSupport.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/GmsCoreSupport.java @@ -31,9 +31,6 @@ @SuppressWarnings("unused") public class GmsCoreSupport { - private static final String PACKAGE_NAME_YOUTUBE = "com.google.android.youtube"; - private static final String PACKAGE_NAME_YOUTUBE_MUSIC = "com.google.android.apps.youtube.music"; - private static final String GMS_CORE_PACKAGE_NAME = getGmsCoreVendorGroupId() + ".android.gms"; private static final Uri GMS_CORE_PROVIDER @@ -53,6 +50,20 @@ public class GmsCoreSupport { @Nullable private static volatile Boolean DONT_KILL_MY_APP_MANUFACTURER_SUPPORTED; + private static String getOriginalPackageName() { + return null; // Modified during patching. + } + + /** + * @return If the current package name is the same as the original unpatched app. + * If `GmsCore support` was not included during patching, this returns true; + */ + public static boolean isPackageNameOriginal() { + String originalPackageName = getOriginalPackageName(); + return originalPackageName == null + || originalPackageName.equals(Utils.getContext().getPackageName()); + } + private static void open(String queryOrLink) { Logger.printInfo(() -> "Opening link: " + queryOrLink); @@ -113,11 +124,10 @@ public static void checkGmsCore(Activity context) { // Verify the user has not included GmsCore for a root installation. // GmsCore Support changes the package name, but with a mounted installation // all manifest changes are ignored and the original package name is used. - String packageName = context.getPackageName(); - if (packageName.equals(PACKAGE_NAME_YOUTUBE) || packageName.equals(PACKAGE_NAME_YOUTUBE_MUSIC)) { + if (isPackageNameOriginal()) { Logger.printInfo(() -> "App is mounted with root, but GmsCore patch was included"); - // Cannot use localize text here, since the app will load - // resources from the unpatched app and all patch strings are missing. + // Cannot use localize text here, since the app will load resources + // from the unpatched app and all patch strings are missing. Utils.showToastLong("The 'GmsCore support' patch breaks mount installations"); // Do not exit. If the app exits before launch completes (and without @@ -250,8 +260,8 @@ private static String getGmsCoreDownload() { }; } - // Modified by a patch. Do not touch. private static String getGmsCoreVendorGroupId() { - return "app.revanced"; + // Modified during patching. + throw new IllegalStateException(); } } diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/CustomBrandingPatch.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/CustomBrandingPatch.java new file mode 100644 index 0000000000..79a4d54849 --- /dev/null +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/CustomBrandingPatch.java @@ -0,0 +1,136 @@ +package app.revanced.extension.shared.patches; + +import android.content.ComponentName; +import android.content.Context; +import android.content.pm.PackageManager; + +import java.util.ArrayList; +import java.util.List; + +import app.revanced.extension.shared.GmsCoreSupport; +import app.revanced.extension.shared.Logger; +import app.revanced.extension.shared.Utils; +import app.revanced.extension.shared.settings.BaseSettings; + +/** + * Patch shared by YouTube and YT Music. + */ +@SuppressWarnings("unused") +public class CustomBrandingPatch { + + // Important: In the future, additional branding themes can be added but all existing and prior + // themes cannot be removed or renamed. + // + // This is because if a user has a branding theme selected, then only that launch alias is enabled. + // If a future update removes or renames that alias, then after updating the app is effectively + // broken and it cannot be opened and not even clearing the app data will fix it. + // In that situation the only fix is to completely uninstall and reinstall again. + // + // The most that can be done is to hide a theme from the UI and keep the alias with dummy data. + public enum BrandingTheme { + /** + * Original unpatched icon. Must be first enum. + */ + ORIGINAL("revanced_original"), + ROUNDED("revanced_rounded"), + MINIMAL("revanced_minimal"), + SCALED("revanced_scaled"), + /** + * User provided custom icon. Must be the last enum. + */ + CUSTOM("revanced_custom"); + + public final String themeAlias; + + BrandingTheme(String themeAlias) { + this.themeAlias = themeAlias; + } + + private String packageAndNameIndexToClassAlias(String packageName, int appIndex) { + if (appIndex <= 0) { + throw new IllegalArgumentException("App index starts at index 1"); + } + return packageName + '.' + themeAlias + '_' + appIndex; + } + } + + /** + * Injection point. + * + * The total number of app name aliases, including dummy aliases. + */ + private static int numberOfPresetAppNames() { + // Modified during patching. + throw new IllegalStateException(); + } + + /** + * Injection point. + */ + @SuppressWarnings("ConstantConditions") + public static void setBranding() { + try { + if (GmsCoreSupport.isPackageNameOriginal()) { + Logger.printInfo(() -> "App is root mounted. Cannot dynamically change app icon"); + return; + } + + Context context = Utils.getContext(); + PackageManager pm = context.getPackageManager(); + String packageName = context.getPackageName(); + + BrandingTheme selectedBranding = BaseSettings.CUSTOM_BRANDING_ICON.get(); + final int selectedNameIndex = BaseSettings.CUSTOM_BRANDING_NAME.get(); + ComponentName componentToEnable = null; + ComponentName defaultComponent = null; + List componentsToDisable = new ArrayList<>(); + + for (BrandingTheme theme : BrandingTheme.values()) { + // Must always update all aliases including custom alias (last index). + final int numberOfPresetAppNames = numberOfPresetAppNames(); + + // App name indices starts at 1. + for (int index = 1; index <= numberOfPresetAppNames; index++) { + String aliasClass = theme.packageAndNameIndexToClassAlias(packageName, index); + ComponentName component = new ComponentName(packageName, aliasClass); + if (defaultComponent == null) { + // Default is always the first alias. + defaultComponent = component; + } + + if (index == selectedNameIndex && theme == selectedBranding) { + componentToEnable = component; + } else { + componentsToDisable.add(component); + } + } + } + + if (componentToEnable == null) { + // User imported a bad app name index value. Either the imported data + // was corrupted, or they previously had custom name enabled and the app + // no longer has a custom name specified. + Utils.showToastLong("Custom branding reset"); + BaseSettings.CUSTOM_BRANDING_ICON.resetToDefault(); + BaseSettings.CUSTOM_BRANDING_NAME.resetToDefault(); + + componentToEnable = defaultComponent; + componentsToDisable.remove(defaultComponent); + } + + for (ComponentName disable : componentsToDisable) { + // Use info logging because if the alias status become corrupt the app cannot launch. + Logger.printInfo(() -> "Disabling: " + disable.getClassName()); + pm.setComponentEnabledSetting(disable, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); + } + + ComponentName componentToEnableFinal = componentToEnable; + Logger.printInfo(() -> "Enabling: " + componentToEnableFinal.getClassName()); + pm.setComponentEnabledSetting(componentToEnable, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0); + } catch (Exception ex) { + Logger.printException(() -> "setBranding failure", ex); + } + } +} diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java index 1eff30361d..3bc16e313c 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/BaseSettings.java @@ -2,6 +2,7 @@ import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; +import static app.revanced.extension.shared.patches.CustomBrandingPatch.BrandingTheme; import static app.revanced.extension.shared.settings.Setting.parent; import static app.revanced.extension.shared.spoof.SpoofVideoStreamsPatch.AudioStreamLanguageOverrideAvailability; @@ -40,4 +41,7 @@ public class BaseSettings { public static final BooleanSetting REPLACE_MUSIC_LINKS_WITH_YOUTUBE = new BooleanSetting("revanced_replace_music_with_youtube", FALSE); public static final BooleanSetting CHECK_WATCH_HISTORY_DOMAIN_NAME = new BooleanSetting("revanced_check_watch_history_domain_name", TRUE, false, false); + + public static final EnumSetting CUSTOM_BRANDING_ICON = new EnumSetting<>("revanced_custom_branding_icon", BrandingTheme.ORIGINAL, true); + public static final IntegerSetting CUSTOM_BRANDING_NAME = new IntegerSetting("revanced_custom_branding_name", 1, true); } diff --git a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ReVancedAboutPreference.java b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ReVancedAboutPreference.java index be14e4a635..4f4d3ef928 100644 --- a/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ReVancedAboutPreference.java +++ b/extensions/shared/library/src/main/java/app/revanced/extension/shared/settings/preference/ReVancedAboutPreference.java @@ -5,6 +5,7 @@ import static app.revanced.extension.shared.requests.Route.Method.GET; import android.annotation.SuppressLint; +import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.content.Context; @@ -125,6 +126,8 @@ private String createDialogHtml(WebLink[] aboutLinks) { { setOnPreferenceClickListener(pref -> { + Context context = pref.getContext(); + // Show a progress spinner if the social links are not fetched yet. if (!AboutLinksRoutes.hasFetchedLinks() && Utils.isNetworkConnected()) { // Show a progress spinner, but only if the api fetch takes more than a half a second. @@ -137,17 +140,18 @@ private String createDialogHtml(WebLink[] aboutLinks) { handler.postDelayed(showDialogRunnable, delayToShowProgressSpinner); Utils.runOnBackgroundThread(() -> - fetchLinksAndShowDialog(handler, showDialogRunnable, progress)); + fetchLinksAndShowDialog(context, handler, showDialogRunnable, progress)); } else { // No network call required and can run now. - fetchLinksAndShowDialog(null, null, null); + fetchLinksAndShowDialog(context, null, null, null); } return false; }); } - private void fetchLinksAndShowDialog(@Nullable Handler handler, + private void fetchLinksAndShowDialog(Context context, + @Nullable Handler handler, Runnable showDialogRunnable, @Nullable ProgressDialog progress) { WebLink[] links = AboutLinksRoutes.fetchAboutLinks(); @@ -164,7 +168,17 @@ private void fetchLinksAndShowDialog(@Nullable Handler handler, if (handler != null) { handler.removeCallbacks(showDialogRunnable); } - if (progress != null) { + + // Don't continue if the activity is done. To test this tap the + // about dialog and immediately press back before the dialog can show. + if (context instanceof Activity activity) { + if (activity.isFinishing() || activity.isDestroyed()) { + Logger.printDebug(() -> "Not showing about dialog, activity is closed"); + return; + } + } + + if (progress != null && progress.isShowing()) { progress.dismiss(); } new WebViewDialog(getContext(), htmlDialog).show(); diff --git a/patches/api/patches.api b/patches/api/patches.api index c85acef50f..15b955acb8 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -1919,6 +1919,7 @@ public final class app/revanced/util/ResourceUtilsKt { public static final fun forEachChildElement (Lorg/w3c/dom/Node;Lkotlin/jvm/functions/Function1;)V public static final fun insertFirst (Lorg/w3c/dom/Node;Lorg/w3c/dom/Node;)V public static final fun iterateXmlNodeChildren (Lapp/revanced/patcher/patch/ResourcePatchContext;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public static final fun removeFromParent (Lorg/w3c/dom/Node;)Lorg/w3c/dom/Node; } public final class app/revanced/util/resource/ArrayResource : app/revanced/util/resource/BaseResource { diff --git a/patches/src/main/kotlin/app/revanced/patches/music/layout/branding/CustomBrandingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/music/layout/branding/CustomBrandingPatch.kt index 530e981303..6f0f460263 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/layout/branding/CustomBrandingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/layout/branding/CustomBrandingPatch.kt @@ -4,6 +4,10 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWith import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.music.misc.gms.Constants.MUSIC_MAIN_ACTIVITY_NAME +import app.revanced.patches.music.misc.gms.Constants.MUSIC_PACKAGE_NAME +import app.revanced.patches.music.misc.gms.musicActivityOnCreateFingerprint +import app.revanced.patches.music.misc.settings.PreferenceScreen import app.revanced.patches.shared.layout.branding.baseCustomBrandingPatch import app.revanced.patches.shared.misc.mapping.get import app.revanced.patches.shared.misc.mapping.resourceMappingPatch @@ -50,24 +54,18 @@ private val disableSplashAnimationPatch = bytecodePatch { } } -private const val APP_NAME = "YT Music ReVanced" - @Suppress("unused") val customBrandingPatch = baseCustomBrandingPatch( - defaultAppName = APP_NAME, - appNameValues = mapOf( - "YT Music ReVanced" to APP_NAME, - "Music ReVanced" to "Music ReVanced", - "Music" to "Music", - "YT Music" to "YT Music", - ), - resourceFolder = "custom-branding/music", - iconResourceFileNames = arrayOf( - "adaptiveproduct_youtube_music_2024_q4_background_color_108", - "adaptiveproduct_youtube_music_2024_q4_foreground_color_108", - "ic_launcher_release", - ), - monochromeIconFileNames = arrayOf("ic_app_icons_themed_youtube_music.xml"), + addResourcePatchName = "music", + originalLauncherIconName = "ic_launcher_release", + originalAppName = "@string/app_launcher_name", + originalAppPackageName = MUSIC_PACKAGE_NAME, + copyExistingIntentsToAliases = false, + numberOfPresetAppNames = 5, + mainActivityOnCreateFingerprint = musicActivityOnCreateFingerprint, + mainActivityName = MUSIC_MAIN_ACTIVITY_NAME, + activityAliasNameWithIntents = MUSIC_MAIN_ACTIVITY_NAME, + preferenceScreen = PreferenceScreen.GENERAL, block = { dependsOn(disableSplashAnimationPatch) diff --git a/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/Constants.kt index f4114a00b2..39dda22aa2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/music/misc/gms/Constants.kt @@ -1,6 +1,8 @@ package app.revanced.patches.music.misc.gms object Constants { + internal const val MUSIC_MAIN_ACTIVITY_NAME = "com.google.android.apps.youtube.music.activities.MusicActivity" + internal const val REVANCED_MUSIC_PACKAGE_NAME = "app.revanced.android.apps.youtube.music" internal const val MUSIC_PACKAGE_NAME = "com.google.android.apps.youtube.music" } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/BaseCustomBrandingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/BaseCustomBrandingPatch.kt index d865b2081c..d8356aee03 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/BaseCustomBrandingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/BaseCustomBrandingPatch.kt @@ -1,173 +1,387 @@ package app.revanced.patches.shared.layout.branding +import app.revanced.patcher.Fingerprint +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.ResourcePatch import app.revanced.patcher.patch.ResourcePatchBuilder import app.revanced.patcher.patch.ResourcePatchContext +import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.patch.stringOption +import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName +import app.revanced.patches.all.misc.resources.addResources +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.ListPreference import app.revanced.util.ResourceGroup import app.revanced.util.Utils.trimIndentMultiline import app.revanced.util.copyResources +import app.revanced.util.findElementByAttributeValueOrThrow +import app.revanced.util.removeFromParent +import app.revanced.util.returnEarly +import org.w3c.dom.Element +import org.w3c.dom.Node +import org.w3c.dom.NodeList import java.io.File -import java.nio.file.Files import java.util.logging.Logger -private const val REVANCED_ICON = "ReVanced*Logo" // Can never be a valid path. - -internal val mipmapDirectories = arrayOf( +private val mipmapDirectories = arrayOf( // Target app does not have ldpi icons. - "mdpi", - "hdpi", - "xhdpi", - "xxhdpi", - "xxxhdpi", -).map { "mipmap-$it" }.toTypedArray() + "mipmap-mdpi", + "mipmap-hdpi", + "mipmap-xhdpi", + "mipmap-xxhdpi", + "mipmap-xxxhdpi" +) -private fun formatResourceFileList(resourceNames: Array) = resourceNames.joinToString("\n") { "- $it" } +private val iconStyleNames = arrayOf( + "rounded", + "minimal", + "scaled" +) -/** - * Attempts to fix unescaped and invalid characters not allowed for an Android app name. - */ -private fun escapeAppName(name: String): String? { - // Remove ASCII control characters. - val cleanedName = name.filter { it.code >= 32 } +private const val ORIGINAL_USER_ICON_STYLE_NAME = "original" +private const val CUSTOM_USER_ICON_STYLE_NAME = "custom" - // Replace invalid XML characters with escaped equivalents. - val escapedName = cleanedName - .replace("&", "&") // Must be first to avoid double-escaping. - .replace("<", "<") - .replace(">", ">") - .replace(Regex("(?, - resourceFolder: String, - iconResourceFileNames: Array, - monochromeIconFileNames: Array, - block: ResourcePatchBuilder.() -> Unit = {}, + addResourcePatchName: String, + originalLauncherIconName: String, + originalAppName: String, + originalAppPackageName: String, + copyExistingIntentsToAliases: Boolean, + numberOfPresetAppNames: Int, + mainActivityOnCreateFingerprint: Fingerprint, + mainActivityName: String, + activityAliasNameWithIntents: String, + preferenceScreen: BasePreferenceScreen.Screen, + block: ResourcePatchBuilder.() -> Unit, executeBlock: ResourcePatchContext.() -> Unit = {} ): ResourcePatch = resourcePatch( name = "Custom branding", - description = "Applies a custom app name and icon. Defaults to \"$defaultAppName\" and the ReVanced logo.", - use = false, + description = "Adds options to change the app icon and app name. " + + "Branding cannot be changed for mounted (root) installations." ) { - val iconResourceFileNamesPng = iconResourceFileNames.map { "$it.png" }.toTypedArray() - - val appName by stringOption( - key = "appName", - default = defaultAppName, - values = appNameValues, + val customName by stringOption( + key = "customName", title = "App name", - description = "The name of the app.", + description = "Custom app name." ) - val iconPath by stringOption( - key = "iconPath", - default = REVANCED_ICON, - values = mapOf("ReVanced Logo" to REVANCED_ICON), - title = "App icon", + val customIcon by stringOption( + key = "customIcon", + title = "Custom icon", description = """ - The icon to apply to the app. + Folder with images to use as a custom icon. - If a path to a folder is provided, the folder must contain the following folders: - - ${formatResourceFileList(mipmapDirectories)} - - Each of these folders must contain the following files: - - ${formatResourceFileList(iconResourceFileNamesPng)} + The folder must contain one or more of the following folders, depending on the DPI of the device: + ${mipmapDirectories.joinToString("\n") { "- $it" }} - Optionally, a 'drawable' folder with the monochrome icon files: - - ${formatResourceFileList(monochromeIconFileNames)} - """.trimIndentMultiline(), + Each of the folders must contain all of the following files: + ${USER_CUSTOM_ADAPTIVE_FILE_NAMES.joinToString("\n")} + + Optionally, the path can contain a 'drawable' folder with the monochrome icon file: + $USER_CUSTOM_MONOCHROME_NAME + """.trimIndentMultiline() ) block() + dependsOn( + addResourcesPatch, + bytecodePatch { + execute { + mainActivityOnCreateFingerprint.method.addInstruction( + 0, + "invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->setBranding()V" + ) + + numberOfPresetAppNamesExtensionFingerprint.method.returnEarly(numberOfPresetAppNames) + } + } + ) + + finalize { + val useCustomName = customName != null + val useCustomIcon = customIcon != null + + if (setOrGetFallbackPackageName(originalAppPackageName) == originalAppPackageName) { + if (useCustomName || useCustomIcon) { + Logger.getLogger(this::class.java.name).warning( + "Custom branding does not work with root installation. No changes applied." + ) + } + return@finalize + } + + preferenceScreen.addPreferences( + if (useCustomName) { + ListPreference( + key = "revanced_custom_branding_name", + entriesKey = "revanced_custom_branding_name_custom_entries", + entryValuesKey = "revanced_custom_branding_name_custom_entry_values" + ) + } else { + ListPreference("revanced_custom_branding_name") + }, + if (useCustomIcon) { + ListPreference( + key = "revanced_custom_branding_icon", + entriesKey = "revanced_custom_branding_icon_custom_entries", + entryValuesKey = "revanced_custom_branding_icon_custom_entry_values" + ) + } else { + ListPreference("revanced_custom_branding_icon") + } + ) + } + execute { - val mipmapIconResourceGroups = mipmapDirectories.map { directory -> + addResources("shared", "layout.branding.baseCustomBrandingPatch") + addResources(addResourcePatchName, "layout.branding.customBrandingPatch") + + val useCustomName = customName != null + val useCustomIcon = customIcon != null + + iconStyleNames.forEach { style -> + copyResources( + "custom-branding", + ResourceGroup( + "drawable", + "$LAUNCHER_ADAPTIVE_BACKGROUND_PREFIX$style.xml", + "$LAUNCHER_ADAPTIVE_FOREGROUND_PREFIX$style.xml", + "$LAUNCHER_ADAPTIVE_MONOCHROME_PREFIX$style.xml" + ), + ResourceGroup( + "mipmap-anydpi", + "$LAUNCHER_RESOURCE_NAME_PREFIX$style.xml" + ) + ) + } + + // Copy template user icon, because the aliases must be added even if no user icon is provided. + copyResources( + "custom-branding", + ResourceGroup( + "mipmap-anydpi", + "$LAUNCHER_RESOURCE_NAME_PREFIX$CUSTOM_USER_ICON_STYLE_NAME.xml", + ), ResourceGroup( - directory, - *iconResourceFileNamesPng, + "drawable", + "$LAUNCHER_ADAPTIVE_MONOCHROME_PREFIX$CUSTOM_USER_ICON_STYLE_NAME.xml", + ) + ) + + // Copy template icon png files. + mipmapDirectories.forEach { dpi -> + copyResources( + "custom-branding", + ResourceGroup( + dpi, + "$LAUNCHER_ADAPTIVE_BACKGROUND_PREFIX$CUSTOM_USER_ICON_STYLE_NAME.png", + "$LAUNCHER_ADAPTIVE_FOREGROUND_PREFIX$CUSTOM_USER_ICON_STYLE_NAME.png", + ) ) } - val iconPathTrimmed = iconPath!!.trim() - if (iconPathTrimmed == REVANCED_ICON) { - // Replace mipmap icons with preset patch icons. - mipmapIconResourceGroups.forEach { groupResources -> - copyResources(resourceFolder, groupResources) + if (useCustomIcon) { + // Copy user provided files + val iconPathFile = File(customIcon!!.trim()) + + if (!iconPathFile.exists()) { + throw PatchException( + "The custom icon path cannot be found: " + iconPathFile.absolutePath + ) } - // Replace monochrome icons. - monochromeIconFileNames.forEach { fileName -> - copyResources( - resourceFolder, - ResourceGroup("drawable", fileName) + if (!iconPathFile.isDirectory) { + throw PatchException( + "The custom icon path must be a folder: " + iconPathFile.absolutePath ) } - } else { - val filePath = File(iconPathTrimmed) + + val sourceFolders = iconPathFile.listFiles { file -> file.isDirectory } + ?: throw PatchException("The custom icon path contains no subfolders: " + + iconPathFile.absolutePath) + val resourceDirectory = get("res") + var copiedFiles = false - // Replace - mipmapIconResourceGroups.forEach { groupResources -> - val groupResourceDirectoryName = groupResources.resourceDirectoryName - val fromDirectory = filePath.resolve(groupResourceDirectoryName) - val toDirectory = resourceDirectory.resolve(groupResourceDirectoryName) + // For each source folder, copy the files to the target resource directories. + sourceFolders.forEach { dpiSourceFolder -> + val targetDpiFolder = resourceDirectory.resolve(dpiSourceFolder.name) + if (!targetDpiFolder.exists()) return@forEach - groupResources.resources.forEach { iconFileName -> - Files.write( - toDirectory.resolve(iconFileName).toPath(), - fromDirectory.resolve(iconFileName).readBytes(), - ) + val customFiles = dpiSourceFolder.listFiles { file -> + file.isFile && file.name in USER_CUSTOM_ADAPTIVE_FILE_NAMES + }!! + + if (customFiles.size > 0 && customFiles.size != USER_CUSTOM_ADAPTIVE_FILE_NAMES.size) { + throw PatchException("Must include all required icon files " + + "but only found " + customFiles.map { it.name }) } - } - // Copy all monochrome icons if provided. - monochromeIconFileNames.forEach { fileName -> - val replacementMonochrome = filePath.resolve("drawable").resolve(fileName) - if (replacementMonochrome.exists()) { - Files.write( - resourceDirectory.resolve("drawable").resolve(fileName).toPath(), - replacementMonochrome.readBytes(), - ) + customFiles.forEach { imgSourceFile -> + val imgTargetFile = targetDpiFolder.resolve(imgSourceFile.name) + imgSourceFile.copyTo(target = imgTargetFile, overwrite = true) + + copiedFiles = true } } + + // Copy monochrome if it provided. + val monochromeRelativePath = "drawable/$USER_CUSTOM_MONOCHROME_NAME" + val monochromeFile = iconPathFile.resolve(monochromeRelativePath) + if (monochromeFile.exists()) { + monochromeFile.copyTo( + target = resourceDirectory.resolve(monochromeRelativePath), + overwrite = true + ) + copiedFiles = true + } + + if (!copiedFiles) { + throw PatchException("Could not find any replacement images in " + + "patch option path: " + iconPathFile.absolutePath) + } } - // Change the app name. - escapeAppName(appName!!)?.let { escapedAppName -> - val newValue = "android:label=\"$escapedAppName\"" + document("AndroidManifest.xml").use { document -> + // Create launch aliases that can be programmatically selected in app. + fun createAlias( + aliasName: String, + iconMipmapName: String, + appNameIndex: Int, + useCustomName: Boolean, + enabled: Boolean, + intents: NodeList + ): Element { + val label = if (useCustomName) { + if (customName == null) { + "Custom" // Dummy text, and normally cannot be seen. + } else { + customName!! + } + } else if (appNameIndex == 1) { + // Indexing starts at 1. + originalAppName + } else { + "@string/revanced_custom_branding_name_entry_$appNameIndex" + } + val alias = document.createElement("activity-alias") + alias.setAttribute("android:name", aliasName) + alias.setAttribute("android:enabled", enabled.toString()) + alias.setAttribute("android:exported", "true") + alias.setAttribute("android:icon", "@mipmap/$iconMipmapName") + alias.setAttribute("android:label", label) + alias.setAttribute("android:targetActivity", mainActivityName) + + // Copy all intents from the original alias so long press actions still work. + if (copyExistingIntentsToAliases) { + for (i in 0 until intents.length) { + alias.appendChild( + intents.item(i).cloneNode(true) + ) + } + } else { + val intentFilter = document.createElement("intent-filter").apply { + val action = document.createElement("action") + action.setAttribute("android:name", "android.intent.action.MAIN") + appendChild(action) - val manifest = get("AndroidManifest.xml") - val original = manifest.readText() - val replacement = original - // YouTube - .replace("android:label=\"@string/application_name\"", newValue) - // YT Music - .replace("android:label=\"@string/app_launcher_name\"", newValue) + val category = document.createElement("category") + category.setAttribute("android:name", "android.intent.category.LAUNCHER") + appendChild(category) + } + alias.appendChild(intentFilter) + } - if (original == replacement) { - Logger.getLogger(this::class.java.name).warning( - "Could not replace manifest app name" + return alias + } + + val intentFilters = document.childNodes.findElementByAttributeValueOrThrow( + "android:name", + activityAliasNameWithIntents + ).childNodes + + val application = document.getElementsByTagName("application").item(0) as Element + + for (appNameIndex in 1 .. numberOfPresetAppNames) { + fun aliasName(name: String): String = ".revanced_" + name + '_' + appNameIndex + + val useCustomNameLabel = (useCustomName && appNameIndex == numberOfPresetAppNames) + + // Original icon. + application.appendChild( + createAlias( + aliasName = aliasName(ORIGINAL_USER_ICON_STYLE_NAME), + iconMipmapName = originalLauncherIconName, + appNameIndex = appNameIndex, + useCustomName = useCustomNameLabel, + enabled = (appNameIndex == 1), + intentFilters + ) + ) + + // Bundled icons. + iconStyleNames.forEachIndexed { index, style -> + application.appendChild( + createAlias( + aliasName = aliasName(style), + iconMipmapName = LAUNCHER_RESOURCE_NAME_PREFIX + style, + appNameIndex = appNameIndex, + useCustomName = useCustomNameLabel, + enabled = false, + intentFilters + ) + ) + } + + // User provided custom icon. + // + // Must add all aliases even if the user did not provide a custom icon of their own. + // This is because if the user installs with an option, then repatches without the option, + // the alias must still exist because if it was previously enabled and then it's removed + // the app will become broken and cannot launch. Even if the app data is cleared + // it still cannot be launched and the only fix is to uninstall the app. + // To prevent this, always include all aliases and use dummy data if needed. + application.appendChild( + createAlias( + aliasName = aliasName(CUSTOM_USER_ICON_STYLE_NAME), + iconMipmapName = LAUNCHER_RESOURCE_NAME_PREFIX + CUSTOM_USER_ICON_STYLE_NAME, + appNameIndex = appNameIndex, + useCustomName = useCustomNameLabel, + enabled = false, + intentFilters + ) ) } - manifest.writeText(replacement) + // Remove the main action from the original alias, otherwise two apps icons + // can be shown in the launcher. Can only be done after adding the new aliases. + intentFilters.findElementByAttributeValueOrThrow( + "android:name", + "android.intent.action.MAIN" + ).removeFromParent() } - executeBlock() // Must be after the main code to rename the new icons for YouTube 19.34+. + executeBlock() } } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/Fingerprints.kt new file mode 100644 index 0000000000..c46cb1a883 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/shared/layout/branding/Fingerprints.kt @@ -0,0 +1,13 @@ +package app.revanced.patches.shared.layout.branding + +import app.revanced.patcher.fingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +internal val numberOfPresetAppNamesExtensionFingerprint = fingerprint { + accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) + returns("I") + parameters() + custom { method, classDef -> + method.name == "numberOfPresetAppNames" && classDef.type == EXTENSION_CLASS_DESCRIPTOR + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/BaseThemePatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/BaseThemePatch.kt index de070fb89f..40fb779806 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/BaseThemePatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/layout/theme/BaseThemePatch.kt @@ -79,7 +79,7 @@ internal val darkThemeBackgroundColorOption = stringOption( */ internal fun baseThemePatch( extensionClassDescriptor: String, - block: BytecodePatchBuilder.() -> Unit = {}, + block: BytecodePatchBuilder.() -> Unit, executeBlock: BytecodePatchContext.() -> Unit = {} ) = bytecodePatch( name = "Theme", diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt index b5f613d541..27eebb8ab0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/Fingerprints.kt @@ -1,16 +1,11 @@ package app.revanced.patches.shared.misc.gms import app.revanced.patcher.fingerprint +import app.revanced.patches.shared.misc.gms.EXTENSION_CLASS_DESCRIPTOR import com.android.tools.smali.dexlib2.AccessFlags const val GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME = "getGmsCoreVendorGroupId" -internal val gmsCoreSupportFingerprint = fingerprint { - custom { _, classDef -> - classDef.endsWith("GmsCoreSupport;") - } -} - internal val googlePlayUtilityFingerprint = fingerprint { accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) returns("I") @@ -28,3 +23,21 @@ internal val serviceCheckFingerprint = fingerprint { parameters("L", "I") strings("Google Play Services not available") } + +internal val gmsCoreSupportFingerprint = fingerprint { + accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) + returns("Ljava/lang/String;") + parameters() + custom { method, classDef -> + method.name == "getGmsCoreVendorGroupId" && classDef.type == EXTENSION_CLASS_DESCRIPTOR + } +} + +internal val originalPackageNameExtensionFingerprint = fingerprint { + accessFlags(AccessFlags.PRIVATE, AccessFlags.STATIC) + returns("Ljava/lang/String;") + parameters() + custom { methodDef, classDef -> + methodDef.name == "getOriginalPackageName" && classDef.type == EXTENSION_CLASS_DESCRIPTOR + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt index ef8743fda4..fb773457f8 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/gms/GmsCoreSupportPatch.kt @@ -1,10 +1,18 @@ package app.revanced.patches.shared.misc.gms import app.revanced.patcher.Fingerprint -import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.instructions import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction -import app.revanced.patcher.patch.* +import app.revanced.patcher.patch.BytecodePatchBuilder +import app.revanced.patcher.patch.BytecodePatchContext +import app.revanced.patcher.patch.Option +import app.revanced.patcher.patch.Patch +import app.revanced.patcher.patch.ResourcePatchBuilder +import app.revanced.patcher.patch.ResourcePatchContext +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patcher.patch.resourcePatch +import app.revanced.patcher.patch.stringOption import app.revanced.patches.all.misc.packagename.changePackageNamePatch import app.revanced.patches.all.misc.packagename.setOrGetFallbackPackageName import app.revanced.patches.all.misc.resources.addResources @@ -12,7 +20,8 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch import app.revanced.patches.shared.misc.gms.Constants.ACTIONS import app.revanced.patches.shared.misc.gms.Constants.AUTHORITIES import app.revanced.patches.shared.misc.gms.Constants.PERMISSIONS -import app.revanced.util.* +import app.revanced.util.getReference +import app.revanced.util.returnEarly import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.builder.instruction.BuilderInstruction21c import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction @@ -23,6 +32,8 @@ import com.android.tools.smali.dexlib2.util.MethodUtil import org.w3c.dom.Element import org.w3c.dom.Node +internal const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/shared/GmsCoreSupport;" + private const val PACKAGE_NAME_REGEX_PATTERN = "^[a-z]\\w*(\\.[a-z]\\w*)+\$" /** @@ -201,19 +212,18 @@ fun gmsCoreSupportPatch( googlePlayUtilityFingerprint.method.returnEarly(0) } + // Set original and patched package names for extension to use. + originalPackageNameExtensionFingerprint.method.returnEarly(fromPackageName) + // Verify GmsCore is installed and whitelisted for power optimizations and background usage. - mainActivityOnCreateFingerprint.method.apply { - addInstructions( - 0, - "invoke-static/range { p0 .. p0 }, Lapp/revanced/extension/shared/GmsCoreSupport;->" + - "checkGmsCore(Landroid/app/Activity;)V", - ) - } + mainActivityOnCreateFingerprint.method.addInstruction( + 0, + "invoke-static/range { p0 .. p0 }, $EXTENSION_CLASS_DESCRIPTOR->" + + "checkGmsCore(Landroid/app/Activity;)V" + ) // Change the vendor of GmsCore in the extension. - gmsCoreSupportFingerprint.classDef.methods - .single { it.name == GET_GMS_CORE_VENDOR_GROUP_ID_METHOD_NAME } - .replaceInstruction(0, "const-string v0, \"$gmsCoreVendorGroupId\"") + gmsCoreSupportFingerprint.method.returnEarly(gmsCoreVendorGroupId!!) executeBlock() } diff --git a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt index 7c1c58410d..7395c3983d 100644 --- a/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/shared/misc/spoof/SpoofVideoStreamsPatch.kt @@ -43,7 +43,7 @@ internal fun spoofVideoStreamsPatch( fixMediaFetchHotConfig: BytecodePatchBuilder.() -> Boolean = { false }, fixMediaFetchHotConfigAlternative: BytecodePatchBuilder.() -> Boolean = { false }, fixParsePlaybackResponseFeatureFlag: BytecodePatchBuilder.() -> Boolean = { false }, - block: BytecodePatchBuilder.() -> Unit = {}, + block: BytecodePatchBuilder.() -> Unit, executeBlock: BytecodePatchContext.() -> Unit = {}, ) = bytecodePatch( name = "Spoof video streams", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt index ca028c4388..2294ef9b20 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/CustomBrandingPatch.kt @@ -1,38 +1,28 @@ package app.revanced.patches.youtube.layout.branding import app.revanced.patches.shared.layout.branding.baseCustomBrandingPatch -import app.revanced.patches.shared.layout.branding.mipmapDirectories -import java.nio.file.Files - -private const val APP_NAME = "YouTube ReVanced" - -private val youtubeIconResourceFileNames_19_34 = mapOf( - "adaptiveproduct_youtube_foreground_color_108" to "adaptiveproduct_youtube_2024_q4_foreground_color_108", - "adaptiveproduct_youtube_background_color_108" to "adaptiveproduct_youtube_2024_q4_background_color_108", -) +import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch +import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_MAIN_ACTIVITY_NAME +import app.revanced.patches.youtube.misc.gms.Constants.YOUTUBE_PACKAGE_NAME +import app.revanced.patches.youtube.misc.settings.PreferenceScreen +import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint @Suppress("unused") val customBrandingPatch = baseCustomBrandingPatch( - defaultAppName = APP_NAME, - appNameValues = mapOf( - "YouTube ReVanced" to APP_NAME, - "YT ReVanced" to "YT ReVanced", - "YT" to "YT", - "YouTube" to "YouTube", - ), - resourceFolder = "custom-branding/youtube", - iconResourceFileNames = arrayOf( - "adaptiveproduct_youtube_background_color_108", - "adaptiveproduct_youtube_foreground_color_108", - "ic_launcher", - "ic_launcher_round", - ), - monochromeIconFileNames = arrayOf( - "adaptive_monochrome_ic_youtube_launcher.xml", - "ringo2_adaptive_monochrome_ic_youtube_launcher.xml" - ), + addResourcePatchName = "youtube", + originalLauncherIconName = "ic_launcher", + originalAppName = "@string/application_name", + originalAppPackageName = YOUTUBE_PACKAGE_NAME, + copyExistingIntentsToAliases = true, + numberOfPresetAppNames = 5, + mainActivityOnCreateFingerprint = mainActivityOnCreateFingerprint, + mainActivityName = YOUTUBE_MAIN_ACTIVITY_NAME, + activityAliasNameWithIntents = "com.google.android.youtube.app.honeycomb.Shell\$HomeActivity", + preferenceScreen = PreferenceScreen.GENERAL_LAYOUT, block = { + dependsOn(sharedExtensionPatch) + compatibleWith( "com.google.android.youtube"( "19.34.42", @@ -41,20 +31,5 @@ val customBrandingPatch = baseCustomBrandingPatch( "20.14.43", ) ) - }, - - executeBlock = { - val resourceDirectory = get("res") - - mipmapDirectories.forEach { directory -> - val targetDirectory = resourceDirectory.resolve(directory) - - youtubeIconResourceFileNames_19_34.forEach { (old, new) -> - val oldFile = targetDirectory.resolve("$old.png") - val newFile = targetDirectory.resolve("$new.png") - - Files.write(newFile.toPath(), oldFile.readBytes()) - } - } } ) diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt index fa02fcc296..26a10aacf2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/branding/header/ChangeHeaderPatch.kt @@ -136,8 +136,21 @@ val changeHeaderPatch = resourcePatch( ) if (custom != null) { - val sourceFolders = File(custom!!).listFiles { file -> file.isDirectory } - ?: throw PatchException("The provided path is not a directory: $custom") + val customFile = File(custom!!) + if (!customFile.exists()) { + throw PatchException("The custom icon path cannot be found: " + + customFile.absolutePath + ) + } + + if (!customFile.isDirectory) { + throw PatchException("The custom icon path must be a folder: " + + customFile.absolutePath) + } + + val sourceFolders = customFile.listFiles { file -> file.isDirectory } + ?: throw PatchException("The custom icon path contains no subfolders: " + + customFile.absolutePath) val customResourceFileNames = getLightDarkFileNames(CUSTOM_HEADER_RESOURCE_NAME) @@ -166,7 +179,8 @@ val changeHeaderPatch = resourcePatch( } if (!copiedFiles) { - throw PatchException("No custom header images found in the provided path: $custom") + throw PatchException("No custom header images found in " + + "the provided path: " + customFile.absolutePath) } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt index f94b27099b..de715d06c2 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/hide/shorts/HideShortsComponentsPatch.kt @@ -27,6 +27,7 @@ import app.revanced.util.forEachLiteralValueInstruction import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstLiteralInstruction +import app.revanced.util.removeFromParent import app.revanced.util.returnLate import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference @@ -127,7 +128,7 @@ private val hideShortsComponentsResourcePatch = resourcePatch { ) if (hideShortsAppShortcut == true) { - shortsItem.parentNode.removeChild(shortsItem) + shortsItem.removeFromParent() } } @@ -138,7 +139,7 @@ private val hideShortsComponentsResourcePatch = resourcePatch { ) if (hideShortsWidget == true) { - shortsItem.parentNode.removeChild(shortsItem) + shortsItem.removeFromParent() } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Constants.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Constants.kt index c532c57d4a..19f0454bad 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Constants.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/gms/Constants.kt @@ -1,6 +1,8 @@ package app.revanced.patches.youtube.misc.gms internal object Constants { + internal const val YOUTUBE_MAIN_ACTIVITY_NAME = "com.google.android.apps.youtube.app.watchwhile.MainActivity" + const val YOUTUBE_PACKAGE_NAME = "com.google.android.youtube" const val REVANCED_YOUTUBE_PACKAGE_NAME = "app.revanced.android.youtube" } \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/util/ResourceUtils.kt b/patches/src/main/kotlin/app/revanced/util/ResourceUtils.kt index 61d7be3502..b2d8ba287f 100644 --- a/patches/src/main/kotlin/app/revanced/util/ResourceUtils.kt +++ b/patches/src/main/kotlin/app/revanced/util/ResourceUtils.kt @@ -14,6 +14,13 @@ import java.nio.file.StandardCopyOption private val classLoader = object {}.javaClass.classLoader +/** + * Removes a node from its parent. + * + * @return The node that was removed (object this method was called on). + */ +fun Node.removeFromParent() : Node = parentNode.removeChild(this) + /** * Returns a sequence for all child nodes. */ @@ -70,8 +77,13 @@ fun ResourcePatchContext.copyResources( for (resourceGroup in resources) { resourceGroup.resources.forEach { resource -> val resourceFile = "${resourceGroup.resourceDirectoryName}/$resource" + val stream = inputStreamFromBundledResource(sourceResourceDirectory, resourceFile) + if (stream == null) { + throw IllegalArgumentException("Could not find resource: $resourceFile " + + "in directory: $sourceResourceDirectory") + } Files.copy( - inputStreamFromBundledResource(sourceResourceDirectory, resourceFile)!!, + stream, targetResourceDirectory.resolve(resourceFile).toPath(), StandardCopyOption.REPLACE_EXISTING, ) diff --git a/patches/src/main/resources/addresources/values/arrays.xml b/patches/src/main/resources/addresources/values/arrays.xml index 3faa7cdbeb..980f0c20c5 100644 --- a/patches/src/main/resources/addresources/values/arrays.xml +++ b/patches/src/main/resources/addresources/values/arrays.xml @@ -1,5 +1,33 @@ + + + @string/revanced_custom_branding_icon_entry_1 + @string/revanced_custom_branding_icon_entry_2 + @string/revanced_custom_branding_icon_entry_3 + @string/revanced_custom_branding_icon_entry_4 + + + ORIGINAL + ROUNDED + MINIMAL + SCALED + + + @string/revanced_custom_branding_icon_entry_1 + @string/revanced_custom_branding_icon_entry_2 + @string/revanced_custom_branding_icon_entry_3 + @string/revanced_custom_branding_icon_entry_4 + @string/revanced_custom_branding_icon_entry_5 + + + ORIGINAL + ROUNDED + MINIMAL + SCALED + CUSTOM + + @string/revanced_language_DEFAULT @@ -123,6 +151,36 @@ + + + + @string/app_launcher_name + @string/revanced_custom_branding_name_entry_2 + @string/revanced_custom_branding_name_entry_3 + @string/revanced_custom_branding_name_entry_4 + + + 1 + 2 + 3 + 4 + + + + @string/app_launcher_name + @string/revanced_custom_branding_name_entry_2 + @string/revanced_custom_branding_name_entry_3 + @string/revanced_custom_branding_name_entry_4 + @string/revanced_custom_branding_name_entry_5 + + + 1 + 2 + 3 + 4 + 5 + + Android VR @@ -135,6 +193,36 @@ + + + + @string/application_name + @string/revanced_custom_branding_name_entry_2 + @string/revanced_custom_branding_name_entry_3 + @string/revanced_custom_branding_name_entry_4 + + + 1 + 2 + 3 + 4 + + + + @string/application_name + @string/revanced_custom_branding_name_entry_2 + @string/revanced_custom_branding_name_entry_3 + @string/revanced_custom_branding_name_entry_4 + @string/revanced_custom_branding_name_entry_5 + + + 1 + 2 + 3 + 4 + 5 + + Android VR diff --git a/patches/src/main/resources/addresources/values/strings.xml b/patches/src/main/resources/addresources/values/strings.xml index 2461191bbf..1b464b3829 100644 --- a/patches/src/main/resources/addresources/values/strings.xml +++ b/patches/src/main/resources/addresources/values/strings.xml @@ -19,6 +19,19 @@ Second \"item\" text" --> + + App name + + Custom + App icon + Original + ReVanced + + ReVanced minimal + ReVanced scaled + + Custom + Checks failed Open official website @@ -1484,13 +1497,18 @@ Swipe to expand or close" The accent color of the seekbar Invalid seekbar color value + + YouTube ReVanced + YT ReVanced + YT + Header logo Default Regular Premium ReVanced - + ReVanced minimal Custom @@ -1708,6 +1726,11 @@ Video playback with AV1 may stutter or drop frames." + + YT Music ReVanced + Music ReVanced + Music + About Ads diff --git a/patches/src/main/resources/change-header/drawable-hdpi/revanced_header_logo_minimal_dark.png b/patches/src/main/resources/change-header/drawable-hdpi/revanced_header_logo_minimal_dark.png index c2995578d9..bf0c300aab 100644 Binary files a/patches/src/main/resources/change-header/drawable-hdpi/revanced_header_logo_minimal_dark.png and b/patches/src/main/resources/change-header/drawable-hdpi/revanced_header_logo_minimal_dark.png differ diff --git a/patches/src/main/resources/change-header/drawable-hdpi/revanced_header_logo_minimal_light.png b/patches/src/main/resources/change-header/drawable-hdpi/revanced_header_logo_minimal_light.png index 9bd381fc75..7434d79a54 100644 Binary files a/patches/src/main/resources/change-header/drawable-hdpi/revanced_header_logo_minimal_light.png and b/patches/src/main/resources/change-header/drawable-hdpi/revanced_header_logo_minimal_light.png differ diff --git a/patches/src/main/resources/change-header/drawable-mdpi/revanced_header_logo_minimal_dark.png b/patches/src/main/resources/change-header/drawable-mdpi/revanced_header_logo_minimal_dark.png index 834b0690b4..9206e9f3d5 100644 Binary files a/patches/src/main/resources/change-header/drawable-mdpi/revanced_header_logo_minimal_dark.png and b/patches/src/main/resources/change-header/drawable-mdpi/revanced_header_logo_minimal_dark.png differ diff --git a/patches/src/main/resources/change-header/drawable-mdpi/revanced_header_logo_minimal_light.png b/patches/src/main/resources/change-header/drawable-mdpi/revanced_header_logo_minimal_light.png index e147d3f6bf..0e52e1a247 100644 Binary files a/patches/src/main/resources/change-header/drawable-mdpi/revanced_header_logo_minimal_light.png and b/patches/src/main/resources/change-header/drawable-mdpi/revanced_header_logo_minimal_light.png differ diff --git a/patches/src/main/resources/change-header/drawable-xhdpi/revanced_header_logo_minimal_dark.png b/patches/src/main/resources/change-header/drawable-xhdpi/revanced_header_logo_minimal_dark.png index 8586ec0363..b33a7c41fe 100644 Binary files a/patches/src/main/resources/change-header/drawable-xhdpi/revanced_header_logo_minimal_dark.png and b/patches/src/main/resources/change-header/drawable-xhdpi/revanced_header_logo_minimal_dark.png differ diff --git a/patches/src/main/resources/change-header/drawable-xhdpi/revanced_header_logo_minimal_light.png b/patches/src/main/resources/change-header/drawable-xhdpi/revanced_header_logo_minimal_light.png index f9f9db247b..d1d98ed2dd 100644 Binary files a/patches/src/main/resources/change-header/drawable-xhdpi/revanced_header_logo_minimal_light.png and b/patches/src/main/resources/change-header/drawable-xhdpi/revanced_header_logo_minimal_light.png differ diff --git a/patches/src/main/resources/change-header/drawable-xxhdpi/revanced_header_logo_minimal_dark.png b/patches/src/main/resources/change-header/drawable-xxhdpi/revanced_header_logo_minimal_dark.png index 4bd24b995f..f189bbd385 100644 Binary files a/patches/src/main/resources/change-header/drawable-xxhdpi/revanced_header_logo_minimal_dark.png and b/patches/src/main/resources/change-header/drawable-xxhdpi/revanced_header_logo_minimal_dark.png differ diff --git a/patches/src/main/resources/change-header/drawable-xxhdpi/revanced_header_logo_minimal_light.png b/patches/src/main/resources/change-header/drawable-xxhdpi/revanced_header_logo_minimal_light.png index f157928cd2..725e73c23e 100644 Binary files a/patches/src/main/resources/change-header/drawable-xxhdpi/revanced_header_logo_minimal_light.png and b/patches/src/main/resources/change-header/drawable-xxhdpi/revanced_header_logo_minimal_light.png differ diff --git a/patches/src/main/resources/change-header/drawable-xxxhdpi/revanced_header_logo_minimal_dark.png b/patches/src/main/resources/change-header/drawable-xxxhdpi/revanced_header_logo_minimal_dark.png index 4e65b42c65..beecb30b53 100644 Binary files a/patches/src/main/resources/change-header/drawable-xxxhdpi/revanced_header_logo_minimal_dark.png and b/patches/src/main/resources/change-header/drawable-xxxhdpi/revanced_header_logo_minimal_dark.png differ diff --git a/patches/src/main/resources/change-header/drawable-xxxhdpi/revanced_header_logo_minimal_light.png b/patches/src/main/resources/change-header/drawable-xxxhdpi/revanced_header_logo_minimal_light.png index 566290423a..590b0b63e5 100644 Binary files a/patches/src/main/resources/change-header/drawable-xxxhdpi/revanced_header_logo_minimal_light.png and b/patches/src/main/resources/change-header/drawable-xxxhdpi/revanced_header_logo_minimal_light.png differ diff --git a/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_background_minimal.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_background_minimal.xml new file mode 100644 index 0000000000..ab5fb737ef --- /dev/null +++ b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_background_minimal.xml @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_background_rounded.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_background_rounded.xml new file mode 100644 index 0000000000..ab5fb737ef --- /dev/null +++ b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_background_rounded.xml @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_background_scaled.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_background_scaled.xml new file mode 100644 index 0000000000..6098eed222 --- /dev/null +++ b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_background_scaled.xml @@ -0,0 +1,2 @@ + \ No newline at end of file diff --git a/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_foreground_minimal.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_foreground_minimal.xml new file mode 100644 index 0000000000..41345de3a6 --- /dev/null +++ b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_foreground_minimal.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + diff --git a/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_foreground_rounded.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_foreground_rounded.xml new file mode 100644 index 0000000000..2864f3769e --- /dev/null +++ b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_foreground_rounded.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_foreground_scaled.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_foreground_scaled.xml new file mode 100644 index 0000000000..0e81a1d359 --- /dev/null +++ b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_foreground_scaled.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + diff --git a/patches/src/main/resources/custom-branding/youtube/drawable/adaptive_monochrome_ic_youtube_launcher.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_custom.xml similarity index 90% rename from patches/src/main/resources/custom-branding/youtube/drawable/adaptive_monochrome_ic_youtube_launcher.xml rename to patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_custom.xml index 72cd56f5a7..7a65401447 100644 --- a/patches/src/main/resources/custom-branding/youtube/drawable/adaptive_monochrome_ic_youtube_launcher.xml +++ b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_custom.xml @@ -3,10 +3,10 @@ android:height="108dp" android:viewportWidth="256" android:viewportHeight="256"> - + diff --git a/patches/src/main/resources/custom-branding/youtube/drawable/ringo2_adaptive_monochrome_ic_youtube_launcher.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_minimal.xml similarity index 90% rename from patches/src/main/resources/custom-branding/youtube/drawable/ringo2_adaptive_monochrome_ic_youtube_launcher.xml rename to patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_minimal.xml index 72cd56f5a7..7a65401447 100644 --- a/patches/src/main/resources/custom-branding/youtube/drawable/ringo2_adaptive_monochrome_ic_youtube_launcher.xml +++ b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_minimal.xml @@ -3,10 +3,10 @@ android:height="108dp" android:viewportWidth="256" android:viewportHeight="256"> - + diff --git a/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_rounded.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_rounded.xml new file mode 100644 index 0000000000..bcb70d260c --- /dev/null +++ b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_rounded.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/patches/src/main/resources/custom-branding/music/drawable/ic_app_icons_themed_youtube_music.xml b/patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_scaled.xml similarity index 100% rename from patches/src/main/resources/custom-branding/music/drawable/ic_app_icons_themed_youtube_music.xml rename to patches/src/main/resources/custom-branding/drawable/revanced_adaptive_monochrome_scaled.xml diff --git a/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_custom.xml b/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_custom.xml new file mode 100644 index 0000000000..3746c061df --- /dev/null +++ b/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_custom.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_minimal.xml b/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_minimal.xml new file mode 100644 index 0000000000..f21fbb1f3b --- /dev/null +++ b/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_minimal.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_rounded.xml b/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_rounded.xml new file mode 100644 index 0000000000..a5b8aef86b --- /dev/null +++ b/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_rounded.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_scaled.xml b/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_scaled.xml new file mode 100644 index 0000000000..f5126df718 --- /dev/null +++ b/patches/src/main/resources/custom-branding/mipmap-anydpi/revanced_launcher_scaled.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/patches/src/main/resources/custom-branding/mipmap-hdpi/revanced_adaptive_background_custom.png b/patches/src/main/resources/custom-branding/mipmap-hdpi/revanced_adaptive_background_custom.png new file mode 100644 index 0000000000..1bc5dbe712 Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-hdpi/revanced_adaptive_background_custom.png differ diff --git a/patches/src/main/resources/custom-branding/mipmap-hdpi/revanced_adaptive_foreground_custom.png b/patches/src/main/resources/custom-branding/mipmap-hdpi/revanced_adaptive_foreground_custom.png new file mode 100644 index 0000000000..c639a3d561 Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-hdpi/revanced_adaptive_foreground_custom.png differ diff --git a/patches/src/main/resources/custom-branding/mipmap-mdpi/revanced_adaptive_background_custom.png b/patches/src/main/resources/custom-branding/mipmap-mdpi/revanced_adaptive_background_custom.png new file mode 100644 index 0000000000..ff3c7a4c0d Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-mdpi/revanced_adaptive_background_custom.png differ diff --git a/patches/src/main/resources/custom-branding/mipmap-mdpi/revanced_adaptive_foreground_custom.png b/patches/src/main/resources/custom-branding/mipmap-mdpi/revanced_adaptive_foreground_custom.png new file mode 100644 index 0000000000..9e0ebb944a Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-mdpi/revanced_adaptive_foreground_custom.png differ diff --git a/patches/src/main/resources/custom-branding/mipmap-xhdpi/revanced_adaptive_background_custom.png b/patches/src/main/resources/custom-branding/mipmap-xhdpi/revanced_adaptive_background_custom.png new file mode 100644 index 0000000000..82c15e2b9d Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-xhdpi/revanced_adaptive_background_custom.png differ diff --git a/patches/src/main/resources/custom-branding/mipmap-xhdpi/revanced_adaptive_foreground_custom.png b/patches/src/main/resources/custom-branding/mipmap-xhdpi/revanced_adaptive_foreground_custom.png new file mode 100644 index 0000000000..2119d70cf3 Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-xhdpi/revanced_adaptive_foreground_custom.png differ diff --git a/patches/src/main/resources/custom-branding/mipmap-xxhdpi/revanced_adaptive_background_custom.png b/patches/src/main/resources/custom-branding/mipmap-xxhdpi/revanced_adaptive_background_custom.png new file mode 100644 index 0000000000..be663ad727 Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-xxhdpi/revanced_adaptive_background_custom.png differ diff --git a/patches/src/main/resources/custom-branding/mipmap-xxhdpi/revanced_adaptive_foreground_custom.png b/patches/src/main/resources/custom-branding/mipmap-xxhdpi/revanced_adaptive_foreground_custom.png new file mode 100644 index 0000000000..b0254084a5 Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-xxhdpi/revanced_adaptive_foreground_custom.png differ diff --git a/patches/src/main/resources/custom-branding/mipmap-xxxhdpi/revanced_adaptive_background_custom.png b/patches/src/main/resources/custom-branding/mipmap-xxxhdpi/revanced_adaptive_background_custom.png new file mode 100644 index 0000000000..addcbda14f Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-xxxhdpi/revanced_adaptive_background_custom.png differ diff --git a/patches/src/main/resources/custom-branding/mipmap-xxxhdpi/revanced_adaptive_foreground_custom.png b/patches/src/main/resources/custom-branding/mipmap-xxxhdpi/revanced_adaptive_foreground_custom.png new file mode 100644 index 0000000000..88f8ebc40b Binary files /dev/null and b/patches/src/main/resources/custom-branding/mipmap-xxxhdpi/revanced_adaptive_foreground_custom.png differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-hdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-hdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png deleted file mode 100644 index 80c1e2c2bd..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-hdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-hdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-hdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png deleted file mode 100644 index 93c925a28d..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-hdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-hdpi/ic_launcher_release.png b/patches/src/main/resources/custom-branding/music/mipmap-hdpi/ic_launcher_release.png deleted file mode 100644 index c922a45568..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-hdpi/ic_launcher_release.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-mdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-mdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png deleted file mode 100644 index f7c252a26f..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-mdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-mdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-mdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png deleted file mode 100644 index e9eac76185..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-mdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-mdpi/ic_launcher_release.png b/patches/src/main/resources/custom-branding/music/mipmap-mdpi/ic_launcher_release.png deleted file mode 100644 index 827bd124b1..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-mdpi/ic_launcher_release.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-xhdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-xhdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png deleted file mode 100644 index f4e6e1294b..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-xhdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-xhdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-xhdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png deleted file mode 100644 index 30bd1e6d9e..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-xhdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-xhdpi/ic_launcher_release.png b/patches/src/main/resources/custom-branding/music/mipmap-xhdpi/ic_launcher_release.png deleted file mode 100644 index 8fb88d3676..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-xhdpi/ic_launcher_release.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-xxhdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-xxhdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png deleted file mode 100644 index 200224bed5..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-xxhdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-xxhdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-xxhdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png deleted file mode 100644 index 9f75c02d02..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-xxhdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-xxhdpi/ic_launcher_release.png b/patches/src/main/resources/custom-branding/music/mipmap-xxhdpi/ic_launcher_release.png deleted file mode 100644 index 4ac235573a..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-xxhdpi/ic_launcher_release.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-xxxhdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-xxxhdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png deleted file mode 100644 index 20ea7bdffa..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-xxxhdpi/adaptiveproduct_youtube_music_2024_q4_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-xxxhdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png b/patches/src/main/resources/custom-branding/music/mipmap-xxxhdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png deleted file mode 100644 index df2d7f0a47..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-xxxhdpi/adaptiveproduct_youtube_music_2024_q4_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/music/mipmap-xxxhdpi/ic_launcher_release.png b/patches/src/main/resources/custom-branding/music/mipmap-xxxhdpi/ic_launcher_release.png deleted file mode 100644 index 8adc8af1db..0000000000 Binary files a/patches/src/main/resources/custom-branding/music/mipmap-xxxhdpi/ic_launcher_release.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index 80c1e2c2bd..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index 93c925a28d..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/ic_launcher.png b/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index c922a45568..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/ic_launcher_round.png b/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index c922a45568..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index f7c252a26f..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index e9eac76185..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/ic_launcher.png b/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 827bd124b1..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/ic_launcher_round.png b/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index 827bd124b1..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index f4e6e1294b..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index 30bd1e6d9e..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/ic_launcher.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 8fb88d3676..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/ic_launcher_round.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 8fb88d3676..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index 200224bed5..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index 9f75c02d02..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/ic_launcher.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 4ac235573a..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/ic_launcher_round.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index 4ac235573a..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png deleted file mode 100644 index 20ea7bdffa..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/adaptiveproduct_youtube_background_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png deleted file mode 100644 index df2d7f0a47..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/adaptiveproduct_youtube_foreground_color_108.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/ic_launcher.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 8adc8af1db..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/ic_launcher_round.png b/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index 8adc8af1db..0000000000 Binary files a/patches/src/main/resources/custom-branding/youtube/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ