From e0bdce0c190dc5a9298887adcde5c28b2d417c49 Mon Sep 17 00:00:00 2001 From: inotia00 <108592928+inotia00@users.noreply.github.com> Date: Sun, 8 Dec 2024 11:50:12 +0900 Subject: [PATCH] refactor(YouTube - PlayerTypeHook): Use search query instead of View to determine whether a user is in search results or not --- .../extension/youtube/shared/RootView.java | 24 +++++------- .../youtube/utils/playertype/Fingerprints.kt | 25 ++++++------ .../utils/playertype/PlayerTypeHookPatch.kt | 38 +++++++++++++------ .../utils/resourceid/SharedResourceIdPatch.kt | 6 --- 4 files changed, 50 insertions(+), 43 deletions(-) diff --git a/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/RootView.java b/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/RootView.java index 2dcebb9b8..1a6d97edd 100644 --- a/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/RootView.java +++ b/extensions/shared/src/main/java/app/revanced/extension/youtube/shared/RootView.java @@ -2,20 +2,8 @@ package app.revanced.extension.youtube.shared; import static app.revanced.extension.youtube.patches.components.RelatedVideoFilter.isActionBarVisible; -import android.view.View; - -import java.lang.ref.WeakReference; - @SuppressWarnings("unused") public final class RootView { - private static volatile WeakReference searchBarResultsRef = new WeakReference<>(null); - - /** - * Injection point. - */ - public static void searchBarResultsViewLoaded(View searchbarResults) { - searchBarResultsRef = new WeakReference<>(searchbarResults); - } /** * @return If the search bar is on screen. This includes if the player @@ -23,8 +11,8 @@ public final class RootView { * Detecting the search is covered by the player can be done by checking {@link RootView#isPlayerActive()}. */ public static boolean isSearchBarActive() { - View searchbarResults = searchBarResultsRef.get(); - return searchbarResults != null && searchbarResults.getParent() != null; + String searchQuery = getSearchQuery(); + return !searchQuery.isEmpty(); } public static boolean isPlayerActive() { @@ -38,4 +26,12 @@ public final class RootView { public static String getBrowseId() { return ""; } + + /** + * Get current SearchQuery. + * Rest of the implementation added by patch. + */ + public static String getSearchQuery() { + return ""; + } } diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/Fingerprints.kt index e54f60ab3..5a418d9f0 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/Fingerprints.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/Fingerprints.kt @@ -1,6 +1,5 @@ package app.revanced.patches.youtube.utils.playertype -import app.revanced.patches.youtube.utils.resourceid.actionBarSearchResultsViewMic import app.revanced.patches.youtube.utils.resourceid.reelWatchPlayer import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.getReference @@ -11,16 +10,6 @@ import com.android.tools.smali.dexlib2.Opcode import com.android.tools.smali.dexlib2.iface.Method import com.android.tools.smali.dexlib2.iface.reference.MethodReference -internal val actionBarSearchResultsFingerprint = legacyFingerprint( - name = "actionBarSearchResultsFingerprint", - accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, - returnType = "Landroid/view/View;", - literals = listOf(actionBarSearchResultsViewMic), - customFingerprint = { method, _ -> - indexOfLayoutDirectionInstruction(method) >= 0 - } -) - internal fun indexOfLayoutDirectionInstruction(method: Method) = method.indexOfFirstInstruction { opcode == Opcode.INVOKE_VIRTUAL && @@ -56,6 +45,20 @@ internal val reelWatchPagerFingerprint = legacyFingerprint( literals = listOf(reelWatchPlayer), ) +internal val searchQueryClassFingerprint = legacyFingerprint( + name = "searchQueryClassFingerprint", + returnType = "V", + accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL, + parameters = listOf("L", "Ljava/util/Map;"), + opcodes = listOf( + Opcode.CHECK_CAST, + Opcode.IGET_OBJECT, + Opcode.INVOKE_VIRTUAL, + Opcode.MOVE_RESULT, + ), + strings = listOf("force_enable_sticky_browsy_bars"), +) + internal val videoStateFingerprint = legacyFingerprint( name = "videoStateFingerprint", returnType = "V", diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/PlayerTypeHookPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/PlayerTypeHookPatch.kt index 9fe31de23..4fef422ff 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/PlayerTypeHookPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/playertype/PlayerTypeHookPatch.kt @@ -22,7 +22,6 @@ import app.revanced.util.indexOfFirstInstructionOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import app.revanced.util.indexOfFirstStringInstructionOrThrow import com.android.tools.smali.dexlib2.Opcode -import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.OneRegisterInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.reference.FieldReference @@ -136,18 +135,33 @@ val playerTypeHookPatch = bytecodePatch( // region patch for hook search bar - //two different layouts are used at the hooked code. - //insert before the firstviewGroup method call after inflating, - // so this works regardless which layout is used. - actionBarSearchResultsFingerprint.methodOrThrow().apply { - val instructionIndex = indexOfLayoutDirectionInstruction(this) - val viewRegister = getInstruction(instructionIndex).registerC + searchQueryClassFingerprint.matchOrThrow().let { + it.method.apply { + val searchQueryIndex = it.patternMatch!!.startIndex + 1 + val searchQueryFieldReference = getInstruction(searchQueryIndex).reference + val searchQueryClass = (searchQueryFieldReference as FieldReference).definingClass - addInstruction( - instructionIndex, - "invoke-static { v$viewRegister }, " + - "$EXTENSION_ROOT_VIEW_HOOK_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V", - ) + findMethodOrThrow(searchQueryClass).apply { + val smaliInstructions = + """ + if-eqz v0, :ignore + iget-object v0, v0, $searchQueryFieldReference + if-eqz v0, :ignore + return-object v0 + :ignore + const-string v0, "" + return-object v0 + """ + + addStaticFieldToExtension( + EXTENSION_ROOT_VIEW_HOOK_CLASS_DESCRIPTOR, + "getSearchQuery", + "searchQueryClass", + definingClass, + smaliInstructions + ) + } + } } // endregion diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt index ae8fa384b..b813e6a84 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/utils/resourceid/SharedResourceIdPatch.kt @@ -20,8 +20,6 @@ var actionBarRingo = -1L private set var actionBarRingoBackground = -1L private set -var actionBarSearchResultsViewMic = -1L - private set var adAttribution = -1L private set var appearance = -1L @@ -246,10 +244,6 @@ internal val sharedResourceIdPatch = resourcePatch( LAYOUT, "action_bar_ringo_background" ] - actionBarSearchResultsViewMic = resourceMappings[ - LAYOUT, - "action_bar_search_results_view_mic" - ] adAttribution = resourceMappings[ ID, "ad_attribution"