feat(YouTube): Support version 18.29.38

This commit is contained in:
oSumAtrIX
2023-08-23 05:01:09 +02:00
parent 038d6b215a
commit 52df1e6814
32 changed files with 214 additions and 334 deletions
@@ -19,8 +19,5 @@ object SubtitleButtonControllerFingerprint : MethodFingerprint(
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.IGET_OBJECT,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("SubtitleButtonController;")
}
)
)
@@ -1,10 +0,0 @@
package app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object LayoutConstructorFingerprint : MethodFingerprint(
strings = listOf("1.0x"),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
}
)
@@ -17,7 +17,7 @@ import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.buttons.autoplay.annotations.AutoplayButtonCompatibility
import app.revanced.patches.youtube.layout.buttons.autoplay.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import com.android.tools.smali.dexlib2.iface.instruction.Instruction
@@ -38,12 +38,12 @@ class HideCaptionsButtonPatch : BytecodePatch(listOf(
val subtitleButtonControllerMethod = SubtitleButtonControllerFingerprint.result!!.mutableMethod
// Due to previously applied patches, scanResult index cannot be used in this context
val igetBooleanIndex = subtitleButtonControllerMethod.implementation!!.instructions.indexOfFirst {
val insertIndex = subtitleButtonControllerMethod.implementation!!.instructions.indexOfFirst {
it.opcode == Opcode.IGET_BOOLEAN
}
} + 1
subtitleButtonControllerMethod.addInstruction(
igetBooleanIndex + 1,
insertIndex,
"""
invoke-static {v0}, Lapp/revanced/integrations/patches/HideCaptionsButtonPatch;->hideCaptionsButton(Landroid/widget/ImageView;)V
"""
@@ -1,15 +1,10 @@
package app.revanced.patches.youtube.layout.hide.loadmorebutton.bytecode.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.util.patch.LiteralValueFingerprint
import app.revanced.patches.youtube.layout.hide.loadmorebutton.resource.patch.HideLoadMoreButtonResourcePatch
import com.android.tools.smali.dexlib2.AccessFlags
import app.revanced.util.patch.LiteralValueFingerprint
import com.android.tools.smali.dexlib2.Opcode
object HideLoadMoreButtonFingerprint : LiteralValueFingerprint(
returnType = "V",
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
parameters = listOf("L", "L", "L", "L"),
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
@@ -17,7 +17,6 @@ object CreatePlayerOverviewFingerprint : MethodFingerprint(
Opcode.CHECK_CAST
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("YouTubeControlsOverlay;")
&& methodDef.containsConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId)
methodDef.containsConstantInstructionValue(HidePlayerOverlayResourcePatch.scrimOverlayId)
}
)
@@ -1,28 +1,24 @@
package app.revanced.patches.youtube.layout.hide.time.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.annotation.FuzzyPatternScanMethod
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
@FuzzyPatternScanMethod(1)
object TimeCounterFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf(),
returnType = "V",
opcodes = listOf(
Opcode.SUB_LONG_2ADDR,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
"V", AccessFlags.PUBLIC or AccessFlags.FINAL, listOf(), listOf(
Opcode.IGET_OBJECT,
Opcode.IGET_WIDE,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.INVOKE_INTERFACE,
Opcode.RETURN_VOID,
),
customFingerprint = { _, classDef ->
// On older devices this fingerprint resolves very slowly.
// Speed this up by checking for the number of methods.
classDef.methods.count() == 14
}
Opcode.CONST_WIDE_16,
Opcode.CMP_LONG,
Opcode.IF_LEZ,
Opcode.IGET_OBJECT,
Opcode.IF_EQZ,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT,
Opcode.IF_EQZ,
Opcode.GOTO,
)
)
@@ -1,8 +0,0 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.annotations
import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package
@Compatibility([Package("com.google.android.youtube", arrayOf("18.16.37", "18.19.35", "18.20.39", "18.23.35"))])
@Target(AnnotationTarget.CLASS)
internal annotation class FullscreenPanelsCompatibility
@@ -1,11 +0,0 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
object FullscreenViewAdderFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.IGET_BOOLEAN
)
)
@@ -1,20 +0,0 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.Opcode
object FullscreenViewAdderParentFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("Landroid/content/Context;", "Landroid/view/View;"),
opcodes = listOf(
Opcode.GOTO,
Opcode.IGET_BOOLEAN,
Opcode.IF_EQ,
Opcode.GOTO,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass.endsWith("FullscreenEngagementPanelOverlay;")
}
)
@@ -1,63 +0,0 @@
package app.revanced.patches.youtube.layout.panels.fullscreen.remove.patch
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.panels.fullscreen.remove.annotations.FullscreenPanelsCompatibility
import app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints.FullscreenViewAdderFingerprint
import app.revanced.patches.youtube.layout.panels.fullscreen.remove.fingerprints.FullscreenViewAdderParentFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
@Patch
@Name("Disable fullscreen panels")
@DependsOn([IntegrationsPatch::class, SettingsPatch::class])
@Description("Disables video description and comments panel in fullscreen view.")
@FullscreenPanelsCompatibility
class FullscreenPanelsRemoverPatch : BytecodePatch(
listOf(
FullscreenViewAdderParentFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_hide_fullscreen_panels",
StringResource("revanced_hide_fullscreen_panels_title", "Hide fullscreen panels"),
StringResource("revanced_hide_fullscreen_panels_summary_on", "Fullscreen panels are hidden"),
StringResource("revanced_hide_fullscreen_panels_summary_off", "Fullscreen panels are shown")
)
)
val parentResult = FullscreenViewAdderParentFingerprint.result!!
FullscreenViewAdderFingerprint.resolve(context, parentResult.method, parentResult.classDef)
val result = FullscreenViewAdderParentFingerprint.result
?: return PatchResultError("Fingerprint not resolved!")
val method = result.mutableMethod
val ifIndex = result.scanResult.patternScanResult!!.startIndex + 2
method.removeInstruction(ifIndex)
method.addInstructions(
ifIndex,
"""
invoke-static {}, Lapp/revanced/integrations/patches/FullscreenPanelsRemoverPatch;->getFullscreenPanelsVisibility()I
move-result p1
"""
)
return PatchResultSuccess()
}
}
@@ -1,12 +1,12 @@
package app.revanced.patches.youtube.layout.returnyoutubedislike.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object ShortsTextViewFingerprint : MethodFingerprint(
accessFlags = AccessFlags.PROTECTED or AccessFlags.FINAL,
// 18.29.38 method is public final visibility, but in 18.23.35 and older it's protected final.
// If 18.23.35 is dropped then accessFlags should be specified here.
returnType = "V",
parameters = listOf("L", "L"),
opcodes = listOf(
@@ -15,7 +15,7 @@ object TextComponentAtomicReferenceFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.MOVE_OBJECT_FROM16, // available unused register
Opcode.MOVE_OBJECT_FROM16,
Opcode.MOVE_OBJECT_FROM16,
null, // move-object/from16 or move/from16
Opcode.MOVE_OBJECT_FROM16,
Opcode.INVOKE_VIRTUAL, // CharSequence atomic reference
Opcode.MOVE_RESULT_OBJECT,
@@ -19,9 +19,6 @@ object ControlsOverlayFingerprint : MethodFingerprint(
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
Opcode.NEW_INSTANCE,
),
customFingerprint = { methodDef, _ ->
methodDef.definingClass == "Lcom/google/android/apps/youtube/app/player/overlay/YouTubeControlsOverlay;"
}
Opcode.NEW_INSTANCE
)
)
@@ -17,6 +17,7 @@ import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.fingerprints.LayoutConstructorFingerprint
import app.revanced.patches.shared.fingerprints.SeekbarFingerprint
import app.revanced.patches.shared.fingerprints.SeekbarOnDrawFingerprint
import app.revanced.patches.shared.mapping.misc.patch.ResourceMappingPatch
@@ -59,23 +60,16 @@ class SponsorBlockBytecodePatch : BytecodePatch(
listOf(
SeekbarFingerprint,
AppendTimeFingerprint,
ControlsOverlayFingerprint,
LayoutConstructorFingerprint,
AutoRepeatParentFingerprint,
)
) {
private companion object {
const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/SegmentPlaybackController;"
const val INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController;"
const val INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/VotingButtonController;"
const val INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/SponsorBlockViewController;"
}
override fun execute(context: BytecodeContext): PatchResult {
LayoutConstructorFingerprint.result?.let {
if (!ControlsOverlayFingerprint.resolve(context, it.classDef))
throw ControlsOverlayFingerprint.toErrorResult()
} ?: return LayoutConstructorFingerprint.toErrorResult()
/*
* Hook the video time methods
*/
@@ -279,4 +273,15 @@ class SponsorBlockBytecodePatch : BytecodePatch(
return PatchResultSuccess()
}
private companion object {
const val INTEGRATIONS_SEGMENT_PLAYBACK_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/SegmentPlaybackController;"
const val INTEGRATIONS_CREATE_SEGMENT_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/CreateSegmentButtonController;"
const val INTEGRATIONS_VOTING_BUTTON_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/VotingButtonController;"
const val INTEGRATIONS_SPONSORBLOCK_VIEW_CONTROLLER_CLASS_DESCRIPTOR =
"Lapp/revanced/integrations/sponsorblock/ui/SponsorBlockViewController;"
}
}
@@ -3,21 +3,10 @@ package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
object MiniPlayerOverrideFingerprint : MethodFingerprint(
"Z", AccessFlags.STATIC or AccessFlags.PUBLIC,
listOf("Landroid/content/Context;"),
opcodes = listOf(
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT,
Opcode.CONST_4,
Opcode.IF_EQ,
Opcode.CONST_4,
Opcode.IF_EQ,
Opcode.CONST_4, // override this value
Opcode.RETURN,
Opcode.CONST_4, // override this value
Opcode.RETURN
),
returnType = "L",
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
parameters = listOf("L"),
strings = listOf("appName")
)
@@ -1,7 +0,0 @@
package app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object MiniPlayerOverrideParentFingerprint : MethodFingerprint(
strings = listOf("Unset or unknown Input OneOf case for dynamic input")
)
@@ -4,6 +4,7 @@ import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.data.toMethodWalker
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
@@ -17,7 +18,10 @@ import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
import app.revanced.patches.shared.settings.preference.impl.StringResource
import app.revanced.patches.shared.settings.preference.impl.SwitchPreference
import app.revanced.patches.youtube.layout.tabletminiplayer.annotations.TabletMiniPlayerCompatibility
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.*
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorParentFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
import app.revanced.patches.youtube.layout.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import com.android.tools.smali.dexlib2.Opcode
@@ -32,7 +36,7 @@ class TabletMiniPlayerPatch : BytecodePatch(
listOf(
MiniPlayerDimensionsCalculatorParentFingerprint,
MiniPlayerResponseModelSizeCheckFingerprint,
MiniPlayerOverrideParentFingerprint
MiniPlayerOverrideFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
@@ -62,33 +66,33 @@ class TabletMiniPlayerPatch : BytecodePatch(
/** same register used to return **/
)
/*
* Method with context parameter.
*/
MiniPlayerOverrideParentFingerprint.result?.let {
if (!MiniPlayerOverrideFingerprint.resolve(context, it.classDef))
throw MiniPlayerOverrideFingerprint.toErrorResult()
} ?: return MiniPlayerOverrideParentFingerprint.toErrorResult()
/*
* Override every return instruction with the proxy call.
*/
MiniPlayerOverrideFingerprint.result!!.mutableMethod.apply {
implementation!!.let { implementation ->
val returnIndices = implementation.instructions
.withIndex()
.filter { (_, instruction) -> instruction.opcode == Opcode.RETURN }
.map { (index, _) -> index }
MiniPlayerOverrideFingerprint.result?.let { result ->
result.mutableMethod.let { method ->
val appNameStringIndex = result.scanResult.stringsScanResult!!.matches.first().index + 2
context.toMethodWalker(method).nextMethod(appNameStringIndex, true)
.getMethod() as MutableMethod
}.apply {
implementation!!.let { implementation ->
val returnIndices = implementation.instructions
.withIndex()
.filter { (_, instruction) -> instruction.opcode == Opcode.RETURN }
.map { (index, _) -> index }
if (returnIndices.isEmpty()) throw PatchResultError("No return instructions found.")
if (returnIndices.isEmpty()) throw PatchResultError("No return instructions found.")
// This method clobbers register p0 to return the value, calculate to override.
val returnedRegister = implementation.registerCount - parameters.size
// This method clobbers register p0 to return the value, calculate to override.
val returnedRegister = implementation.registerCount - parameters.size
// Hook the returned register on every return instruction.
returnIndices.forEach { index -> insertOverride(index, returnedRegister) }
// Hook the returned register on every return instruction.
returnIndices.forEach { index -> insertOverride(index, returnedRegister) }
}
}
}
return@let
} ?: return MiniPlayerOverrideFingerprint.toErrorResult()
/*
* Size check return value override.