add sleep-timer-hook patch (included in share-button-hook patch)

This commit is contained in:
inotia00 2023-04-28 11:32:16 +09:00
parent 1bd4de1e7d
commit 22498750e7
7 changed files with 161 additions and 1 deletions

View File

@ -15,6 +15,7 @@ import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility
import app.revanced.patches.shared.patch.options.PatchOptions
import app.revanced.util.microg.MicroGManifestHelper.addSpoofingMetadata
import app.revanced.util.microg.MicroGResourceHelper.patchManifest
import app.revanced.util.resources.MusicResourceHelper.setMicroG
@Name("music-microg-resource-patch")
@Description("Resource patch to allow YouTube Music ReVanced to run without root and under a different package name.")
@ -40,6 +41,9 @@ class MusicMicroGResourcePatch : ResourcePatch {
SPOOFED_PACKAGE_NAME,
SPOOFED_PACKAGE_SIGNATURE
)
context.setMicroG(packageNameMusic)
return PatchResultSuccess()
}
}

View File

@ -16,6 +16,7 @@ import app.revanced.patcher.patch.annotations.Patch
import app.revanced.patcher.util.smali.ExternalLabel
import app.revanced.patches.music.misc.settings.resource.patch.MusicSettingsPatch
import app.revanced.patches.music.misc.sharebuttonhook.fingerprints.*
import app.revanced.patches.music.misc.sleeptimerhook.patch.SleepTimerHookPatch
import app.revanced.patches.music.misc.videoid.patch.MusicVideoIdPatch
import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility
import app.revanced.util.enum.CategoryType
@ -28,7 +29,8 @@ import app.revanced.util.integrations.Constants.MUSIC_MISC_PATH
@DependsOn(
[
MusicSettingsPatch::class,
MusicVideoIdPatch::class
MusicVideoIdPatch::class,
SleepTimerHookPatch::class
]
)
@YouTubeMusicCompatibility

View File

@ -0,0 +1,13 @@
package app.revanced.patches.music.misc.sleeptimerhook.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.Opcode
object MusicPlaybackControlsClickFingerprint : MethodFingerprint(
returnType = "V",
opcodes = listOf(
Opcode.INVOKE_VIRTUAL,
Opcode.RETURN_VOID
),
customFingerprint = { it.definingClass.endsWith("/MusicPlaybackControls;") && it.name == "onClick" }
)

View File

@ -0,0 +1,13 @@
package app.revanced.patches.music.misc.sleeptimerhook.fingerprints
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
object MusicPlaybackControlsTimeFingerprint : MethodFingerprint(
returnType = "V",
access = AccessFlags.PUBLIC or AccessFlags.FINAL or AccessFlags.SYNTHETIC,
parameters = listOf("J","J","J","J"),
opcodes = listOf(Opcode.RETURN_VOID),
)

View File

@ -0,0 +1,9 @@
package app.revanced.patches.music.misc.sleeptimerhook.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SleepTimerFinalFingerprint : MethodFingerprint(
returnType = "V",
parameters = listOf("L"),
strings = listOf("SLEEP_TIMER_MENU_BOTTOM_SHEET_FRAGMENT")
)

View File

@ -0,0 +1,9 @@
package app.revanced.patches.music.misc.sleeptimerhook.fingerprints
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint
object SleepTimerStaticFingerprint : MethodFingerprint(
returnType = "L",
parameters = listOf("L"),
strings = listOf("SLEEP_TIMER_MENU_BOTTOM_SHEET_FRAGMENT")
)

View File

