Skip to content

Commit

Permalink
feat(YouTube - Navigation bar components): Add missing resource for C…
Browse files Browse the repository at this point in the history
…airo notification icon (YouTube 19.34.42+)
  • Loading branch information
anddea committed Dec 17, 2024
1 parent 963dbe8 commit 2982725
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ public static boolean hideSnackBar() {

// region [Hide navigation bar components] patch

private static final int fillBellCairoBlack = ResourceUtils.getDrawableIdentifier("yt_fill_bell_cairo_black_24");

private static final Map<NavigationButton, Boolean> shouldHideMap = new EnumMap<>(NavigationButton.class) {
{
put(NavigationButton.HOME, Settings.HIDE_NAVIGATION_HOME_BUTTON.get());
Expand All @@ -216,6 +218,18 @@ public static boolean enableTranslucentNavigationBar() {
return Settings.ENABLE_TRANSLUCENT_NAVIGATION_BAR.get();
}

/**
* @noinspection ALL
*/
public static void setCairoNotificationFilledIcon(EnumMap enumMap, Enum tabActivityCairo) {
if (fillBellCairoBlack != 0) {
// It's very unlikely, but Google might fix this issue someday.
// If so, [fillBellCairoBlack] might already be in enumMap.
// That's why 'EnumMap.putIfAbsent()' is used instead of 'EnumMap.put()'.
enumMap.putIfAbsent(tabActivityCairo, Integer.valueOf(fillBellCairoBlack));
}
}

public static boolean switchCreateWithNotificationButton(boolean original) {
return Settings.SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON.get() || original;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package app.revanced.patches.youtube.general.navigation

import app.revanced.patches.youtube.utils.resourceid.ytFillBell
import app.revanced.util.fingerprint.legacyFingerprint
import app.revanced.util.or
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode

internal const val ANDROID_AUTOMOTIVE_STRING = "Android Automotive"
internal const val TAB_ACTIVITY_CAIRO_STRING = "TAB_ACTIVITY_CAIRO"

internal val autoMotiveFingerprint = legacyFingerprint(
name = "autoMotiveFingerprint",
opcodes = listOf(
Expand All @@ -13,7 +17,13 @@ internal val autoMotiveFingerprint = legacyFingerprint(
Opcode.MOVE_RESULT,
Opcode.IF_EQZ
),
strings = listOf("Android Automotive")
strings = listOf(ANDROID_AUTOMOTIVE_STRING)
)

internal val imageEnumConstructorFingerprint = legacyFingerprint(
name = "imageEnumConstructorFingerprint",
returnType = "V",
strings = listOf(TAB_ACTIVITY_CAIRO_STRING)
)

internal val pivotBarChangedFingerprint = legacyFingerprint(
Expand Down Expand Up @@ -59,6 +69,11 @@ internal val pivotBarStyleFingerprint = legacyFingerprint(
}
)

internal val setEnumMapFingerprint = legacyFingerprint(
name = "setEnumMapFingerprint",
literals = listOf(ytFillBell),
)

internal val translucentNavigationBarFingerprint = legacyFingerprint(
name = "translucentNavigationBarFingerprint",
literals = listOf(45630927L),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,62 @@ 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.patch.bytecodePatch
import app.revanced.patcher.patch.resourcePatch
import app.revanced.patches.youtube.utils.compatibility.Constants.COMPATIBLE_PACKAGE
import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR
import app.revanced.patches.youtube.utils.navigation.addBottomBarContainerHook
import app.revanced.patches.youtube.utils.navigation.hookNavigationButtonCreated
import app.revanced.patches.youtube.utils.navigation.navigationBarHookPatch
import app.revanced.patches.youtube.utils.patch.PatchList.NAVIGATION_BAR_COMPONENTS
import app.revanced.patches.youtube.utils.playservice.is_19_23_or_greater
import app.revanced.patches.youtube.utils.playservice.is_19_28_or_greater
import app.revanced.patches.youtube.utils.playservice.versionCheckPatch
import app.revanced.patches.youtube.utils.resourceid.sharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.ResourceUtils.addPreference
import app.revanced.patches.youtube.utils.settings.settingsPatch
import app.revanced.util.ResourceGroup
import app.revanced.util.copyResources
import app.revanced.util.fingerprint.injectLiteralInstructionBooleanCall
import app.revanced.util.fingerprint.matchOrThrow
import app.revanced.util.fingerprint.methodOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
import app.revanced.util.indexOfFirstStringInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference

private val navigationBarComponentsResourcePatch = resourcePatch(
description = "navigationBarComponentsResourcePatch"
) {
dependsOn(versionCheckPatch)

execute {
if (is_19_28_or_greater) {
// Since I couldn't get the Cairo notification filled icon anywhere,
// I just made it as close as possible.
arrayOf(
"xxxhdpi",
"xxhdpi",
"xhdpi",
"hdpi",
"mdpi"
).forEach { dpi ->
copyResources(
"youtube/navigationbuttons",
ResourceGroup(
"drawable-$dpi",
"yt_fill_bell_cairo_black_24.png"
)
)
}
}
}
}

@Suppress("unused")
val navigationBarComponentsPatch = bytecodePatch(
NAVIGATION_BAR_COMPONENTS.title,
Expand All @@ -33,7 +68,9 @@ val navigationBarComponentsPatch = bytecodePatch(
compatibleWith(COMPATIBLE_PACKAGE)

dependsOn(
navigationBarComponentsResourcePatch,
settingsPatch,
sharedResourceIdPatch,
navigationBarHookPatch,
versionCheckPatch,
)
Expand Down Expand Up @@ -90,7 +127,7 @@ val navigationBarComponentsPatch = bytecodePatch(
// region patch for hide navigation buttons

autoMotiveFingerprint.methodOrThrow().apply {
val insertIndex = indexOfFirstStringInstructionOrThrow("Android Automotive") - 1
val insertIndex = indexOfFirstStringInstructionOrThrow(ANDROID_AUTOMOTIVE_STRING) - 1
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA

addInstructions(
Expand Down Expand Up @@ -122,6 +159,51 @@ val navigationBarComponentsPatch = bytecodePatch(

// endregion

// region fix for cairo notification icon

/**
* The Cairo navigation bar was widely rolled out in YouTube 19.28.42.
*
* Unlike Home, Shorts, and Subscriptions, which have Cairo icons,
* Notifications does not have a Cairo icon.
*
* This led to an issue <a href="https://github.com/ReVanced/revanced-patches/issues/4046">revanced-patches#4046</a>,
* Which was closed as not planned because it was a YouTube issue and not a ReVanced issue.
*
* It was not too hard to fix, so it was implemented as a patch.
*/
if (is_19_28_or_greater) {
val cairoNotificationEnumReference = with (imageEnumConstructorFingerprint.methodOrThrow()) {
val stringIndex = indexOfFirstStringInstructionOrThrow(TAB_ACTIVITY_CAIRO_STRING)
val cairoNotificationEnumIndex = indexOfFirstInstructionOrThrow(stringIndex) {
opcode == Opcode.SPUT_OBJECT
}
getInstruction<ReferenceInstruction>(cairoNotificationEnumIndex).reference
}

setEnumMapFingerprint.methodOrThrow().apply {
val enumMapIndex = indexOfFirstInstructionReversedOrThrow {
val reference = getReference<MethodReference>()
opcode == Opcode.INVOKE_VIRTUAL &&
reference?.definingClass == "Ljava/util/EnumMap;" &&
reference.name == "put" &&
reference.parameterTypes.firstOrNull() == "Ljava/lang/Enum;"
}
val (enumMapRegister, enumRegister) = getInstruction<FiveRegisterInstruction>(enumMapIndex).let {
Pair(it.registerC, it.registerD)
}

addInstructions(
enumMapIndex + 1, """
sget-object v$enumRegister, $cairoNotificationEnumReference
invoke-static {v$enumMapRegister, v$enumRegister}, $GENERAL_CLASS_DESCRIPTOR->setCairoNotificationFilledIcon(Ljava/util/EnumMap;Ljava/lang/Enum;)V
"""
)
}
}

// endregion

// Hook navigation button created, in order to hide them.
hookNavigationButtonCreated(GENERAL_CLASS_DESCRIPTOR)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ var youTubeControlsOverlaySubtitleButton = -1L
private set
var youTubeLogo = -1L
private set
var ytFillBell = -1L
private set
var ytOutlinePictureInPictureWhite = -1L
private set
var ytOutlineVideoCamera = -1L
Expand Down Expand Up @@ -638,6 +640,10 @@ internal val sharedResourceIdPatch = resourcePatch(
ID,
"youtube_logo"
]
ytFillBell = resourceMappings[
DRAWABLE,
"yt_fill_bell_black_24"
]
ytOutlinePictureInPictureWhite = resourceMappings[
DRAWABLE,
"yt_outline_picture_in_picture_white_24"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 2982725

Please sign in to comment.