refactor(YouTube - PlayerTypeHook): Use search query instead of View to determine whether a user is in search results or not

This commit is contained in:
inotia00 2024-12-08 11:50:12 +09:00
parent 19bce281ef
commit e0bdce0c19
4 changed files with 50 additions and 43 deletions

View File

@ -2,20 +2,8 @@ package app.revanced.extension.youtube.shared;
import static app.revanced.extension.youtube.patches.components.RelatedVideoFilter.isActionBarVisible; import static app.revanced.extension.youtube.patches.components.RelatedVideoFilter.isActionBarVisible;
import android.view.View;
import java.lang.ref.WeakReference;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public final class RootView { public final class RootView {
private static volatile WeakReference<View> 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 * @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()}. * Detecting the search is covered by the player can be done by checking {@link RootView#isPlayerActive()}.
*/ */
public static boolean isSearchBarActive() { public static boolean isSearchBarActive() {
View searchbarResults = searchBarResultsRef.get(); String searchQuery = getSearchQuery();
return searchbarResults != null && searchbarResults.getParent() != null; return !searchQuery.isEmpty();
} }
public static boolean isPlayerActive() { public static boolean isPlayerActive() {
@ -38,4 +26,12 @@ public final class RootView {
public static String getBrowseId() { public static String getBrowseId() {
return ""; return "";
} }
/**
* Get current SearchQuery.
* Rest of the implementation added by patch.
*/
public static String getSearchQuery() {
return "";
}
} }

View File

@ -1,6 +1,5 @@
package app.revanced.patches.youtube.utils.playertype 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.patches.youtube.utils.resourceid.reelWatchPlayer
import app.revanced.util.fingerprint.legacyFingerprint import app.revanced.util.fingerprint.legacyFingerprint
import app.revanced.util.getReference 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.Method
import com.android.tools.smali.dexlib2.iface.reference.MethodReference 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) = internal fun indexOfLayoutDirectionInstruction(method: Method) =
method.indexOfFirstInstruction { method.indexOfFirstInstruction {
opcode == Opcode.INVOKE_VIRTUAL && opcode == Opcode.INVOKE_VIRTUAL &&
@ -56,6 +45,20 @@ internal val reelWatchPagerFingerprint = legacyFingerprint(
literals = listOf(reelWatchPlayer), 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( internal val videoStateFingerprint = legacyFingerprint(
name = "videoStateFingerprint", name = "videoStateFingerprint",
returnType = "V", returnType = "V",

View File

@ -22,7 +22,6 @@ import app.revanced.util.indexOfFirstInstructionOrThrow
import app.revanced.util.indexOfFirstLiteralInstructionOrThrow import app.revanced.util.indexOfFirstLiteralInstructionOrThrow
import app.revanced.util.indexOfFirstStringInstructionOrThrow import app.revanced.util.indexOfFirstStringInstructionOrThrow
import com.android.tools.smali.dexlib2.Opcode 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.OneRegisterInstruction
import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction
import com.android.tools.smali.dexlib2.iface.reference.FieldReference import com.android.tools.smali.dexlib2.iface.reference.FieldReference
@ -136,18 +135,33 @@ val playerTypeHookPatch = bytecodePatch(
// region patch for hook search bar // region patch for hook search bar
//two different layouts are used at the hooked code. searchQueryClassFingerprint.matchOrThrow().let {
//insert before the firstviewGroup method call after inflating, it.method.apply {
// so this works regardless which layout is used. val searchQueryIndex = it.patternMatch!!.startIndex + 1
actionBarSearchResultsFingerprint.methodOrThrow().apply { val searchQueryFieldReference = getInstruction<ReferenceInstruction>(searchQueryIndex).reference
val instructionIndex = indexOfLayoutDirectionInstruction(this) val searchQueryClass = (searchQueryFieldReference as FieldReference).definingClass
val viewRegister = getInstruction<FiveRegisterInstruction>(instructionIndex).registerC
addInstruction( findMethodOrThrow(searchQueryClass).apply {
instructionIndex, val smaliInstructions =
"invoke-static { v$viewRegister }, " + """
"$EXTENSION_ROOT_VIEW_HOOK_CLASS_DESCRIPTOR->searchBarResultsViewLoaded(Landroid/view/View;)V", 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 // endregion

View File

@ -20,8 +20,6 @@ var actionBarRingo = -1L
private set private set
var actionBarRingoBackground = -1L var actionBarRingoBackground = -1L
private set private set
var actionBarSearchResultsViewMic = -1L
private set
var adAttribution = -1L var adAttribution = -1L
private set private set
var appearance = -1L var appearance = -1L
@ -246,10 +244,6 @@ internal val sharedResourceIdPatch = resourcePatch(
LAYOUT, LAYOUT,
"action_bar_ringo_background" "action_bar_ringo_background"
] ]
actionBarSearchResultsViewMic = resourceMappings[
LAYOUT,
"action_bar_search_results_view_mic"
]
adAttribution = resourceMappings[ adAttribution = resourceMappings[
ID, ID,
"ad_attribution" "ad_attribution"