@ -0,0 +1,110 @@
package app.revanced.patches.music.misc.sleeptimerhook.patch
import app.revanced.extensions.toErrorResult
import app.revanced.patcher.annotation.Name
import app.revanced.patcher.annotation.Version
import app.revanced.patcher.data.BytecodeContext
import app.revanced.patcher.extensions.addInstruction
import app.revanced.patcher.extensions.or
import app.revanced.patcher.fingerprint.method.impl.MethodFingerprint.Companion.resolve
import app.revanced.patcher.patch.BytecodePatch
import app.revanced.patcher.patch.PatchResult
import app.revanced.patcher.patch.PatchResultSuccess
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod.Companion.toMutable
import app.revanced.patcher.util.smali.toInstructions
import app.revanced.patches.music.misc.sleeptimerhook.fingerprints.*
import app.revanced.patches.shared.annotation.YouTubeMusicCompatibility
import app.revanced.util.integrations.Constants.MUSIC_MISC_PATH
import org.jf.dexlib2.AccessFlags
import org.jf.dexlib2.Opcode
import org.jf.dexlib2.dexbacked.reference.DexBackedFieldReference
import org.jf.dexlib2.iface.instruction.ReferenceInstruction
import org.jf.dexlib2.immutable.ImmutableMethod
import org.jf.dexlib2.immutable.ImmutableMethodImplementation
@Name("sleep-timer-hook")
@YouTubeMusicCompatibility
@Version("0.0.1")
class SleepTimerHookPatch : BytecodePatch(
listOf(
MusicPlaybackControlsClickFingerprint,
SleepTimerFinalFingerprint,
SleepTimerStaticFingerprint
)
) {
override fun execute(context: BytecodeContext): PatchResult {
val sleepTimerStaticMethod = SleepTimerStaticFingerprint.result?.mutableMethod
?: return SleepTimerStaticFingerprint.toErrorResult()
val sleepTimerStaticMethodToCall = sleepTimerStaticMethod.definingClass +
"->" +
sleepTimerStaticMethod.name +
"(${sleepTimerStaticMethod.parameters[0]})" +
sleepTimerStaticMethod.returnType
val sleepTimerFinalMethod = SleepTimerFinalFingerprint.result?.mutableMethod
?: return SleepTimerFinalFingerprint.toErrorResult()
val sleepTimerFinalMethodToCall = sleepTimerFinalMethod.definingClass +
"->" +
sleepTimerFinalMethod.name +
"(${sleepTimerFinalMethod.parameters[0]})" +
sleepTimerFinalMethod.returnType
MusicPlaybackControlsClickFingerprint.result?.let { parentResult ->
with (parentResult.mutableMethod.implementation!!.instructions) {
for (i in this.size - 1 downTo 0) {
if (this[i].opcode != Opcode.IGET_OBJECT) continue
val invokeInstruction = this[i] as? ReferenceInstruction ?: continue
val targetReference = (invokeInstruction.reference as DexBackedFieldReference).toString()
if (!targetReference.contains(parentResult.classDef.type)) continue
musicPlaybackControlsMethodToCall = targetReference
break
}
if (musicPlaybackControlsMethodToCall == null)
return MusicPlaybackControlsClickFingerprint.toErrorResult()
}
MusicPlaybackControlsTimeFingerprint.also { it.resolve(context, parentResult.classDef) }.result?.mutableMethod?.addInstruction(
1,
"invoke-virtual {p0}, ${parentResult.classDef.type}->openSleepTimer()V"
) ?: return MusicPlaybackControlsTimeFingerprint.toErrorResult()
parentResult.mutableClass.methods.add(
ImmutableMethod(
parentResult.classDef.type,
"openSleepTimer",
listOf(),
"V",
AccessFlags.PUBLIC or AccessFlags.FINAL,
null,
null,
ImmutableMethodImplementation(
4, """
sget-boolean v0, $INTEGRATIONS_CLASS_DESCRIPTOR
if-eqz v0, :dismiss
iget-object v1, v3, $musicPlaybackControlsMethodToCall
invoke-static {v1}, $sleepTimerStaticMethodToCall
move-result-object v0
iget-object v1, v3, $musicPlaybackControlsMethodToCall
invoke-virtual {v0, v1}, $sleepTimerFinalMethodToCall
const/4 v0, 0x0
sput-boolean v0, $INTEGRATIONS_CLASS_DESCRIPTOR
:dismiss
return-void
""".toInstructions(), null, null
)
).toMutable()
)
} ?: return MusicPlaybackControlsClickFingerprint.toErrorResult()
return PatchResultSuccess()
}
private companion object {
const val INTEGRATIONS_CLASS_DESCRIPTOR = "$MUSIC_MISC_PATH/HookShareButtonPatch;->isShareButtonClicked:Z"
var musicPlaybackControlsMethodToCall: String? = null
}
}