diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/SearchTermThumbnailPatch.kt b/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/SearchTermThumbnailPatch.kt new file mode 100644 index 000000000..6b08e1604 --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/SearchTermThumbnailPatch.kt @@ -0,0 +1,140 @@ +package app.revanced.patches.youtube.general.searchterm + +import app.revanced.extensions.exception +import app.revanced.patcher.data.BytecodeContext +import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction +import app.revanced.patcher.patch.BytecodePatch +import app.revanced.patcher.patch.PatchException +import app.revanced.patcher.patch.annotation.CompatiblePackage +import app.revanced.patcher.patch.annotation.Patch +import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod +import app.revanced.patcher.util.smali.ExternalLabel +import app.revanced.patches.youtube.general.searchterm.fingerprints.SearchTermThumbnailFingerprint +import app.revanced.patches.youtube.utils.settings.SettingsPatch +import app.revanced.util.integrations.Constants.GENERAL +import com.android.tools.smali.dexlib2.Opcode +import com.android.tools.smali.dexlib2.iface.instruction.NarrowLiteralInstruction +import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction +import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction + +@Patch( + name = "Hide search term thumbnail", + description = "Hide thumbnails in the search term history.", + dependencies = [SettingsPatch::class], + compatiblePackages = [ + CompatiblePackage( + "com.google.android.youtube", + [ + "18.25.40", + "18.27.36", + "18.29.38", + "18.30.37", + "18.31.40", + "18.32.39", + "18.33.40", + "18.34.38", + "18.35.36", + "18.36.39", + "18.37.36", + "18.38.44", + "18.39.41", + "18.40.34" + ] + ) + ] +) +@Suppress("unused") +object SearchTermThumbnailPatch : BytecodePatch( + setOf(SearchTermThumbnailFingerprint) +) { + override fun execute(context: BytecodeContext) { + SearchTermThumbnailFingerprint.result?.let { result -> + result.mutableMethod.apply { + val instructions = implementation!!.instructions + + val relativeIndex = instructions.indexOfFirst { instruction -> + instruction.opcode == Opcode.CONST_16 + && (instruction as NarrowLiteralInstruction).narrowLiteral == 40 + } + + val replaceIndex = + getTargetIndexDownTo( + relativeIndex, + Opcode.INVOKE_VIRTUAL, + "Landroid/widget/ImageView;->setVisibility(I)V" + ) - 1 + + val jumpIndex = + getTargetIndexUpTo( + relativeIndex, + Opcode.INVOKE_STATIC, + "Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;" + ) + 4 + + val replaceIndexInstruction = getInstruction(replaceIndex) + val replaceIndexReference = getInstruction(replaceIndex).reference + + addInstructionsWithLabels( + replaceIndex + 1, """ + invoke-static { }, $GENERAL->hideSearchTermThumbnail()Z + move-result v${replaceIndexInstruction.registerA} + if-nez v${replaceIndexInstruction.registerA}, :hidden + iget-object v${replaceIndexInstruction.registerA}, v${replaceIndexInstruction.registerB}, $replaceIndexReference + """, ExternalLabel("hidden", getInstruction(jumpIndex)) + ) + removeInstruction(replaceIndex) + } + } ?: throw SearchTermThumbnailFingerprint.exception + + /** + * Add settings + */ + SettingsPatch.addPreference( + arrayOf( + "PREFERENCE: GENERAL_SETTINGS", + "SETTINGS: HIDE_SEARCH_TERM_THUMBNAIL" + ) + ) + + SettingsPatch.updatePatchStatus("Hide search term thumbnail") + + } + + private fun MutableMethod.getTargetIndexDownTo( + startIndex: Int, + opcode: Opcode, + reference: String + ): Int { + for (index in startIndex downTo 0) { + if (getInstruction(index).opcode != opcode) + continue + + val targetReference = getInstruction(index).reference.toString() + if (targetReference != reference) + continue + + return index + } + throw PatchException("Failed to find hook method") + } + + private fun MutableMethod.getTargetIndexUpTo( + startIndex: Int, + opcode: Opcode, + reference: String + ): Int { + for (index in startIndex until implementation!!.instructions.size) { + if (getInstruction(index).opcode != opcode) + continue + + val targetReference = getInstruction(index).reference.toString() + if (targetReference != reference) + continue + + return index + } + throw PatchException("Failed to find hook method") + } +} diff --git a/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/fingerprints/SearchTermThumbnailFingerprint.kt b/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/fingerprints/SearchTermThumbnailFingerprint.kt new file mode 100644 index 000000000..d7ad1a38c --- /dev/null +++ b/src/main/kotlin/app/revanced/patches/youtube/general/searchterm/fingerprints/SearchTermThumbnailFingerprint.kt @@ -0,0 +1,12 @@ +package app.revanced.patches.youtube.general.searchterm.fingerprints + +import app.revanced.patcher.extensions.or +import app.revanced.patcher.fingerprint.MethodFingerprint +import com.android.tools.smali.dexlib2.AccessFlags + +object SearchTermThumbnailFingerprint : MethodFingerprint( + returnType = "Landroid/view/View;", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("I", "Landroid/view/View;", "Landroid/view/ViewGroup;"), + strings = listOf("ss_rds") +) \ No newline at end of file diff --git a/src/main/resources/youtube/settings/host/values/strings.xml b/src/main/resources/youtube/settings/host/values/strings.xml index 3fe3c5efb..8722adba0 100644 --- a/src/main/resources/youtube/settings/host/values/strings.xml +++ b/src/main/resources/youtube/settings/host/values/strings.xml @@ -488,6 +488,9 @@ Some components may not be hidden." Search bar is shown. Search bar is hidden. Hide search bar in home feed + Thumbnails in the search term history are shown. + Thumbnails in the search term history are hidden. + Hide search term thumbnail Video player seekbar is shown. Video player seekbar is hidden. Thumbnail seekbar is shown. diff --git a/src/main/resources/youtube/settings/xml/revanced_prefs.xml b/src/main/resources/youtube/settings/xml/revanced_prefs.xml index 74fe9c1a8..8cda48ca6 100644 --- a/src/main/resources/youtube/settings/xml/revanced_prefs.xml +++ b/src/main/resources/youtube/settings/xml/revanced_prefs.xml @@ -205,6 +205,9 @@ + + @@ -370,6 +373,7 @@ +