refactor(YouTube - Hide end screen suggested video): Use more idiomatic APIs
This commit is contained in:
parent
11bd06d374
commit
b826db02e3
2 changed files with 74 additions and 34 deletions
|
|
@ -1,14 +1,25 @@
|
|||
package app.revanced.patches.youtube.layout.hide.endscreensuggestedvideo
|
||||
|
||||
import app.revanced.patcher.*
|
||||
import app.revanced.patcher.extensions.instructions
|
||||
import app.revanced.patcher.accessFlags
|
||||
import app.revanced.patcher.definingClass
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.methodReference
|
||||
import app.revanced.patcher.firstMethodComposite
|
||||
import app.revanced.patcher.instructions
|
||||
import app.revanced.patcher.name
|
||||
import app.revanced.patcher.parameterTypes
|
||||
import app.revanced.patcher.patch.BytecodePatchContext
|
||||
import app.revanced.patcher.returnType
|
||||
import com.android.tools.smali.dexlib2.AccessFlags
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.ClassDef
|
||||
import com.android.tools.smali.dexlib2.iface.Method
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
|
||||
internal val BytecodePatchContext.autoNavConstructorMethod by gettingFirstImmutableMethodDeclaratively("main_app_autonav") {
|
||||
internal val BytecodePatchContext.autoNavConstructorMethod by gettingFirstImmutableMethodDeclaratively(
|
||||
"main_app_autonav"
|
||||
) {
|
||||
returnType("V")
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.CONSTRUCTOR)
|
||||
}
|
||||
|
|
@ -24,15 +35,50 @@ internal val BytecodePatchContext.removeOnLayoutChangeListenerMethodMatch by com
|
|||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes()
|
||||
opcodes(
|
||||
Opcode.IPUT,
|
||||
Opcode.INVOKE_VIRTUAL,
|
||||
instructions(
|
||||
allOf(Opcode.IPUT(), field { type == "I" }),
|
||||
afterAtMost(
|
||||
3,
|
||||
allOf(
|
||||
Opcode.INVOKE_VIRTUAL(),
|
||||
method { returnType == "V" && parameterTypes.isEmpty() }
|
||||
)
|
||||
),
|
||||
allOf(Opcode.INVOKE_VIRTUAL(), method {
|
||||
name == "removeOnLayoutChangeListener" &&
|
||||
returnType == "Z" &&
|
||||
definingClass == "Lcom/google/android/apps/youtube/app/common/" +
|
||||
"player/overlay/YouTubePlayerOverlaysLayout;"
|
||||
}),
|
||||
)
|
||||
// This is the only reference present in the entire smali.
|
||||
custom {
|
||||
instructions.anyInstruction {
|
||||
val reference = methodReference
|
||||
reference?.name == "removeOnLayoutChangeListener" && reference.definingClass.endsWith("/YouTubePlayerOverlaysLayout;")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BytecodePatchContext.getEndScreenSuggestedVideoMethodMatch(autoNavStatusMethod: Method): CompositeMatch {
|
||||
val endScreenMethod = removeOnLayoutChangeListenerMethodMatch.let {
|
||||
firstMethod(it.method.getInstruction<ReferenceInstruction>(it[1]).methodReference!!)
|
||||
}
|
||||
|
||||
return firstMethodComposite {
|
||||
name(endScreenMethod.name)
|
||||
definingClass(endScreenMethod.definingClass)
|
||||
accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL)
|
||||
returnType("V")
|
||||
parameterTypes()
|
||||
instructions(
|
||||
allOf(
|
||||
Opcode.IGET_OBJECT(),
|
||||
field {
|
||||
definingClass == endScreenMethod.definingClass &&
|
||||
type == autoNavStatusMethod.definingClass
|
||||
}
|
||||
),
|
||||
afterAtMost(
|
||||
3,
|
||||
allOf(
|
||||
Opcode.INVOKE_VIRTUAL(),
|
||||
method { this == autoNavStatusMethod }
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ package app.revanced.patches.youtube.layout.hide.endscreensuggestedvideo
|
|||
|
||||
import app.revanced.patcher.extensions.ExternalLabel
|
||||
import app.revanced.patcher.extensions.addInstructionsWithLabels
|
||||
import app.revanced.patcher.extensions.fieldReference
|
||||
import app.revanced.patcher.extensions.getInstruction
|
||||
import app.revanced.patcher.extensions.methodReference
|
||||
import app.revanced.patcher.firstMethod
|
||||
import app.revanced.patcher.immutableClassDef
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.resources.addResources
|
||||
|
|
@ -11,9 +13,6 @@ import app.revanced.patches.all.misc.resources.addResourcesPatch
|
|||
import app.revanced.patches.shared.misc.settings.preference.SwitchPreference
|
||||
import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch
|
||||
import app.revanced.patches.youtube.misc.settings.PreferenceScreen
|
||||
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||
import app.revanced.util.indexOfFirstInstructionReversedOrThrow
|
||||
import com.android.tools.smali.dexlib2.Opcode
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
|
||||
|
||||
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||
|
|
@ -41,32 +40,27 @@ val hideEndScreenSuggestedVideoPatch = bytecodePatch(
|
|||
)
|
||||
|
||||
apply {
|
||||
addResources("youtube", "layout.hide.endscreensuggestedvideo.hideEndScreenSuggestedVideoPatch")
|
||||
addResources(
|
||||
"youtube",
|
||||
"layout.hide.endscreensuggestedvideo.hideEndScreenSuggestedVideoPatch"
|
||||
)
|
||||
|
||||
PreferenceScreen.PLAYER.addPreferences(
|
||||
SwitchPreference("revanced_end_screen_suggested_video"),
|
||||
)
|
||||
|
||||
removeOnLayoutChangeListenerMethodMatch.let {
|
||||
val endScreenMethod = navigate(it.immutableMethod).to(it[-1]).stop()
|
||||
|
||||
endScreenMethod.apply {
|
||||
val autoNavStatusMethodName =
|
||||
autoNavConstructorMethod.immutableClassDef.getAutoNavStatusMethod().name
|
||||
val autoNavStatusMethod =
|
||||
autoNavConstructorMethod.immutableClassDef.getAutoNavStatusMethod()
|
||||
|
||||
val invokeIndex = indexOfFirstInstructionOrThrow {
|
||||
val reference = methodReference
|
||||
reference?.name == autoNavStatusMethodName &&
|
||||
reference.returnType == "Z" &&
|
||||
reference.parameterTypes.isEmpty()
|
||||
}
|
||||
val endScreenMethod = removeOnLayoutChangeListenerMethodMatch.let {
|
||||
firstMethod(it.method.getInstruction<ReferenceInstruction>(it[1]).methodReference!!)
|
||||
}
|
||||
|
||||
val iGetObjectIndex =
|
||||
indexOfFirstInstructionReversedOrThrow(invokeIndex, Opcode.IGET_OBJECT)
|
||||
val invokeReference = getInstruction<ReferenceInstruction>(invokeIndex).reference
|
||||
val iGetObjectReference =
|
||||
getInstruction<ReferenceInstruction>(iGetObjectIndex).reference
|
||||
val opcodeName = getInstruction(invokeIndex).opcode.name
|
||||
|
||||
getEndScreenSuggestedVideoMethodMatch(autoNavStatusMethod).let { match ->
|
||||
match.method.apply {
|
||||
val autoNavField = getInstruction(match[0]).fieldReference!!
|
||||
|
||||
addInstructionsWithLabels(
|
||||
0,
|
||||
|
|
@ -75,10 +69,10 @@ val hideEndScreenSuggestedVideoPatch = bytecodePatch(
|
|||
move-result v0
|
||||
if-eqz v0, :show_end_screen_recommendation
|
||||
|
||||
iget-object v0, p0, $iGetObjectReference
|
||||
iget-object v0, p0, $autoNavField
|
||||
|
||||
# This reference checks whether autoplay is turned on.
|
||||
$opcodeName { v0 }, $invokeReference
|
||||
invoke-virtual { v0 }, $autoNavStatusMethod
|
||||
move-result v0
|
||||
|
||||
# Hide suggested video end screen only when autoplay is turned off.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue