fix(YouTube/Hide captions button): patch does not work when A/B testing is applied

This commit is contained in:
inotia00 2023-12-28 21:52:00 +09:00
parent dcd5ffe82e
commit 61ddd921fb
4 changed files with 71 additions and 14 deletions

View File

@ -2,22 +2,26 @@ package app.revanced.patches.youtube.player.captionsbutton
import app.revanced.patcher.data.BytecodeContext
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.annotation.CompatiblePackage
import app.revanced.patcher.patch.annotation.Patch
import app.revanced.patches.youtube.utils.fingerprints.SubtitleButtonControllerFingerprint
import app.revanced.patches.youtube.player.captionsbutton.fingerprints.LithoSubtitleButtonConfigFingerprint
import app.revanced.patches.youtube.player.captionsbutton.fingerprints.YouTubeControlsOverlaySubtitleButtonFingerprint
import app.revanced.patches.youtube.utils.integrations.Constants.COMPONENTS_PATH
import app.revanced.patches.youtube.utils.integrations.Constants.PLAYER
import app.revanced.patches.youtube.utils.litho.LithoFilterPatch
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
import app.revanced.patches.youtube.utils.settings.SettingsPatch
import app.revanced.util.exception
import com.android.tools.smali.dexlib2.Opcode
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction
@Patch(
name = "Hide captions button",
description = "Hides the captions button in the video player.",
dependencies = [
LithoFilterPatch::class,
SettingsPatch::class,
SharedResourceIdPatch::class,
],
@ -50,27 +54,46 @@ import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
)
@Suppress("unused")
object HideCaptionsButtonBytecodePatch : BytecodePatch(
setOf(SubtitleButtonControllerFingerprint)
setOf(
LithoSubtitleButtonConfigFingerprint,
YouTubeControlsOverlaySubtitleButtonFingerprint
)
) {
override fun execute(context: BytecodeContext) {
SubtitleButtonControllerFingerprint.result?.let {
/**
* Added in YouTube v18.31.40
*
* No exception even if fail to resolve fingerprints.
* For compatibility with YouTube v18.25.40 ~ YouTube v18.30.37.
*/
LithoSubtitleButtonConfigFingerprint.result?.let {
it.mutableMethod.apply {
val targetIndex = implementation!!.instructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.IGET_OBJECT
}
val targetRegister = getInstruction<TwoRegisterInstruction>(targetIndex).registerA
val insertIndex = implementation!!.instructions.size - 1
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
val insertIndex = implementation!!.instructions.indexOfFirst { instruction ->
instruction.opcode == Opcode.IGET_BOOLEAN
} + 1
addInstructions(
insertIndex, """
invoke-static {v$insertRegister}, $PLAYER->hideCaptionsButton(Z)Z
move-result v$insertRegister
"""
)
}
}
YouTubeControlsOverlaySubtitleButtonFingerprint.result?.let {
it.mutableMethod.apply {
val insertIndex = implementation!!.instructions.size - 1
val insertRegister = getInstruction<OneRegisterInstruction>(insertIndex).registerA
addInstruction(
insertIndex,
"invoke-static {v$targetRegister}, $PLAYER->hideCaptionsButton(Landroid/widget/ImageView;)V"
"invoke-static {v$insertRegister}, $PLAYER->hideCaptionsButton(Landroid/view/View;)V"
)
}
} ?: throw SubtitleButtonControllerFingerprint.exception
} ?: throw YouTubeControlsOverlaySubtitleButtonFingerprint.exception
LithoFilterPatch.addFilter("$COMPONENTS_PATH/CaptionsFilter;")
/**
* Add settings

View File

@ -0,0 +1,14 @@
package app.revanced.patches.youtube.player.captionsbutton.fingerprints
import app.revanced.util.fingerprint.LiteralValueFingerprint
/**
* Added in YouTube v18.31.40
*
* When this value is TRUE, litho subtitle button is used.
* In this case, the empty area remains, so set this value to FALSE.
*/
object LithoSubtitleButtonConfigFingerprint : LiteralValueFingerprint(
returnType = "Z",
literalSupplier = { 45421555 }
)

View File

@ -0,0 +1,18 @@
package app.revanced.patches.youtube.player.captionsbutton.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YoutubeControlsOverlaySubtitleButton
import app.revanced.util.fingerprint.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
/**
* The parameters of the method have changed in YouTube v18.31.40.
* Therefore, this fingerprint does not check the method's parameters.
*
* This fingerprint is compatible from YouTube v18.25.40 to YouTube v18.45.43
*/
object YouTubeControlsOverlaySubtitleButtonFingerprint : LiteralValueFingerprint(
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.STATIC,
literalSupplier = { YoutubeControlsOverlaySubtitleButton }
)

View File

@ -83,6 +83,7 @@ object SharedResourceIdPatch : ResourcePatch() {
var VideoQualityBottomSheet: Long = -1
var VideoZoomIndicatorLayout: Long = -1
var YoutubeControlsOverlay: Long = -1
var YoutubeControlsOverlaySubtitleButton: Long = -1
var YtOutlineArrowTimeBlack: Long = -1
var YtOutlineFireBlack: Long = -1
var YtOutlineSearchBlack: Long = -1
@ -165,6 +166,7 @@ object SharedResourceIdPatch : ResourcePatch() {
VideoQualityBottomSheet = find(LAYOUT, "video_quality_bottom_sheet_list_fragment_title")
VideoZoomIndicatorLayout = find(ID, "video_zoom_indicator_layout")
YoutubeControlsOverlay = find(ID, "youtube_controls_overlay")
YoutubeControlsOverlaySubtitleButton = find(LAYOUT, "youtube_controls_overlay_subtitle_button")
YtOutlineArrowTimeBlack = find(DRAWABLE, "yt_outline_arrow_time_black_24")
YtOutlineFireBlack = find(DRAWABLE, "yt_outline_fire_black_24")
YtOutlineSearchBlack = find(DRAWABLE, "yt_outline_search_black_24")