mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-01 15:14:34 +02:00
feat(YouTube - Navigation bar components): Add missing resource for Cairo notification icon (YouTube 19.34.42+) https://github.com/inotia00/ReVanced_Extended/issues/2553
This commit is contained in:
parent
2fce2f7139
commit
831d2a1e76
@ -197,6 +197,8 @@ public class GeneralPatch {
|
|||||||
|
|
||||||
// region [Hide navigation bar components] patch
|
// 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) {
|
private static final Map<NavigationButton, Boolean> shouldHideMap = new EnumMap<>(NavigationButton.class) {
|
||||||
{
|
{
|
||||||
put(NavigationButton.HOME, Settings.HIDE_NAVIGATION_HOME_BUTTON.get());
|
put(NavigationButton.HOME, Settings.HIDE_NAVIGATION_HOME_BUTTON.get());
|
||||||
@ -216,6 +218,18 @@ public class GeneralPatch {
|
|||||||
return Settings.ENABLE_TRANSLUCENT_NAVIGATION_BAR.get();
|
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) {
|
public static boolean switchCreateWithNotificationButton(boolean original) {
|
||||||
return Settings.SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON.get() || original;
|
return Settings.SWITCH_CREATE_WITH_NOTIFICATIONS_BUTTON.get() || original;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
package app.revanced.patches.youtube.general.navigation
|
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.fingerprint.legacyFingerprint
|
||||||
import app.revanced.util.or
|
import app.revanced.util.or
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
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(
|
internal val autoMotiveFingerprint = legacyFingerprint(
|
||||||
name = "autoMotiveFingerprint",
|
name = "autoMotiveFingerprint",
|
||||||
opcodes = listOf(
|
opcodes = listOf(
|
||||||
@ -13,7 +17,13 @@ internal val autoMotiveFingerprint = legacyFingerprint(
|
|||||||
Opcode.MOVE_RESULT,
|
Opcode.MOVE_RESULT,
|
||||||
Opcode.IF_EQZ
|
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(
|
internal val pivotBarChangedFingerprint = legacyFingerprint(
|
||||||
@ -59,6 +69,11 @@ internal val pivotBarStyleFingerprint = legacyFingerprint(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
internal val setEnumMapFingerprint = legacyFingerprint(
|
||||||
|
name = "setEnumMapFingerprint",
|
||||||
|
literals = listOf(ytFillBell),
|
||||||
|
)
|
||||||
|
|
||||||
internal val translucentNavigationBarFingerprint = legacyFingerprint(
|
internal val translucentNavigationBarFingerprint = legacyFingerprint(
|
||||||
name = "translucentNavigationBarFingerprint",
|
name = "translucentNavigationBarFingerprint",
|
||||||
literals = listOf(45630927L),
|
literals = listOf(45630927L),
|
||||||
|
@ -4,6 +4,7 @@ import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
|||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
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.compatibility.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_CLASS_DESCRIPTOR
|
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.addBottomBarContainerHook
|
||||||
@ -11,20 +12,54 @@ import app.revanced.patches.youtube.utils.navigation.hookNavigationButtonCreated
|
|||||||
import app.revanced.patches.youtube.utils.navigation.navigationBarHookPatch
|
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.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_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.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.ResourceUtils.addPreference
|
||||||
import app.revanced.patches.youtube.utils.settings.settingsPatch
|
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.injectLiteralInstructionBooleanCall
|
||||||
import app.revanced.util.fingerprint.matchOrThrow
|
import app.revanced.util.fingerprint.matchOrThrow
|
||||||
import app.revanced.util.fingerprint.methodOrThrow
|
import app.revanced.util.fingerprint.methodOrThrow
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||||
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
import app.revanced.util.indexOfFirstStringInstructionOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
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.OneRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
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")
|
@Suppress("unused")
|
||||||
val navigationBarComponentsPatch = bytecodePatch(
|
val navigationBarComponentsPatch = bytecodePatch(
|
||||||
NAVIGATION_BAR_COMPONENTS.title,
|
NAVIGATION_BAR_COMPONENTS.title,
|
||||||
@ -33,7 +68,9 @@ val navigationBarComponentsPatch = bytecodePatch(
|
|||||||
compatibleWith(COMPATIBLE_PACKAGE)
|
compatibleWith(COMPATIBLE_PACKAGE)
|
||||||
|
|
||||||
dependsOn(
|
dependsOn(
|
||||||
|
navigationBarComponentsResourcePatch,
|
||||||
settingsPatch,
|
settingsPatch,
|
||||||
|
sharedResourceIdPatch,
|
||||||
navigationBarHookPatch,
|
navigationBarHookPatch,
|
||||||
versionCheckPatch,
|
versionCheckPatch,
|
||||||
)
|
)
|
||||||
@ -90,7 +127,7 @@ val navigationBarComponentsPatch = bytecodePatch(
|
|||||||
// region patch for hide navigation buttons
|
// region patch for hide navigation buttons
|
||||||
|
|
||||||
autoMotiveFingerprint.methodOrThrow().apply {
|
autoMotiveFingerprint.methodOrThrow().apply {
|
||||||
val insertIndex = indexOfFirstStringInstructionOrThrow("Android Automotive") - 1
|
val insertIndex = indexOfFirstStringInstructionOrThrow(ANDROID_AUTOMOTIVE_STRING) - 1
|
||||||
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
@ -122,6 +159,51 @@ val navigationBarComponentsPatch = bytecodePatch(
|
|||||||
|
|
||||||
// endregion
|
// 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.
|
// Hook navigation button created, in order to hide them.
|
||||||
hookNavigationButtonCreated(GENERAL_CLASS_DESCRIPTOR)
|
hookNavigationButtonCreated(GENERAL_CLASS_DESCRIPTOR)
|
||||||
|
|
||||||
|
@ -216,6 +216,8 @@ var youTubeControlsOverlaySubtitleButton = -1L
|
|||||||
private set
|
private set
|
||||||
var youTubeLogo = -1L
|
var youTubeLogo = -1L
|
||||||
private set
|
private set
|
||||||
|
var ytFillBell = -1L
|
||||||
|
private set
|
||||||
var ytOutlinePictureInPictureWhite = -1L
|
var ytOutlinePictureInPictureWhite = -1L
|
||||||
private set
|
private set
|
||||||
var ytOutlineVideoCamera = -1L
|
var ytOutlineVideoCamera = -1L
|
||||||
@ -638,6 +640,10 @@ internal val sharedResourceIdPatch = resourcePatch(
|
|||||||
ID,
|
ID,
|
||||||
"youtube_logo"
|
"youtube_logo"
|
||||||
]
|
]
|
||||||
|
ytFillBell = resourceMappings[
|
||||||
|
DRAWABLE,
|
||||||
|
"yt_fill_bell_black_24"
|
||||||
|
]
|
||||||
ytOutlinePictureInPictureWhite = resourceMappings[
|
ytOutlinePictureInPictureWhite = resourceMappings[
|
||||||
DRAWABLE,
|
DRAWABLE,
|
||||||
"yt_outline_picture_in_picture_white_24"
|
"yt_outline_picture_in_picture_white_24"
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 518 B |
Binary file not shown.
After Width: | Height: | Size: 394 B |
Binary file not shown.
After Width: | Height: | Size: 627 B |
Binary file not shown.
After Width: | Height: | Size: 860 B |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Loading…
x
Reference in New Issue
Block a user