From cfd244b4088daacd2788ec38357ac521e4b296d5 Mon Sep 17 00:00:00 2001 From: Bceez Date: Sun, 19 Oct 2025 16:24:45 +0200 Subject: [PATCH 1/5] fix(YouTube - Hide layout components): Hide new kind of community post (#6146) --- .../youtube/patches/components/LayoutComponentsFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java index 9b1aa94dc..c096e17e8 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/components/LayoutComponentsFilter.java @@ -87,7 +87,8 @@ public final class LayoutComponentsFilter extends Filter { "post_shelf_slim.e", "videos_post_responsive_root.e", "text_post_responsive_root.e", - "poll_post_responsive_root.e" + "poll_post_responsive_root.e", + "shared_post_root.e" ); final var subscribersCommunityGuidelines = new StringFilterGroup( From 6373829fd6ae5664e00ced23a7c0a277757d4fd2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Sun, 19 Oct 2025 14:29:38 +0000 Subject: [PATCH 2/5] chore: Release v5.43.2-dev.3 [skip ci] ## [5.43.2-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.43.2-dev.2...v5.43.2-dev.3) (2025-10-19) ### Bug Fixes * **YouTube - Hide layout components:** Hide new kind of community post ([#6146](https://github.com/ReVanced/revanced-patches/issues/6146)) ([cfd244b](https://github.com/ReVanced/revanced-patches/commit/cfd244b4088daacd2788ec38357ac521e4b296d5)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b85e438ac..584422306 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.43.2-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.43.2-dev.2...v5.43.2-dev.3) (2025-10-19) + + +### Bug Fixes + +* **YouTube - Hide layout components:** Hide new kind of community post ([#6146](https://github.com/ReVanced/revanced-patches/issues/6146)) ([cfd244b](https://github.com/ReVanced/revanced-patches/commit/cfd244b4088daacd2788ec38357ac521e4b296d5)) + ## [5.43.2-dev.2](https://github.com/ReVanced/revanced-patches/compare/v5.43.2-dev.1...v5.43.2-dev.2) (2025-10-17) diff --git a/gradle.properties b/gradle.properties index 973dda541..d8d1c57a8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.43.2-dev.2 +version = 5.43.2-dev.3 From de97562c5ddc8ec707761c1e04e74c4e18f9c158 Mon Sep 17 00:00:00 2001 From: rospino74 <34315725+rospino74@users.noreply.github.com> Date: Wed, 22 Oct 2025 08:09:34 +0200 Subject: [PATCH 3/5] feat(Samsung Radio): Add `Disable device checks` patch (#6145) --- extensions/samsung/radio/build.gradle.kts | 4 ++ .../radio/src/main/AndroidManifest.xml | 1 + .../radio/misc/fix/crash/FixCrashPatch.java | 24 ++++++++ .../device/BypassDeviceChecksPatch.java | 19 ++++++ .../samsung/radio/stub/build.gradle.kts | 17 ++++++ .../radio/stub/src/main/AndroidManifest.xml | 1 + .../java/android/os/SemSystemProperties.java | 7 +++ patches/api/patches.api | 8 +++ .../fix/crash/AddManifestPermissionsPatch.kt | 34 +++++++++++ .../radio/misc/fix/crash/Fingerprints.kt | 18 ++++++ .../radio/misc/fix/crash/FixCrashPatch.kt | 42 +++++++++++++ .../device/BypassDeviceChecksPatch.kt | 55 +++++++++++++++++ .../radio/restrictions/device/Fingerprints.kt | 61 +++++++++++++++++++ 13 files changed, 291 insertions(+) create mode 100644 extensions/samsung/radio/build.gradle.kts create mode 100644 extensions/samsung/radio/src/main/AndroidManifest.xml create mode 100644 extensions/samsung/radio/src/main/java/app/revanced/extension/samsung/radio/misc/fix/crash/FixCrashPatch.java create mode 100644 extensions/samsung/radio/src/main/java/app/revanced/extension/samsung/radio/restrictions/device/BypassDeviceChecksPatch.java create mode 100644 extensions/samsung/radio/stub/build.gradle.kts create mode 100644 extensions/samsung/radio/stub/src/main/AndroidManifest.xml create mode 100644 extensions/samsung/radio/stub/src/main/java/android/os/SemSystemProperties.java create mode 100644 patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/AddManifestPermissionsPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/Fingerprints.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/FixCrashPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/samsung/radio/restrictions/device/BypassDeviceChecksPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/samsung/radio/restrictions/device/Fingerprints.kt diff --git a/extensions/samsung/radio/build.gradle.kts b/extensions/samsung/radio/build.gradle.kts new file mode 100644 index 000000000..0eadeef26 --- /dev/null +++ b/extensions/samsung/radio/build.gradle.kts @@ -0,0 +1,4 @@ +dependencies { + compileOnly(project(":extensions:shared:library")) + compileOnly(project(":extensions:samsung:radio:stub")) +} diff --git a/extensions/samsung/radio/src/main/AndroidManifest.xml b/extensions/samsung/radio/src/main/AndroidManifest.xml new file mode 100644 index 000000000..9b65eb06c --- /dev/null +++ b/extensions/samsung/radio/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/extensions/samsung/radio/src/main/java/app/revanced/extension/samsung/radio/misc/fix/crash/FixCrashPatch.java b/extensions/samsung/radio/src/main/java/app/revanced/extension/samsung/radio/misc/fix/crash/FixCrashPatch.java new file mode 100644 index 000000000..72c5addc4 --- /dev/null +++ b/extensions/samsung/radio/src/main/java/app/revanced/extension/samsung/radio/misc/fix/crash/FixCrashPatch.java @@ -0,0 +1,24 @@ +package app.revanced.extension.samsung.radio.misc.fix.crash; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@SuppressWarnings("unused") +public final class FixCrashPatch { + /** + * Injection point. + *

+ * Add the required permissions to the request list to avoid crashes on API 34+. + **/ + public static final String[] fixPermissionRequestList(String[] perms) { + List permsList = new ArrayList<>(Arrays.asList(perms)); + if (permsList.contains("android.permission.POST_NOTIFICATIONS")) { + permsList.addAll(Arrays.asList("android.permission.RECORD_AUDIO", "android.permission.READ_PHONE_STATE", "android.permission.FOREGROUND_SERVICE_MICROPHONE")); + } + if (permsList.contains("android.permission.RECORD_AUDIO")) { + permsList.add("android.permission.FOREGROUND_SERVICE_MICROPHONE"); + } + return permsList.toArray(new String[0]); + } +} diff --git a/extensions/samsung/radio/src/main/java/app/revanced/extension/samsung/radio/restrictions/device/BypassDeviceChecksPatch.java b/extensions/samsung/radio/src/main/java/app/revanced/extension/samsung/radio/restrictions/device/BypassDeviceChecksPatch.java new file mode 100644 index 000000000..19b6c3e82 --- /dev/null +++ b/extensions/samsung/radio/src/main/java/app/revanced/extension/samsung/radio/restrictions/device/BypassDeviceChecksPatch.java @@ -0,0 +1,19 @@ +package app.revanced.extension.samsung.radio.restrictions.device; + +import android.os.SemSystemProperties; + +import java.util.Arrays; + +@SuppressWarnings("unused") +public final class BypassDeviceChecksPatch { + + /** + * Injection point. + *

+ * Check if the device has the required hardware + **/ + public static final boolean checkIfDeviceIsIncompatible(String[] deviceList) { + String currentDevice = SemSystemProperties.getSalesCode(); + return Arrays.asList(deviceList).contains(currentDevice); + } +} diff --git a/extensions/samsung/radio/stub/build.gradle.kts b/extensions/samsung/radio/stub/build.gradle.kts new file mode 100644 index 000000000..b4bee8809 --- /dev/null +++ b/extensions/samsung/radio/stub/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + alias(libs.plugins.android.library) +} + +android { + namespace = "app.revanced.extension" + compileSdk = 34 + + defaultConfig { + minSdk = 24 + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} diff --git a/extensions/samsung/radio/stub/src/main/AndroidManifest.xml b/extensions/samsung/radio/stub/src/main/AndroidManifest.xml new file mode 100644 index 000000000..15e7c2ae6 --- /dev/null +++ b/extensions/samsung/radio/stub/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extensions/samsung/radio/stub/src/main/java/android/os/SemSystemProperties.java b/extensions/samsung/radio/stub/src/main/java/android/os/SemSystemProperties.java new file mode 100644 index 000000000..33a4b4400 --- /dev/null +++ b/extensions/samsung/radio/stub/src/main/java/android/os/SemSystemProperties.java @@ -0,0 +1,7 @@ +package android.os; + +public class SemSystemProperties { + public static String getSalesCode() { + throw new UnsupportedOperationException("Stub"); + } +} \ No newline at end of file diff --git a/patches/api/patches.api b/patches/api/patches.api index b15bb5bd3..20f74169a 100644 --- a/patches/api/patches.api +++ b/patches/api/patches.api @@ -764,6 +764,14 @@ public final class app/revanced/patches/reddit/misc/tracking/url/SanitizeUrlQuer public static final fun getSanitizeUrlQueryPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } +public final class app/revanced/patches/samsung/radio/misc/fix/crash/FixCrashPatchKt { + public static final fun getFixCrashPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + +public final class app/revanced/patches/samsung/radio/restrictions/device/BypassDeviceChecksPatchKt { + public static final fun getBypassDeviceChecksPatch ()Lapp/revanced/patcher/patch/BytecodePatch; +} + public final class app/revanced/patches/serviceportalbund/detection/root/RootDetectionPatchKt { public static final fun getRootDetectionPatch ()Lapp/revanced/patcher/patch/BytecodePatch; } diff --git a/patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/AddManifestPermissionsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/AddManifestPermissionsPatch.kt new file mode 100644 index 000000000..35641f2e7 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/AddManifestPermissionsPatch.kt @@ -0,0 +1,34 @@ +package app.revanced.patches.samsung.radio.misc.fix.crash + +import app.revanced.patcher.patch.resourcePatch +import app.revanced.util.asSequence +import org.w3c.dom.Element + +@Suppress("unused") +internal val addManifestPermissionsPatch = resourcePatch { + + val requiredPermissions = listOf( + "android.permission.READ_PHONE_STATE", + "android.permission.FOREGROUND_SERVICE_MICROPHONE", + "android.permission.RECORD_AUDIO", + ) + + execute { + document("AndroidManifest.xml").use { document -> + document.getElementsByTagName("manifest").item(0).let { manifestEl -> + + // Check which permissions are missing + val existingPermissionNames = document.getElementsByTagName("uses-permission").asSequence() + .mapNotNull { (it as? Element)?.getAttribute("android:name") }.toSet() + val missingPermissions = requiredPermissions.filterNot { it in existingPermissionNames } + + // Then add them + for (permission in missingPermissions) { + val element = document.createElement("uses-permission") + element.setAttribute("android:name", permission) + manifestEl.appendChild(element) + } + } + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/Fingerprints.kt new file mode 100644 index 000000000..f842a45cc --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/Fingerprints.kt @@ -0,0 +1,18 @@ +@file:Suppress("unused") + +package app.revanced.patches.samsung.radio.misc.fix.crash + +import app.revanced.patcher.fingerprint +import app.revanced.patches.all.misc.transformation.IMethodCall +import app.revanced.patches.all.misc.transformation.fromMethodReference +import app.revanced.util.getReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +internal val permissionRequestListFingerprint = fingerprint { + strings( + "android.permission.POST_NOTIFICATIONS", + "android.permission.READ_MEDIA_AUDIO", + "android.permission.RECORD_AUDIO" + ) + custom { method, _ -> method.name == "" } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/FixCrashPatch.kt b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/FixCrashPatch.kt new file mode 100644 index 000000000..a076ca830 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/misc/fix/crash/FixCrashPatch.kt @@ -0,0 +1,42 @@ +@file:Suppress("unused") + +package app.revanced.patches.samsung.radio.misc.fix.crash + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.samsung.radio.restrictions.device.bypassDeviceChecksPatch +import app.revanced.util.findInstructionIndicesReversedOrThrow +import app.revanced.util.indexOfFirstInstruction +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction + +private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/samsung/radio/misc/fix/crash/FixCrashPatch;" + +val fixCrashPatch = bytecodePatch( + name = "Fix crashes", description = "Prevents the app from crashing because of missing system permissions." +) { + dependsOn(addManifestPermissionsPatch, bypassDeviceChecksPatch) + extendWith("extensions/samsung/radio.rve") + compatibleWith("com.sec.android.app.fm"("12.4.00.7", "12.3.00.13", "12.3.00.11")) + + execute { + permissionRequestListFingerprint.method.apply { + findInstructionIndicesReversedOrThrow(Opcode.FILLED_NEW_ARRAY).forEach { filledNewArrayIndex -> + val moveResultIndex = indexOfFirstInstruction(filledNewArrayIndex, Opcode.MOVE_RESULT_OBJECT) + if (moveResultIndex < 0) return@forEach // No move-result-object found after the filled-new-array + + // Get the register where the array is saved + val arrayRegister = getInstruction(moveResultIndex).registerA + + // Invoke the method from the extension + addInstructions( + moveResultIndex + 1, """ + invoke-static { v$arrayRegister }, ${EXTENSION_CLASS_DESCRIPTOR}->fixPermissionRequestList([Ljava/lang/String;)[Ljava/lang/String; + move-result-object v$arrayRegister + """ + ) + } + } + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/samsung/radio/restrictions/device/BypassDeviceChecksPatch.kt b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/restrictions/device/BypassDeviceChecksPatch.kt new file mode 100644 index 000000000..68ef9a801 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/restrictions/device/BypassDeviceChecksPatch.kt @@ -0,0 +1,55 @@ +package app.revanced.patches.samsung.radio.restrictions.device + +import app.revanced.patcher.extensions.InstructionExtensions.addInstructions +import app.revanced.patcher.extensions.InstructionExtensions.removeInstructions +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.util.findFreeRegister +import app.revanced.util.getReference +import app.revanced.util.indexOfFirstInstructionOrThrow +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.reference.StringReference + +private const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/samsung/radio/restrictions/device/BypassDeviceChecksPatch;" + +@Suppress("unused") +val bypassDeviceChecksPatch = bytecodePatch( + name = "Bypass device checks", + description = "Removes firmware and region blacklisting. " + + "This patch will still not allow the app to run on devices that do not have the required hardware.", +) { + extendWith("extensions/samsung/radio.rve") + compatibleWith("com.sec.android.app.fm"("12.4.00.7", "12.3.00.13", "12.3.00.11")) + + execute { + // Return false = The device is not blacklisted + checkDeviceFingerprint.method.apply { + // Find the first string that start with "SM-", that's the list of incompatible devices + val firstStringIndex = indexOfFirstInstructionOrThrow { + opcode == Opcode.CONST_STRING && + getReference()?.string?.startsWith("SM-") == true + } + + // Find the following filled-new-array (or filled-new-array/range) instruction + val filledNewArrayIndex = indexOfFirstInstructionOrThrow(firstStringIndex + 1) { + opcode == Opcode.FILLED_NEW_ARRAY || opcode == Opcode.FILLED_NEW_ARRAY_RANGE + } + + // Find an available register for our use + val resultRegister = findFreeRegister(filledNewArrayIndex + 1) + + // Store the array there and invoke the method that we added to the class earlier + addInstructions( + filledNewArrayIndex + 1, """ + move-result-object v$resultRegister + invoke-static { v$resultRegister }, $EXTENSION_CLASS_DESCRIPTOR->checkIfDeviceIsIncompatible([Ljava/lang/String;)Z + move-result v$resultRegister + return v$resultRegister + """ + ) + + // Remove the instructions before our strings + removeInstructions(0, firstStringIndex) + } + } +} diff --git a/patches/src/main/kotlin/app/revanced/patches/samsung/radio/restrictions/device/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/restrictions/device/Fingerprints.kt new file mode 100644 index 000000000..476823591 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/samsung/radio/restrictions/device/Fingerprints.kt @@ -0,0 +1,61 @@ +package app.revanced.patches.samsung.radio.restrictions.device + +import app.revanced.patcher.fingerprint +import app.revanced.patches.all.misc.transformation.IMethodCall +import app.revanced.patches.all.misc.transformation.fromMethodReference +import app.revanced.util.getReference +import com.android.tools.smali.dexlib2.iface.reference.MethodReference + +internal val checkDeviceFingerprint = fingerprint { + returns("Z") + custom { method, _ -> + /* Check for methods call to: + - Landroid/os/SemSystemProperties;->getSalesCode()Ljava/lang/String; + - Landroid/os/SemSystemProperties;->getCountryIso()Ljava/lang/String; + */ + + val impl = method.implementation ?: return@custom false + + // Track which target methods we've found + val foundMethods = mutableSetOf() + + // Scan method instructions for calls to our target methods + for (instr in impl.instructions) { + val ref = instr.getReference() ?: continue + val mc = fromMethodReference(ref) ?: continue + + if (mc == MethodCall.GetSalesCode || mc == MethodCall.GetCountryIso) { + foundMethods.add(mc) + + // If we found both methods, return success + if (foundMethods.size == 2) { + return@custom true + } + } + } + + // Only match if both methods are present + return@custom false + } +} + +// Information about method calls we want to replace +private enum class MethodCall( + override val definedClassName: String, + override val methodName: String, + override val methodParams: Array, + override val returnType: String, +) : IMethodCall { + GetSalesCode( + "Landroid/os/SemSystemProperties;", + "getSalesCode", + arrayOf(), + "Ljava/lang/String;", + ), + GetCountryIso( + "Landroid/os/SemSystemProperties;", + "getCountryIso", + arrayOf(), + "Ljava/lang/String;", + ), +} \ No newline at end of file From b2dd008aeed341e91f87aad8f90da33f13ce0031 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 22 Oct 2025 06:14:00 +0000 Subject: [PATCH 4/5] chore: Release v5.44.0-dev.1 [skip ci] # [5.44.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.43.2-dev.3...v5.44.0-dev.1) (2025-10-22) ### Features * **Samsung Radio:** Add `Disable device checks` patch ([#6145](https://github.com/ReVanced/revanced-patches/issues/6145)) ([de97562](https://github.com/ReVanced/revanced-patches/commit/de97562c5ddc8ec707761c1e04e74c4e18f9c158)) --- CHANGELOG.md | 7 +++++++ gradle.properties | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 584422306..a7b15246d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [5.44.0-dev.1](https://github.com/ReVanced/revanced-patches/compare/v5.43.2-dev.3...v5.44.0-dev.1) (2025-10-22) + + +### Features + +* **Samsung Radio:** Add `Disable device checks` patch ([#6145](https://github.com/ReVanced/revanced-patches/issues/6145)) ([de97562](https://github.com/ReVanced/revanced-patches/commit/de97562c5ddc8ec707761c1e04e74c4e18f9c158)) + ## [5.43.2-dev.3](https://github.com/ReVanced/revanced-patches/compare/v5.43.2-dev.2...v5.43.2-dev.3) (2025-10-19) diff --git a/gradle.properties b/gradle.properties index d8d1c57a8..a5b833989 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,4 +3,4 @@ org.gradle.jvmargs = -Xms512M -Xmx2048M org.gradle.parallel = true android.useAndroidX = true kotlin.code.style = official -version = 5.43.2-dev.3 +version = 5.44.0-dev.1 From c64e29ec5791392b8c26ad91a6bd2b5000392363 Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Wed, 22 Oct 2025 11:47:39 +0400 Subject: [PATCH 5/5] refactor(YouTube - Seekbar): Remove obsolete splash screen color code --- .../patches/theme/ProgressBarDrawable.java | 51 ------- .../patches/theme/SeekbarColorPatch.java | 54 ------- .../layout/seekbar/SeekbarColorPatch.kt | 135 +----------------- .../main/resources/seekbar/values/attrs.xml | 4 - 4 files changed, 1 insertion(+), 243 deletions(-) delete mode 100644 extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/ProgressBarDrawable.java delete mode 100644 patches/src/main/resources/seekbar/values/attrs.xml diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/ProgressBarDrawable.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/ProgressBarDrawable.java deleted file mode 100644 index 93d53c9a5..000000000 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/ProgressBarDrawable.java +++ /dev/null @@ -1,51 +0,0 @@ -package app.revanced.extension.youtube.patches.theme; - -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.drawable.Drawable; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import app.revanced.extension.youtube.patches.HideSeekbarPatch; -import app.revanced.extension.youtube.settings.Settings; - -/** - * Used by {@link SeekbarColorPatch} change the color of the seekbar. - * and {@link HideSeekbarPatch} to hide the seekbar of the feed and watch history. - */ -@SuppressWarnings("unused") -public class ProgressBarDrawable extends Drawable { - - private final Paint paint = new Paint(); - { - paint.setColor(SeekbarColorPatch.getSeekbarColor()); - } - - @Override - public void draw(@NonNull Canvas canvas) { - if (Settings.HIDE_SEEKBAR_THUMBNAIL.get()) { - return; - } - - canvas.drawRect(getBounds(), paint); - } - - @Override - public void setAlpha(int alpha) { - paint.setAlpha(alpha); - } - - @Override - public void setColorFilter(@Nullable ColorFilter colorFilter) { - paint.setColorFilter(colorFilter); - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - -} diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java index 72b74fc94..270576700 100644 --- a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/theme/SeekbarColorPatch.java @@ -4,9 +4,7 @@ import static app.revanced.extension.shared.StringRef.str; import static app.revanced.extension.shared.Utils.clamp; import static app.revanced.extension.youtube.patches.theme.ThemePatch.SplashScreenAnimationStyle; -import android.content.res.Resources; import android.graphics.Color; -import android.graphics.drawable.AnimatedVectorDrawable; import com.airbnb.lottie.LottieAnimationView; @@ -15,7 +13,6 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.Locale; import java.util.Scanner; import app.revanced.extension.shared.Logger; @@ -104,27 +101,6 @@ public final class SeekbarColorPatch { return customSeekbarColor; } - private static int colorChannelTo3Bits(int channel8Bits) { - final float channel3Bits = channel8Bits * 7 / 255f; - - // If a color channel is near zero, then allow rounding up so values between - // 0x12 and 0x23 will show as 0x24. But always round down when the channel is - // near full saturation, otherwise rounding to nearest will cause all values - // between 0xEC and 0xFE to always show as full saturation (0xFF). - return channel3Bits < 6 - ? Math.round(channel3Bits) - : (int) channel3Bits; - } - - @SuppressWarnings("SameParameterValue") - private static String get9BitStyleIdentifier(int color24Bit) { - final int r3 = colorChannelTo3Bits(Color.red(color24Bit)); - final int g3 = colorChannelTo3Bits(Color.green(color24Bit)); - final int b3 = colorChannelTo3Bits(Color.blue(color24Bit)); - - return String.format(Locale.US, "splash_seekbar_color_style_%d_%d_%d", r3, g3, b3); - } - /** * injection point. */ @@ -135,36 +111,6 @@ public final class SeekbarColorPatch { return original; // false = drawable style, true = lottie style. } - /** - * Injection point. - * Old drawable style launch screen. - */ - public static void setSplashAnimationDrawableTheme(AnimatedVectorDrawable vectorDrawable) { - // Alternatively a ColorMatrixColorFilter can be used to change the color of the drawable - // without using any styles, but a color filter cannot selectively change the seekbar - // while keeping the red YT logo untouched. - // Even if the seekbar color xml value is changed to a completely different color (such as green), - // a color filter still cannot be selectively applied when the drawable has more than 1 color. - try { - // Must set the color even if custom seekbar is off, - // because the xml color was replaced with a themed value. - String seekbarStyle = get9BitStyleIdentifier(customSeekbarColor); - Logger.printDebug(() -> "Using splash seekbar style: " + seekbarStyle); - - final int styleIdentifierDefault = Utils.getResourceIdentifierOrThrow( - seekbarStyle, - "style" - ); - - Resources.Theme theme = Utils.getContext().getResources().newTheme(); - theme.applyStyle(styleIdentifierDefault, true); - - vectorDrawable.applyTheme(theme); - } catch (Exception ex) { - Logger.printException(() -> "setSplashAnimationDrawableTheme failure", ex); - } - } - /** * Injection point. * Modern Lottie style animation. diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt index f89175c8f..f7332f5c3 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/layout/seekbar/SeekbarColorPatch.kt @@ -1,11 +1,9 @@ package app.revanced.patches.youtube.layout.seekbar import app.revanced.patcher.Fingerprint -import app.revanced.patcher.extensions.InstructionExtensions.addInstruction import app.revanced.patcher.extensions.InstructionExtensions.addInstructions import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction -import app.revanced.patcher.patch.PatchException import app.revanced.patcher.patch.bytecodePatch import app.revanced.patcher.patch.resourcePatch import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod @@ -17,17 +15,13 @@ import app.revanced.patches.shared.misc.mapping.resourceMappingPatch import app.revanced.patches.shared.misc.mapping.resourceMappings import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater -import app.revanced.patches.youtube.misc.playservice.is_19_46_or_greater import app.revanced.patches.youtube.misc.playservice.is_19_49_or_greater import app.revanced.patches.youtube.misc.playservice.versionCheckPatch import app.revanced.patches.youtube.misc.settings.settingsPatch import app.revanced.patches.youtube.shared.mainActivityOnCreateFingerprint -import app.revanced.util.copyXmlNode -import app.revanced.util.findElementByAttributeValueOrThrow import app.revanced.util.findInstructionIndicesReversedOrThrow import app.revanced.util.getReference import app.revanced.util.indexOfFirstInstructionOrThrow -import app.revanced.util.inputStreamFromBundledResource import app.revanced.util.insertLiteralOverride import com.android.tools.smali.dexlib2.AccessFlags import com.android.tools.smali.dexlib2.Opcode @@ -38,9 +32,6 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.immutable.ImmutableMethod import com.android.tools.smali.dexlib2.immutable.ImmutableMethodParameter -import org.w3c.dom.Element -import java.io.ByteArrayInputStream -import kotlin.use internal var reelTimeBarPlayedColorId = -1L private set @@ -57,8 +48,6 @@ internal var ytTextSecondaryId = -1L internal var inlineTimeBarLiveSeekableRangeId = -1L private set -internal const val splashSeekbarColorAttributeName = "splash_custom_seekbar_color" - private val seekbarColorResourcePatch = resourcePatch { dependsOn( settingsPatch, @@ -92,21 +81,6 @@ private val seekbarColorResourcePatch = resourcePatch { "inline_time_bar_live_seekable_range" ] - // Modify the resume playback drawable and replace the progress bar with a custom drawable. - document("res/drawable/resume_playback_progressbar_drawable.xml").use { document -> - val layerList = document.getElementsByTagName("layer-list").item(0) as Element - val progressNode = layerList.getElementsByTagName("item").item(1) as Element - if (!progressNode.getAttributeNode("android:id").value.endsWith("progress")) { - throw PatchException("Could not find progress bar") - } - val scaleNode = progressNode.getElementsByTagName("scale").item(0) as Element - val shapeNode = scaleNode.getElementsByTagName("shape").item(0) as Element - val replacementNode = document.createElement( - "app.revanced.extension.youtube.patches.theme.ProgressBarDrawable", - ) - scaleNode.replaceChild(replacementNode, shapeNode) - } - ytYoutubeMagentaColorId = resourceMappings[ "color", "yt_youtube_magenta", @@ -115,99 +89,9 @@ private val seekbarColorResourcePatch = resourcePatch { "attr", "ytStaticBrandRed", ] - - // Add attribute and styles for splash screen custom color. - // Using a style is the only way to selectively change just the seekbar fill color. - // - // Because the style colors must be hard coded for all color possibilities, - // instead of allowing 24 bit color the style is restricted to 9-bit (3 bits per color channel) - // and the style color closest to the users custom color is used for the splash screen. - arrayOf( - inputStreamFromBundledResource("seekbar/values", "attrs.xml")!! to "res/values/attrs.xml", - ByteArrayInputStream(create9BitSeekbarColorStyles().toByteArray()) to "res/values/styles.xml" - ).forEach { (source, destination) -> - "resources".copyXmlNode( - document(source), - document(destination), - ).close() - } - - fun setSplashDrawablePathFillColor(xmlFileNames: Iterable, vararg resourceNames: String) { - xmlFileNames.forEach { xmlFileName -> - document(xmlFileName).use { document -> - val childNodes = document.childNodes - - resourceNames.forEach { elementId -> - val element = childNodes.findElementByAttributeValueOrThrow( - "android:name", - elementId - ) - - val attribute = "android:fillColor" - if (!element.hasAttribute(attribute)) { - throw PatchException("Could not find $attribute for $elementId") - } - - element.setAttribute(attribute, "?attr/$splashSeekbarColorAttributeName") - } - } - } - } - - setSplashDrawablePathFillColor( - listOf( - "res/drawable/\$startup_animation_light__0.xml", - "res/drawable/\$startup_animation_dark__0.xml" - ), - "_R_G_L_10_G_D_0_P_0" - ) - - if (!is_19_46_or_greater) { - // Resources removed in 19.46+ - setSplashDrawablePathFillColor( - listOf( - "res/drawable/\$buenos_aires_animation_light__0.xml", - "res/drawable/\$buenos_aires_animation_dark__0.xml" - ), - "_R_G_L_8_G_D_0_P_0" - ) - } } } -/** - * Generate a style xml with all combinations of 9-bit colors. - */ -private fun create9BitSeekbarColorStyles(): String = StringBuilder().apply { - append("") - append("\n") - - for (red in 0..7) { - for (green in 0..7) { - for (blue in 0..7) { - val name = "${red}_${green}_${blue}" - - fun roundTo3BitHex(channel8Bits: Int) = - (channel8Bits * 255 / 7).toString(16).padStart(2, '0') - val r = roundTo3BitHex(red) - val g = roundTo3BitHex(green) - val b = roundTo3BitHex(blue) - val color = "#ff$r$g$b" - - append( - """ - - """ - ) - } - } - } - - append("") -}.toString() - private const val EXTENSION_CLASS_DESCRIPTOR = "Lapp/revanced/extension/youtube/patches/theme/SeekbarColorPatch;" val seekbarColorPatch = bytecodePatch( @@ -344,21 +228,6 @@ val seekbarColorPatch = bytecodePatch( // Hook the splash animation to set the a seekbar color. mainActivityOnCreateFingerprint.method.apply { - val drawableIndex = indexOfFirstInstructionOrThrow { - val reference = getReference() - reference?.definingClass == "Landroid/widget/ImageView;" - && reference.name == "getDrawable" - } - val checkCastIndex = indexOfFirstInstructionOrThrow(drawableIndex, Opcode.CHECK_CAST) - val drawableRegister = getInstruction(checkCastIndex).registerA - - addInstruction( - checkCastIndex + 1, - "invoke-static { v$drawableRegister }, $EXTENSION_CLASS_DESCRIPTOR->" + - "setSplashAnimationDrawableTheme(Landroid/graphics/drawable/AnimatedVectorDrawable;)V" - ) - - // Replace the Lottie animation view setAnimation(int) call. val setAnimationIntMethodName = lottieAnimationViewSetAnimationIntFingerprint.originalMethod.name findInstructionIndicesReversedOrThrow { @@ -371,13 +240,11 @@ val seekbarColorPatch = bytecodePatch( replaceInstruction( index, "invoke-static { v${instruction.registerC}, v${instruction.registerD} }, " + - "$EXTENSION_CLASS_DESCRIPTOR->setSplashAnimationLottie" + - "(Lcom/airbnb/lottie/LottieAnimationView;I)V" + "$EXTENSION_CLASS_DESCRIPTOR->setSplashAnimationLottie(Lcom/airbnb/lottie/LottieAnimationView;I)V" ) } } - // Add non obfuscated method aliases for `setAnimation(int)` // and `setAnimation(InputStream, String)` so extension code can call them. lottieAnimationViewSetAnimationIntFingerprint.classDef.methods.apply { diff --git a/patches/src/main/resources/seekbar/values/attrs.xml b/patches/src/main/resources/seekbar/values/attrs.xml deleted file mode 100644 index 2bf349f0d..000000000 --- a/patches/src/main/resources/seekbar/values/attrs.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file