mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-09 19:14:37 +02:00
fix(YouTube Music/Enable next previous button): no longer use Instrumentation.SendKeySync(KeyEvent)
This commit is contained in:
parent
8f1b86191b
commit
80ba57f9ff
@ -1,16 +1,23 @@
|
|||||||
package app.revanced.patches.music.player.nextprevious
|
package app.revanced.patches.music.player.nextprevious
|
||||||
|
|
||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
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.CompatiblePackage
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableField.Companion.toMutable
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patches.music.utils.fingerprints.MiniPlayerConstructorFingerprint
|
|
||||||
import app.revanced.patches.music.player.nextprevious.fingerprints.MiniPlayerParentFingerprint
|
import app.revanced.patches.music.player.nextprevious.fingerprints.MiniPlayerParentFingerprint
|
||||||
import app.revanced.patches.music.player.nextprevious.fingerprints.MppWatchWhileLayoutFingerprint
|
import app.revanced.patches.music.player.nextprevious.fingerprints.MppWatchWhileLayoutFingerprint
|
||||||
import app.revanced.patches.music.player.nextprevious.fingerprints.NextButtonVisibilityFingerprint
|
import app.revanced.patches.music.player.nextprevious.fingerprints.NextButtonVisibilityFingerprint
|
||||||
|
import app.revanced.patches.music.player.nextprevious.fingerprints.PlayerPatchConstructorFingerprint
|
||||||
|
import app.revanced.patches.music.utils.fingerprints.MiniPlayerConstructorFingerprint
|
||||||
|
import app.revanced.patches.music.utils.fingerprints.PendingIntentReceiverFingerprint
|
||||||
import app.revanced.patches.music.utils.integrations.Constants.PLAYER
|
import app.revanced.patches.music.utils.integrations.Constants.PLAYER
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch
|
||||||
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
|
import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.MiniPlayerPlayPauseReplayButton
|
||||||
@ -19,11 +26,17 @@ import app.revanced.patches.music.utils.resourceid.SharedResourceIdPatch.TopStar
|
|||||||
import app.revanced.patches.music.utils.settings.CategoryType
|
import app.revanced.patches.music.utils.settings.CategoryType
|
||||||
import app.revanced.patches.music.utils.settings.SettingsPatch
|
import app.revanced.patches.music.utils.settings.SettingsPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
|
import app.revanced.util.getStringInstructionIndex
|
||||||
import app.revanced.util.getTargetIndex
|
import app.revanced.util.getTargetIndex
|
||||||
|
import app.revanced.util.getTargetIndexReversed
|
||||||
import app.revanced.util.getWideLiteralInstructionIndex
|
import app.revanced.util.getWideLiteralInstructionIndex
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
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.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.reference.MethodReference
|
||||||
|
import com.android.tools.smali.dexlib2.immutable.ImmutableField
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Enable next previous button",
|
name = "Enable next previous button",
|
||||||
@ -56,17 +69,31 @@ object MiniPlayerButtonPatch : BytecodePatch(
|
|||||||
setOf(
|
setOf(
|
||||||
MiniPlayerConstructorFingerprint,
|
MiniPlayerConstructorFingerprint,
|
||||||
MiniPlayerParentFingerprint,
|
MiniPlayerParentFingerprint,
|
||||||
MppWatchWhileLayoutFingerprint
|
MppWatchWhileLayoutFingerprint,
|
||||||
|
PendingIntentReceiverFingerprint,
|
||||||
|
PlayerPatchConstructorFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
private const val NEXT_BUTTON_FIELD_NAME =
|
private const val NEXT_BUTTON_FIELD_NAME =
|
||||||
"nextButton"
|
"nextButton"
|
||||||
private const val PREVIOUS_BUTTON_FIELD_NAME =
|
private const val PREVIOUS_BUTTON_FIELD_NAME =
|
||||||
"previousButton"
|
"previousButton"
|
||||||
|
private const val NEXT_BUTTON_CLASS_FIELD_NAME =
|
||||||
|
"nextButtonClass"
|
||||||
|
private const val PREVIOUS_BUTTON_CLASS_FIELD_NAME =
|
||||||
|
"previousButtonClass"
|
||||||
private const val NEXT_BUTTON_METHOD_NAME =
|
private const val NEXT_BUTTON_METHOD_NAME =
|
||||||
"setNextButtonOnClickListener"
|
"setNextButton"
|
||||||
private const val PREVIOUS_BUTTON_METHOD_NAME =
|
private const val PREVIOUS_BUTTON_METHOD_NAME =
|
||||||
|
"setPreviousButton"
|
||||||
|
private const val NEXT_BUTTON_ONCLICK_METHOD_NAME =
|
||||||
|
"setNextButtonOnClickListener"
|
||||||
|
private const val PREVIOUS_BUTTON_ONCLICK_METHOD_NAME =
|
||||||
"setPreviousButtonOnClickListener"
|
"setPreviousButtonOnClickListener"
|
||||||
|
private const val NEXT_BUTTON_INTENT_STRING =
|
||||||
|
"YTM Next"
|
||||||
|
private const val PREVIOUS_BUTTON_INTENT_STRING =
|
||||||
|
"YTM Previous"
|
||||||
|
|
||||||
private var arrayCount = 1
|
private var arrayCount = 1
|
||||||
|
|
||||||
@ -80,6 +107,10 @@ object MiniPlayerButtonPatch : BytecodePatch(
|
|||||||
MppWatchWhileLayoutFingerprint.result?.mutableMethod
|
MppWatchWhileLayoutFingerprint.result?.mutableMethod
|
||||||
?: throw MppWatchWhileLayoutFingerprint.exception
|
?: throw MppWatchWhileLayoutFingerprint.exception
|
||||||
|
|
||||||
|
val pendingIntentReceiverMutableMethod =
|
||||||
|
PendingIntentReceiverFingerprint.result?.mutableMethod
|
||||||
|
?: throw PendingIntentReceiverFingerprint.exception
|
||||||
|
|
||||||
if (!SettingsPatch.upward0642) {
|
if (!SettingsPatch.upward0642) {
|
||||||
MiniPlayerParentFingerprint.result?.let { parentResult ->
|
MiniPlayerParentFingerprint.result?.let { parentResult ->
|
||||||
// Resolves fingerprints
|
// Resolves fingerprints
|
||||||
@ -103,10 +134,12 @@ object MiniPlayerButtonPatch : BytecodePatch(
|
|||||||
} else {
|
} else {
|
||||||
miniPlayerConstructorMutableMethod.setInstanceFieldValue(NEXT_BUTTON_METHOD_NAME, TopStart)
|
miniPlayerConstructorMutableMethod.setInstanceFieldValue(NEXT_BUTTON_METHOD_NAME, TopStart)
|
||||||
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(NEXT_BUTTON_FIELD_NAME, TopStart)
|
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(NEXT_BUTTON_FIELD_NAME, TopStart)
|
||||||
|
pendingIntentReceiverMutableMethod.setOnClickListener(context, NEXT_BUTTON_INTENT_STRING, NEXT_BUTTON_ONCLICK_METHOD_NAME, NEXT_BUTTON_CLASS_FIELD_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
miniPlayerConstructorMutableMethod.setInstanceFieldValue(PREVIOUS_BUTTON_METHOD_NAME, TopEnd)
|
miniPlayerConstructorMutableMethod.setInstanceFieldValue(PREVIOUS_BUTTON_METHOD_NAME, TopEnd)
|
||||||
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(PREVIOUS_BUTTON_FIELD_NAME, TopEnd)
|
mppWatchWhileLayoutMutableMethod.setStaticFieldValue(PREVIOUS_BUTTON_FIELD_NAME, TopEnd)
|
||||||
|
pendingIntentReceiverMutableMethod.setOnClickListener(context, PREVIOUS_BUTTON_INTENT_STRING, PREVIOUS_BUTTON_ONCLICK_METHOD_NAME, PREVIOUS_BUTTON_CLASS_FIELD_NAME)
|
||||||
|
|
||||||
mppWatchWhileLayoutMutableMethod.setViewArray()
|
mppWatchWhileLayoutMutableMethod.setViewArray()
|
||||||
|
|
||||||
@ -123,19 +156,6 @@ object MiniPlayerButtonPatch : BytecodePatch(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableMethod.setViewArray() {
|
|
||||||
val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
|
||||||
val invokeStaticIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_STATIC)
|
|
||||||
val viewArrayRegister = getInstruction<FiveRegisterInstruction>(invokeStaticIndex).registerC
|
|
||||||
|
|
||||||
addInstructions(
|
|
||||||
invokeStaticIndex, """
|
|
||||||
invoke-static {v$viewArrayRegister}, $PLAYER->getViewArray([Landroid/view/View;)[Landroid/view/View;
|
|
||||||
move-result-object v$viewArrayRegister
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableMethod.setInstanceFieldValue(
|
private fun MutableMethod.setInstanceFieldValue(
|
||||||
methodName: String,
|
methodName: String,
|
||||||
viewId: Long
|
viewId: Long
|
||||||
@ -173,4 +193,67 @@ object MiniPlayerButtonPatch : BytecodePatch(
|
|||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun MutableMethod.setViewArray() {
|
||||||
|
val miniPlayerPlayPauseReplayButtonIndex = getWideLiteralInstructionIndex(MiniPlayerPlayPauseReplayButton)
|
||||||
|
val invokeStaticIndex = getTargetIndex(miniPlayerPlayPauseReplayButtonIndex, Opcode.INVOKE_STATIC)
|
||||||
|
val viewArrayRegister = getInstruction<FiveRegisterInstruction>(invokeStaticIndex).registerC
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
invokeStaticIndex, """
|
||||||
|
invoke-static {v$viewArrayRegister}, $PLAYER->getViewArray([Landroid/view/View;)[Landroid/view/View;
|
||||||
|
move-result-object v$viewArrayRegister
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MutableMethod.setOnClickListener(
|
||||||
|
context: BytecodeContext,
|
||||||
|
intentString: String,
|
||||||
|
methodName: String,
|
||||||
|
fieldName: String
|
||||||
|
) {
|
||||||
|
val startIndex = getStringInstructionIndex(intentString)
|
||||||
|
val onClickIndex = getTargetIndexReversed(startIndex, Opcode.INVOKE_VIRTUAL)
|
||||||
|
val onClickReference = getInstruction<ReferenceInstruction>(onClickIndex).reference
|
||||||
|
val onClickReferenceDefiningClass = (onClickReference as MethodReference).definingClass
|
||||||
|
|
||||||
|
val onClickClass =
|
||||||
|
context.findClass(onClickReferenceDefiningClass)!!.mutableClass
|
||||||
|
|
||||||
|
onClickClass.methods.find { method -> method.name == "<init>" }
|
||||||
|
?.apply {
|
||||||
|
addInstruction(
|
||||||
|
implementation!!.instructions.size - 1,
|
||||||
|
"sput-object p0, $PLAYER->$fieldName:$onClickReferenceDefiningClass"
|
||||||
|
)
|
||||||
|
} ?: throw PatchException("onClickClass not found!")
|
||||||
|
|
||||||
|
PlayerPatchConstructorFingerprint.result?.let {
|
||||||
|
val mutableClass = it.mutableClass
|
||||||
|
mutableClass.methods.find { method -> method.name == methodName }
|
||||||
|
?.apply {
|
||||||
|
mutableClass.staticFields.add(
|
||||||
|
ImmutableField(
|
||||||
|
definingClass,
|
||||||
|
fieldName,
|
||||||
|
onClickReferenceDefiningClass,
|
||||||
|
AccessFlags.PUBLIC or AccessFlags.STATIC,
|
||||||
|
null,
|
||||||
|
annotations,
|
||||||
|
null
|
||||||
|
).toMutable()
|
||||||
|
)
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
0, """
|
||||||
|
sget-object v0, $PLAYER->$fieldName:$onClickReferenceDefiningClass
|
||||||
|
if-eqz v0, :ignore
|
||||||
|
invoke-virtual {v0}, $onClickReference
|
||||||
|
:ignore
|
||||||
|
return-void
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} ?: throw PlayerPatchConstructorFingerprint.exception
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package app.revanced.patches.music.player.nextprevious.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import app.revanced.patches.music.utils.integrations.Constants.PLAYER
|
||||||
|
|
||||||
|
object PlayerPatchConstructorFingerprint : MethodFingerprint(
|
||||||
|
returnType = "V",
|
||||||
|
customFingerprint = { methodDef, _ ->
|
||||||
|
methodDef.definingClass == PLAYER
|
||||||
|
&& methodDef.name == "<init>"
|
||||||
|
}
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user