refactor(hide-floating-microphone): use more dynamic fingerprint

This commit is contained in:
inotia00 2023-02-23 16:54:40 +09:00
parent 95d6824e84
commit 4e9eff5de2
3 changed files with 55 additions and 63 deletions

View File

@ -0,0 +1,20 @@
package app.revanced.patches.youtube.layout.general.floatingmicrophone.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.WideLiteralInstruction
object FloatingMicrophoneFingerprint : MethodFingerprint(
opcodes = listOf(
Opcode.IGET_BOOLEAN,
Opcode.IF_EQZ,
Opcode.RETURN_VOID
),
customFingerprint = { methodDef ->
methodDef.implementation?.instructions?.any {
it.opcode.ordinal == Opcode.CONST.ordinal &&
(it as? WideLiteralInstruction)?.wideLiteral == SharedResourcdIdPatch.fabLabelId
} == true
}
)

View File

@ -1,98 +1,68 @@
package app.revanced.patches.youtube.layout.general.floatingmicrophone.patch
import app.revanced.extensions.findMutableMethodOf
import app.revanced.extensions.toErrorResult
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.addInstructions
import app.revanced.patcher.extensions.instruction
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultError
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.patch.annotations.DependsOn
import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patches.shared.annotation.YouTubeCompatibility
import app.revanced.patches.shared.patch.mapping.ResourceMappingPatch
import app.revanced.patches.youtube.layout.general.floatingmicrophone.fingerprints.FloatingMicrophoneFingerprint
import app.revanced.patches.youtube.misc.resourceid.patch.SharedResourcdIdPatch
import app.revanced.patches.youtube.misc.settings.resource.patch.SettingsPatch
import app.revanced.util.integrations.Constants.GENERAL_LAYOUT
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.iface.instruction.TwoRegisterInstruction
import org.jf.dexlib2.iface.instruction.formats.Instruction31i
@Patch
@Name("hide-floating-microphone")
@Description("Hide the floating microphone button above the keyboard.")
@DependsOn(
[
ResourceMappingPatch::class,
SettingsPatch::class
SettingsPatch::class,
SharedResourcdIdPatch::class
]
)
@YouTubeCompatibility
@Version("0.0.1")
class FloatingMicrophonePatch : BytecodePatch() {
// list of resource names to get the id of
private val resourceIds = arrayOf(
"fab"
).map { name ->
ResourceMappingPatch.resourceMappings.single { it.name == name }.id
}
private var patchSuccessArray = Array(resourceIds.size) {false}
class FloatingMicrophonePatch : BytecodePatch(
listOf(
FloatingMicrophoneFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
context.classes.forEach { classDef ->
classDef.methods.forEach { method ->
with(method.implementation) {
this?.instructions?.forEachIndexed { index, instruction ->
when (instruction.opcode) {
Opcode.CONST -> {
when ((instruction as Instruction31i).wideLiteral) {
resourceIds[0] -> { // FloatingActionButton
val insertIndex = index + 4
val invokeInstruction = instructions.elementAt(insertIndex)
if (invokeInstruction.opcode != Opcode.IGET_BOOLEAN) return@forEachIndexed
val mutableMethod = context.proxy(classDef).mutableClass.findMutableMethodOf(method)
FloatingMicrophoneFingerprint.result?.let {
with (it.mutableMethod) {
val insertIndex = it.scanResult.patternScanResult!!.startIndex
val register = (instruction(insertIndex) as TwoRegisterInstruction).registerA
val viewRegister = (invokeInstruction as TwoRegisterInstruction).registerA
mutableMethod.addInstructions(
insertIndex + 1, """
invoke-static {v$viewRegister}, $GENERAL_LAYOUT->hideFloatingMicrophone(Z)Z
move-result v$viewRegister
"""
)
patchSuccessArray[0] = true;
}
}
}
else -> return@forEachIndexed
}
}
}
}
}
val errorIndex: Int = patchSuccessArray.indexOf(false)
if (errorIndex == -1) {
/*
* Add settings
*/
SettingsPatch.addPreference(
arrayOf(
"PREFERENCE: GENERAL_LAYOUT_SETTINGS",
"SETTINGS: HIDE_FLOATING_MICROPHONE"
addInstructions(
insertIndex + 1, """
invoke-static {v$register}, $GENERAL_LAYOUT->hideFloatingMicrophone(Z)Z
move-result v$register
"""
)
}
} ?: return FloatingMicrophoneFingerprint.toErrorResult()
/*
* Add settings
*/
SettingsPatch.addPreference(
arrayOf(
"PREFERENCE: GENERAL_LAYOUT_SETTINGS",
"SETTINGS: HIDE_FLOATING_MICROPHONE"
)
)
SettingsPatch.updatePatchStatus("hide-floating-microphone")
SettingsPatch.updatePatchStatus("hide-floating-microphone")
return PatchResultSuccess()
} else
return PatchResultError("Instruction not found: $errorIndex")
return PatchResultSuccess()
}
}

View File

@ -27,6 +27,7 @@ class SharedResourcdIdPatch : ResourcePatch {
var donationCompanionResourceId: Long = -1
var educationTextViewResourceId: Long = -1
var emptycolorLabelId: Long = -1
var fabLabelId: Long = -1
var floatybarQueueLabelId: Long = -1
var imageOnlyTabId: Long = -1
var imageWithTextTabId: Long = -1
@ -57,6 +58,7 @@ class SharedResourcdIdPatch : ResourcePatch {
donationCompanionResourceId = findSharedResourceId("layout", "donation_companion")
educationTextViewResourceId = findSharedResourceId("id", "user_education_text_view")
emptycolorLabelId = findSharedResourceId("color", "inline_time_bar_colorized_bar_empty_color_dark")
fabLabelId = findSharedResourceId("id", "fab")
floatybarQueueLabelId = findSharedResourceId("string", "floaty_bar_queue_status")
imageOnlyTabId = findSharedResourceId("layout", "image_only_tab")
imageWithTextTabId = findSharedResourceId("layout", "image_with_text_tab")