fix(YouTube - Change live ring click action): Sometimes the channel opens even if the live ring is not clicked.

This commit is contained in:
inotia00 2025-01-28 18:02:43 +09:00
parent 7fbac85ef1
commit b95e735345
4 changed files with 26 additions and 34 deletions

View File

@ -2,6 +2,7 @@ package app.revanced.extension.youtube.patches.general;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import app.revanced.extension.shared.utils.Logger; import app.revanced.extension.shared.utils.Logger;
@ -15,9 +16,14 @@ public final class OpenChannelOfLiveAvatarPatch {
Settings.CHANGE_LIVE_RING_CLICK_ACTION.get(); Settings.CHANGE_LIVE_RING_CLICK_ACTION.get();
private static final AtomicBoolean engagementPanelOpen = new AtomicBoolean(false); private static final AtomicBoolean engagementPanelOpen = new AtomicBoolean(false);
private static volatile boolean liveChannelAvatarClicked = false;
private static volatile String videoId = ""; private static volatile String videoId = "";
/**
* If the video is open by clicking live ring, this key does not exists.
*/
private static final String VIDEO_THUMBNAIL_VIEW_KEY =
"VideoPresenterConstants.VIDEO_THUMBNAIL_VIEW_KEY";
public static void showEngagementPanel(@Nullable Object object) { public static void showEngagementPanel(@Nullable Object object) {
engagementPanelOpen.set(object != null); engagementPanelOpen.set(object != null);
} }
@ -26,19 +32,15 @@ public final class OpenChannelOfLiveAvatarPatch {
engagementPanelOpen.compareAndSet(true, false); engagementPanelOpen.compareAndSet(true, false);
} }
public static void liveChannelAvatarClicked() {
liveChannelAvatarClicked = true;
}
public static boolean openChannelOfLiveAvatar() { public static boolean openChannelOfLiveAvatar() {
try { try {
if (!CHANGE_LIVE_RING_CLICK_ACTION) { if (!CHANGE_LIVE_RING_CLICK_ACTION) {
return false; return false;
} }
if (!liveChannelAvatarClicked) { if (engagementPanelOpen.get()) {
return false; return false;
} }
if (engagementPanelOpen.get()) { if (videoId.isEmpty()) {
return false; return false;
} }
VideoDetailsRequest request = VideoDetailsRequest.getRequestForVideoId(videoId); VideoDetailsRequest request = VideoDetailsRequest.getRequestForVideoId(videoId);
@ -46,7 +48,6 @@ public final class OpenChannelOfLiveAvatarPatch {
String channelId = request.getInfo(); String channelId = request.getInfo();
if (channelId != null) { if (channelId != null) {
videoId = ""; videoId = "";
liveChannelAvatarClicked = false;
VideoUtils.openChannel(channelId); VideoUtils.openChannel(channelId);
return true; return true;
} }
@ -57,12 +58,15 @@ public final class OpenChannelOfLiveAvatarPatch {
return false; return false;
} }
public static void openChannelOfLiveAvatar(String newlyLoadedVideoId) { public static void openChannelOfLiveAvatar(Map<Object, Object> playbackStartDescriptorMap, String newlyLoadedVideoId) {
try { try {
if (!CHANGE_LIVE_RING_CLICK_ACTION) { if (!CHANGE_LIVE_RING_CLICK_ACTION) {
return; return;
} }
if (!liveChannelAvatarClicked) { if (playbackStartDescriptorMap == null) {
return;
}
if (playbackStartDescriptorMap.containsKey(VIDEO_THUMBNAIL_VIEW_KEY)) {
return; return;
} }
if (engagementPanelOpen.get()) { if (engagementPanelOpen.get()) {

View File

@ -1,6 +1,5 @@
package app.revanced.patches.youtube.general.livering package app.revanced.patches.youtube.general.livering
import app.revanced.patches.youtube.utils.resourceid.elementsImage
import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.fingerprint.legacyFingerprint
import app.revanced.util.getReference import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstruction import app.revanced.util.indexOfFirstInstruction
@ -10,14 +9,6 @@ import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference import com.android.tools.smali.dexlib2.iface.reference.MethodReference
internal val elementsImageFingerprint = legacyFingerprint(
name = "elementsImageFingerprint",
returnType = "Landroid/view/View;",
accessFlags = AccessFlags.PRIVATE or AccessFlags.STATIC,
parameters = listOf("Landroid/view/View;"),
literals = listOf(elementsImage),
)
internal val clientSettingEndpointFingerprint = legacyFingerprint( internal val clientSettingEndpointFingerprint = legacyFingerprint(
name = "clientSettingEndpointFingerprint", name = "clientSettingEndpointFingerprint",
returnType = "V", returnType = "V",

View File

@ -1,6 +1,5 @@
package app.revanced.patches.youtube.general.livering package app.revanced.patches.youtube.general.livering
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.addInstructionsWithLabels import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
@ -10,16 +9,18 @@ import app.revanced.patches.youtube.utils.engagement.engagementPanelHookPatch
import app.revanced.patches.youtube.utils.engagement.hookEngagementPanelState import app.revanced.patches.youtube.utils.engagement.hookEngagementPanelState
import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_PATH import app.revanced.patches.youtube.utils.extension.Constants.GENERAL_PATH
import app.revanced.patches.youtube.utils.patch.PatchList.CHANGE_LIVE_RING_CLICK_ACTION import app.revanced.patches.youtube.utils.patch.PatchList.CHANGE_LIVE_RING_CLICK_ACTION
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.patches.youtube.video.playbackstart.playbackStartDescriptorPatch import app.revanced.patches.youtube.video.playbackstart.playbackStartDescriptorPatch
import app.revanced.patches.youtube.video.playbackstart.playbackStartVideoIdReference import app.revanced.patches.youtube.video.playbackstart.playbackStartVideoIdReference
import app.revanced.util.fingerprint.methodOrThrow import app.revanced.util.fingerprint.methodOrThrow
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstInstructionReversedOrThrow import app.revanced.util.indexOfFirstInstructionReversedOrThrow
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.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
private const val EXTENSION_CLASS_DESCRIPTOR = private const val EXTENSION_CLASS_DESCRIPTOR =
"$GENERAL_PATH/OpenChannelOfLiveAvatarPatch;" "$GENERAL_PATH/OpenChannelOfLiveAvatarPatch;"
@ -33,18 +34,12 @@ val openChannelOfLiveAvatarPatch = bytecodePatch(
dependsOn( dependsOn(
settingsPatch, settingsPatch,
sharedResourceIdPatch,
playbackStartDescriptorPatch, playbackStartDescriptorPatch,
engagementPanelHookPatch, engagementPanelHookPatch,
) )
execute { execute {
elementsImageFingerprint.methodOrThrow().addInstruction(
0,
"invoke-static { }, $EXTENSION_CLASS_DESCRIPTOR->liveChannelAvatarClicked()V"
)
hookEngagementPanelState(EXTENSION_CLASS_DESCRIPTOR) hookEngagementPanelState(EXTENSION_CLASS_DESCRIPTOR)
clientSettingEndpointFingerprint.methodOrThrow().apply { clientSettingEndpointFingerprint.methodOrThrow().apply {
@ -66,6 +61,14 @@ val openChannelOfLiveAvatarPatch = bytecodePatch(
val playbackStartIndex = indexOfPlaybackStartDescriptorInstruction(this) + 1 val playbackStartIndex = indexOfPlaybackStartDescriptorInstruction(this) + 1
val playbackStartRegister = getInstruction<OneRegisterInstruction>(playbackStartIndex).registerA val playbackStartRegister = getInstruction<OneRegisterInstruction>(playbackStartIndex).registerA
val mapIndex = indexOfFirstInstructionOrThrow(playbackStartIndex) {
val reference = getReference<MethodReference>()
opcode == Opcode.INVOKE_STATIC &&
reference?.returnType == "Ljava/lang/Object;" &&
reference.parameterTypes.firstOrNull() == "Ljava/util/Map;"
}
val mapRegister = getInstruction<FiveRegisterInstruction>(mapIndex).registerC
freeIndex = indexOfFirstInstructionOrThrow(playbackStartIndex, Opcode.CONST_STRING) freeIndex = indexOfFirstInstructionOrThrow(playbackStartIndex, Opcode.CONST_STRING)
freeRegister = getInstruction<OneRegisterInstruction>(freeIndex).registerA freeRegister = getInstruction<OneRegisterInstruction>(freeIndex).registerA
@ -73,7 +76,7 @@ val openChannelOfLiveAvatarPatch = bytecodePatch(
playbackStartIndex + 1, """ playbackStartIndex + 1, """
invoke-virtual { v$playbackStartRegister }, $playbackStartVideoIdReference invoke-virtual { v$playbackStartRegister }, $playbackStartVideoIdReference
move-result-object v$freeRegister move-result-object v$freeRegister
invoke-static { v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->openChannelOfLiveAvatar(Ljava/lang/String;)V invoke-static { v$mapRegister, v$freeRegister }, $EXTENSION_CLASS_DESCRIPTOR->openChannelOfLiveAvatar(Ljava/util/Map;Ljava/lang/String;)V
""" """
) )
} }

View File

@ -83,8 +83,6 @@ var easySeekEduContainer = -1L
private set private set
var editSettingsAction = -1L var editSettingsAction = -1L
private set private set
var elementsImage = -1L
private set
var endScreenElementLayoutCircle = -1L var endScreenElementLayoutCircle = -1L
private set private set
var endScreenElementLayoutIcon = -1L var endScreenElementLayoutIcon = -1L
@ -390,10 +388,6 @@ internal val sharedResourceIdPatch = resourcePatch(
STRING, STRING,
"edit_settings_action" "edit_settings_action"
] ]
elementsImage = resourceMappings[
ID,
"elements_image"
]
endScreenElementLayoutCircle = resourceMappings[ endScreenElementLayoutCircle = resourceMappings[
LAYOUT, LAYOUT,
"endscreen_element_layout_circle" "endscreen_element_layout_circle"