Skip to content

Commit

Permalink
fix(youtube/hide-endscreen-cards): restore functionality (#993)
Browse files Browse the repository at this point in the history
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
  • Loading branch information
OxrxL and oSumAtrIX committed Nov 8, 2022
1 parent 02afb56 commit 9de797b
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
"ad_attribution",
"reel_multiple_items_shelf",
"info_cards_drawer_header",
"endscreen_element_layout_video",
"endscreen_element_layout_circle",
"endscreen_element_layout_icon",
).map { name ->
ResourceMappingResourcePatch.resourceMappings.single { it.name == name }.id
}
Expand Down Expand Up @@ -242,26 +239,6 @@ class GeneralBytecodeAdsPatch : BytecodePatch() {
//ToDo: Add Settings toggle for whatever this is
mutableMethod!!.implementation!!.removeInstruction(removeIndex)
}

resourceIds[3], resourceIds[4], resourceIds[5] -> { // end screen ads
// and is followed by an instruction with the mnemonic IPUT_OBJECT
val insertIndex = index + 7
val invokeInstruction = instructions.elementAt(insertIndex)
if (invokeInstruction.opcode != Opcode.IPUT_OBJECT) return@forEachIndexed

// create proxied method, make sure to not re-resolve() the current class
if (mutableClass == null) mutableClass = context.proxy(classDef).mutableClass
if (mutableMethod == null) mutableMethod =
mutableClass!!.findMutableMethodOf(method)

// TODO: dynamically get registers
mutableMethod!!.addInstructions(
insertIndex, """
const/16 v1, 0x8
invoke-virtual {v0,v1}, Landroid/widget/FrameLayout;->setVisibility(I)V
"""
)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package app.revanced.patches.youtube.layout.hideendscreencards.annotations

import app.revanced.patcher.annotation.Compatibility
import app.revanced.patcher.annotation.Package

@Compatibility(
[Package(
"com.google.android.youtube", arrayOf("17.36.37", "17.41.37", "17.42.35", "17.43.36")
)]
)
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
internal annotation class HideEndscreenCardsCompatibility
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints

import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction

@Name("layout-circle-fingerprint")
@HideEndscreenCardsCompatibility
@Version("0.0.1")
object LayoutCircleFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutCircle
} == true
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints

import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction

@Name("layout-icon-fingerprint")
@HideEndscreenCardsCompatibility
@Version("0.0.1")
object LayoutIconFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST_4,
Opcode.CONST,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutIcon
} == true
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints

import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction

@Name("layout-video-fingerprint")
@HideEndscreenCardsCompatibility
@Version("0.0.1")
object LayoutVideoFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.CONST,
Opcode.CONST_4,
Opcode.INVOKE_VIRTUAL,
Opcode.MOVE_RESULT_OBJECT,
Opcode.CHECK_CAST,
),
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any { instruction ->
instruction.opcode.ordinal == Opcode.CONST.ordinal &&
(instruction as? WideLiteralInstruction)?.wideLiteral == HideEndscreenCardsResourcePatch.layoutVideo
} == true
}
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package app.revanced.patches.youtube.layout.hideendscreencards.bytecode.patch

import app.revanced.patcher.annotation.Description
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.fingerprint.Fingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprintResult
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
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.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutCircleFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutIconFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.bytecode.fingerprints.LayoutVideoFingerprint
import app.revanced.patches.youtube.layout.hideendscreencards.resource.patch.HideEndscreenCardsResourcePatch
import app.revanced.patches.youtube.misc.integrations.patch.IntegrationsPatch
import org.jf.dexlib2.iface.instruction.formats.Instruction21c

@Patch
@DependsOn([IntegrationsPatch::class, HideEndscreenCardsResourcePatch::class])
@Name("hide-endscreen-cards")
@Description("Hides the suggested video cards at the end of a video in fullscreen.")
@HideEndscreenCardsCompatibility
@Version("0.0.1")
class HideEndscreenCardsPatch : BytecodePatch(
listOf(
LayoutCircleFingerprint,
LayoutIconFingerprint,
LayoutVideoFingerprint,
)
) {
override fun execute(context: BytecodeContext): PatchResult {
fun MethodFingerprint.injectHideCall() {
val layoutResult = result!!
val layoutMethod = layoutResult.mutableMethod

val checkCastIndex = layoutResult.scanResult.patternScanResult!!.endIndex
val viewRegister = (layoutMethod.instruction(checkCastIndex) as Instruction21c).registerA

layoutMethod.addInstruction(
checkCastIndex + 1,
"invoke-static { v$viewRegister }, Lapp/revanced/integrations/patches/HideEndscreenCardsPatch;->hideEndscreen(Landroid/view/View;)V"
)
}

listOf(LayoutCircleFingerprint, LayoutIconFingerprint, LayoutVideoFingerprint).forEach(MethodFingerprint::injectHideCall)

return PatchResultSuccess()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package app.revanced.patches.youtube.layout.hideendscreencards.resource.patch

import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.ResourceContext
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.ResourcePatch
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patches.youtube.layout.hideendscreencards.annotations.HideEndscreenCardsCompatibility
import app.revanced.patches.youtube.misc.mapping.patch.ResourceMappingResourcePatch
import app.revanced.patches.youtube.misc.settings.bytecode.patch.SettingsPatch
import app.revanced.patches.youtube.misc.settings.framework.components.impl.StringResource
import app.revanced.patches.youtube.misc.settings.framework.components.impl.SwitchPreference

@Name("hide-endscreen-cards-resource-patch")
@HideEndscreenCardsCompatibility
@DependsOn([SettingsPatch::class, ResourceMappingResourcePatch::class])
@Version("0.0.1")
class HideEndscreenCardsResourcePatch : ResourcePatch {
internal companion object {
var layoutCircle: Long = -1
var layoutIcon: Long = -1
var layoutVideo: Long = -1
}

override fun execute(context: ResourceContext): PatchResult {
SettingsPatch.PreferenceScreen.LAYOUT.addPreferences(
SwitchPreference(
"revanced_hide_endscreen_cards",
StringResource("revanced_hide_endscreen_cards_title", "Hide end-screen cards"),
true,
StringResource("revanced_hide_endscreen_cards_summary_on", "End-screen cards are hidden"),
StringResource("revanced_hide_endscreen_cards_summary_off", "End-screen cards are shown")
),
)

fun findEndscreenResourceId(name: String) = ResourceMappingResourcePatch.resourceMappings.single {
it.type == "layout" && it.name == "endscreen_element_layout_$name"
}.id

layoutCircle = findEndscreenResourceId("circle")
layoutIcon = findEndscreenResourceId("icon")
layoutVideo = findEndscreenResourceId("video")

return PatchResultSuccess()
}
}

0 comments on commit 9de797b

Please sign in to comment.