mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-05-06 01:24:35 +02:00
feat(YouTube/Enable tablet mini player): add Enable modern mini player
settings
This commit is contained in:
parent
9aecec0df8
commit
f66ac24f55
@ -3,24 +3,35 @@ package app.revanced.patches.youtube.general.tabletminiplayer
|
|||||||
import app.revanced.patcher.data.BytecodeContext
|
import app.revanced.patcher.data.BytecodeContext
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
|
||||||
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
import app.revanced.patcher.util.proxy.mutableTypes.MutableMethod
|
||||||
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorFingerprint
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerDimensionsCalculatorFingerprint
|
||||||
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideFingerprint
|
||||||
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerOverrideNoContextFingerprint
|
||||||
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.MiniPlayerResponseModelSizeCheckFingerprint
|
||||||
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.ModernMiniPlayerConfigFingerprint
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.ModernMiniPlayerConfigFingerprint
|
||||||
|
import app.revanced.patches.youtube.general.tabletminiplayer.fingerprints.ModernMiniPlayerConstructorFingerprint
|
||||||
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
|
import app.revanced.patches.youtube.utils.integrations.Constants.COMPATIBLE_PACKAGE
|
||||||
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
import app.revanced.patches.youtube.utils.integrations.Constants.GENERAL_CLASS_DESCRIPTOR
|
||||||
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch
|
||||||
|
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YtOutlinePiPWhite
|
||||||
|
import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YtOutlineXWhite
|
||||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||||
|
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||||
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.getStringInstructionIndex
|
import app.revanced.util.getStringInstructionIndex
|
||||||
import app.revanced.util.getTargetIndex
|
import app.revanced.util.getTargetIndex
|
||||||
import app.revanced.util.getTargetIndexReversed
|
import app.revanced.util.getTargetIndexReversed
|
||||||
import app.revanced.util.getWalkerMethod
|
import app.revanced.util.getWalkerMethod
|
||||||
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
import app.revanced.util.literalInstructionHook
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
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.TwoRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object TabletMiniPlayerPatch : BaseBytecodePatch(
|
object TabletMiniPlayerPatch : BaseBytecodePatch(
|
||||||
@ -35,7 +46,8 @@ object TabletMiniPlayerPatch : BaseBytecodePatch(
|
|||||||
MiniPlayerDimensionsCalculatorFingerprint,
|
MiniPlayerDimensionsCalculatorFingerprint,
|
||||||
MiniPlayerResponseModelSizeCheckFingerprint,
|
MiniPlayerResponseModelSizeCheckFingerprint,
|
||||||
MiniPlayerOverrideFingerprint,
|
MiniPlayerOverrideFingerprint,
|
||||||
ModernMiniPlayerConfigFingerprint
|
ModernMiniPlayerConfigFingerprint,
|
||||||
|
ModernMiniPlayerConstructorFingerprint
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
@ -57,6 +69,35 @@ object TabletMiniPlayerPatch : BaseBytecodePatch(
|
|||||||
hook(it.scanResult.patternScanResult!!.endIndex)
|
hook(it.scanResult.patternScanResult!!.endIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModernMiniPlayerConstructorFingerprint.resultOrThrow().let {
|
||||||
|
it.mutableClass.methods.forEach { mutableMethod ->
|
||||||
|
mutableMethod.hookModernMiniPlayer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In ModernMiniPlayer, the drawables of the close button and expand button are reversed.
|
||||||
|
// OnClickListener appears to be applied normally, so this appears to be a bug in YouTube.
|
||||||
|
// To solve this, swap the drawables of the close and expand buttons.
|
||||||
|
// This Drawable will be used in multiple Classes, so instead of using LiteralValueFingerprint to patch only specific methods,
|
||||||
|
// Apply the patch to all methods where literals are used.
|
||||||
|
mapOf(
|
||||||
|
YtOutlineXWhite to "replaceCloseButtonDrawableId",
|
||||||
|
YtOutlinePiPWhite to "replaceExpandButtonDrawableId"
|
||||||
|
).forEach { (literal, methodName) ->
|
||||||
|
val smaliInstruction = """
|
||||||
|
invoke-static {v$REGISTER_TEMPLATE_REPLACEMENT}, $GENERAL_CLASS_DESCRIPTOR->$methodName(I)I
|
||||||
|
move-result v$REGISTER_TEMPLATE_REPLACEMENT
|
||||||
|
"""
|
||||||
|
|
||||||
|
context.literalInstructionHook(literal, smaliInstruction)
|
||||||
|
}
|
||||||
|
|
||||||
|
SettingsPatch.addPreference(
|
||||||
|
arrayOf(
|
||||||
|
"SETTINGS: ENABLE_MODERN_MINI_PLAYER"
|
||||||
|
)
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
MiniPlayerOverrideFingerprint.resultOrThrow().let {
|
MiniPlayerOverrideFingerprint.resultOrThrow().let {
|
||||||
it.mutableMethod.apply {
|
it.mutableMethod.apply {
|
||||||
@ -89,14 +130,46 @@ object TabletMiniPlayerPatch : BaseBytecodePatch(
|
|||||||
SettingsPatch.updatePatchStatus(this)
|
SettingsPatch.updatePatchStatus(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MutableMethod.hook(index: Int) {
|
private fun MutableMethod.hook(index: Int) =
|
||||||
|
hook(index, "enableTabletMiniPlayer")
|
||||||
|
|
||||||
|
private fun MutableMethod.hook(
|
||||||
|
index: Int,
|
||||||
|
methodName: String
|
||||||
|
) {
|
||||||
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
val register = getInstruction<OneRegisterInstruction>(index).registerA
|
||||||
|
|
||||||
addInstructions(
|
addInstructions(
|
||||||
index, """
|
index, """
|
||||||
invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->enableTabletMiniPlayer(Z)Z
|
invoke-static {v$register}, $GENERAL_CLASS_DESCRIPTOR->$methodName(Z)Z
|
||||||
move-result v$register
|
move-result v$register
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun MutableMethod.hookModernMiniPlayer() {
|
||||||
|
if (returnType == "Z") {
|
||||||
|
hook(getTargetIndexReversed(Opcode.RETURN), "enableModernMiniPlayer")
|
||||||
|
hook(getTargetIndex(Opcode.RETURN), "enableModernMiniPlayer")
|
||||||
|
}
|
||||||
|
|
||||||
|
val iPutIndex = indexOfFirstInstruction {
|
||||||
|
this.opcode == Opcode.IPUT
|
||||||
|
&& this.getReference<FieldReference>()?.type == "I"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iPutIndex < 0) return
|
||||||
|
|
||||||
|
val targetReference = getInstruction<ReferenceInstruction>(iPutIndex).reference
|
||||||
|
val targetInstruction = getInstruction<TwoRegisterInstruction>(iPutIndex)
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
iPutIndex + 1, """
|
||||||
|
invoke-static {v${targetInstruction.registerA}}, $GENERAL_CLASS_DESCRIPTOR->enableModernMiniPlayer(I)I
|
||||||
|
move-result v${targetInstruction.registerA}
|
||||||
|
iput v${targetInstruction.registerA}, v${targetInstruction.registerB}, $targetReference
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
removeInstruction(iPutIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package app.revanced.patches.youtube.general.tabletminiplayer.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.util.fingerprint.LiteralValueFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal object ModernMiniPlayerConstructorFingerprint : LiteralValueFingerprint(
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.CONSTRUCTOR,
|
||||||
|
literalSupplier = { 45623000 }
|
||||||
|
)
|
@ -38,8 +38,8 @@ import app.revanced.patches.youtube.utils.resourceid.SharedResourceIdPatch.YtWor
|
|||||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
import app.revanced.patches.youtube.utils.settings.SettingsPatch
|
||||||
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
|
import app.revanced.patches.youtube.utils.settings.SettingsPatch.contexts
|
||||||
import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch
|
import app.revanced.patches.youtube.utils.toolbar.ToolBarHookPatch
|
||||||
|
import app.revanced.util.REGISTER_TEMPLATE_REPLACEMENT
|
||||||
import app.revanced.util.doRecursively
|
import app.revanced.util.doRecursively
|
||||||
import app.revanced.util.findMutableMethodOf
|
|
||||||
import app.revanced.util.getTargetIndex
|
import app.revanced.util.getTargetIndex
|
||||||
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
import app.revanced.util.getTargetIndexWithMethodReferenceName
|
||||||
import app.revanced.util.getTargetIndexWithReference
|
import app.revanced.util.getTargetIndexWithReference
|
||||||
@ -47,6 +47,7 @@ import app.revanced.util.getTargetIndexWithReferenceReversed
|
|||||||
import app.revanced.util.getWalkerMethod
|
import app.revanced.util.getWalkerMethod
|
||||||
import app.revanced.util.getWideLiteralInstructionIndex
|
import app.revanced.util.getWideLiteralInstructionIndex
|
||||||
import app.revanced.util.literalInstructionBooleanHook
|
import app.revanced.util.literalInstructionBooleanHook
|
||||||
|
import app.revanced.util.literalInstructionHook
|
||||||
import app.revanced.util.patch.BaseBytecodePatch
|
import app.revanced.util.patch.BaseBytecodePatch
|
||||||
import app.revanced.util.resultOrThrow
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.Opcode
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
@ -54,7 +55,6 @@ 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.instruction.TwoRegisterInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i
|
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
@ -97,7 +97,17 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
|||||||
// region patch for change YouTube header
|
// region patch for change YouTube header
|
||||||
|
|
||||||
// Invoke YouTube's header attribute into integrations.
|
// Invoke YouTube's header attribute into integrations.
|
||||||
replaceHeaderAttributeId(context)
|
val smaliInstruction = """
|
||||||
|
invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->getHeaderAttributeId()I
|
||||||
|
move-result v$REGISTER_TEMPLATE_REPLACEMENT
|
||||||
|
"""
|
||||||
|
|
||||||
|
arrayOf(
|
||||||
|
YtPremiumWordMarkHeader,
|
||||||
|
YtWordMarkHeader
|
||||||
|
).forEach { literal ->
|
||||||
|
context.literalInstructionHook(literal, smaliInstruction)
|
||||||
|
}
|
||||||
|
|
||||||
// YouTube's headers have the form of AttributeSet, which is decoded from YouTube's built-in classes.
|
// YouTube's headers have the form of AttributeSet, which is decoded from YouTube's built-in classes.
|
||||||
val attributeResolverMethod = AttributeResolverFingerprint.resultOrThrow().mutableMethod
|
val attributeResolverMethod = AttributeResolverFingerprint.resultOrThrow().mutableMethod
|
||||||
@ -404,36 +414,6 @@ object ToolBarComponentsPatch : BaseBytecodePatch(
|
|||||||
SettingsPatch.updatePatchStatus(this)
|
SettingsPatch.updatePatchStatus(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun replaceHeaderAttributeId(context: BytecodeContext) {
|
|
||||||
val headerAttributeIdArray = arrayOf(YtPremiumWordMarkHeader, YtWordMarkHeader)
|
|
||||||
|
|
||||||
context.classes.forEach { classDef ->
|
|
||||||
classDef.methods.forEach { method ->
|
|
||||||
method.implementation.apply {
|
|
||||||
this?.instructions?.forEachIndexed { index, instruction ->
|
|
||||||
if (instruction.opcode != Opcode.CONST)
|
|
||||||
return@forEachIndexed
|
|
||||||
if (headerAttributeIdArray.indexOf((instruction as Instruction31i).wideLiteral) < 0)
|
|
||||||
return@forEachIndexed
|
|
||||||
|
|
||||||
(instructions.elementAt(index)).apply {
|
|
||||||
val register = (this as OneRegisterInstruction).registerA
|
|
||||||
context.proxy(classDef)
|
|
||||||
.mutableClass
|
|
||||||
.findMutableMethodOf(method)
|
|
||||||
.addInstructions(
|
|
||||||
index + 1, """
|
|
||||||
invoke-static {}, $GENERAL_CLASS_DESCRIPTOR->getHeaderAttributeId()I
|
|
||||||
move-result v$register
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun MutableMethod.injectSearchBarHook(
|
private fun MutableMethod.injectSearchBarHook(
|
||||||
insertIndex: Int,
|
insertIndex: Int,
|
||||||
descriptor: String
|
descriptor: String
|
||||||
|
@ -91,7 +91,9 @@ object SharedResourceIdPatch : ResourcePatch() {
|
|||||||
var VideoQualityBottomSheet = -1L
|
var VideoQualityBottomSheet = -1L
|
||||||
var VoiceSearch = -1L
|
var VoiceSearch = -1L
|
||||||
var YouTubeControlsOverlaySubtitleButton = -1L
|
var YouTubeControlsOverlaySubtitleButton = -1L
|
||||||
|
var YtOutlinePiPWhite = -1L
|
||||||
var YtOutlineVideoCamera = -1L
|
var YtOutlineVideoCamera = -1L
|
||||||
|
var YtOutlineXWhite = -1L
|
||||||
var YtPremiumWordMarkHeader = -1L
|
var YtPremiumWordMarkHeader = -1L
|
||||||
var YtWordMarkHeader = -1L
|
var YtWordMarkHeader = -1L
|
||||||
|
|
||||||
@ -173,7 +175,9 @@ object SharedResourceIdPatch : ResourcePatch() {
|
|||||||
VideoQualityBottomSheet = getId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title")
|
VideoQualityBottomSheet = getId(LAYOUT, "video_quality_bottom_sheet_list_fragment_title")
|
||||||
VoiceSearch = getId(ID, "voice_search")
|
VoiceSearch = getId(ID, "voice_search")
|
||||||
YouTubeControlsOverlaySubtitleButton = getId(LAYOUT, "youtube_controls_overlay_subtitle_button")
|
YouTubeControlsOverlaySubtitleButton = getId(LAYOUT, "youtube_controls_overlay_subtitle_button")
|
||||||
|
YtOutlinePiPWhite = getId(DRAWABLE, "yt_outline_picture_in_picture_white_24")
|
||||||
YtOutlineVideoCamera = getId(DRAWABLE, "yt_outline_video_camera_black_24")
|
YtOutlineVideoCamera = getId(DRAWABLE, "yt_outline_video_camera_black_24")
|
||||||
|
YtOutlineXWhite = getId(DRAWABLE, "yt_outline_x_white_24")
|
||||||
YtPremiumWordMarkHeader = getId(ATTR, "ytPremiumWordmarkHeader")
|
YtPremiumWordMarkHeader = getId(ATTR, "ytPremiumWordmarkHeader")
|
||||||
YtWordMarkHeader = getId(ATTR, "ytWordmarkHeader")
|
YtWordMarkHeader = getId(ATTR, "ytWordmarkHeader")
|
||||||
|
|
||||||
|
@ -24,12 +24,15 @@ import com.android.tools.smali.dexlib2.iface.instruction.Instruction
|
|||||||
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.instruction.WideLiteralInstruction
|
import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction31i
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
import com.android.tools.smali.dexlib2.iface.reference.FieldReference
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
||||||
import com.android.tools.smali.dexlib2.immutable.ImmutableField
|
import com.android.tools.smali.dexlib2.immutable.ImmutableField
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
|
|
||||||
|
const val REGISTER_TEMPLATE_REPLACEMENT: String = "REGISTER_INDEX"
|
||||||
|
|
||||||
fun MethodFingerprint.resultOrThrow() = result ?: throw exception
|
fun MethodFingerprint.resultOrThrow() = result ?: throw exception
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,7 +139,7 @@ fun MethodFingerprint.literalInstructionBooleanHook(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MethodFingerprint.literalInstructionViewHook(
|
fun MethodFingerprint.literalInstructionHook(
|
||||||
literal: Long,
|
literal: Long,
|
||||||
descriptor: String
|
descriptor: String
|
||||||
) {
|
) {
|
||||||
@ -152,6 +155,37 @@ fun MethodFingerprint.literalInstructionViewHook(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun BytecodeContext.literalInstructionHook(
|
||||||
|
literal: Long,
|
||||||
|
smaliInstruction: String
|
||||||
|
) {
|
||||||
|
val context = this
|
||||||
|
context.classes.forEach { classDef ->
|
||||||
|
classDef.methods.forEach { method ->
|
||||||
|
method.implementation.apply {
|
||||||
|
this?.instructions?.forEachIndexed { _, instruction ->
|
||||||
|
if (instruction.opcode != Opcode.CONST)
|
||||||
|
return@forEachIndexed
|
||||||
|
if ((instruction as Instruction31i).wideLiteral != literal)
|
||||||
|
return@forEachIndexed
|
||||||
|
|
||||||
|
context.proxy(classDef)
|
||||||
|
.mutableClass
|
||||||
|
.findMutableMethodOf(method).apply {
|
||||||
|
val index = getWideLiteralInstructionIndex(literal)
|
||||||
|
val register = (instruction as OneRegisterInstruction).registerA.toString()
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
index + 1,
|
||||||
|
smaliInstruction.replace(REGISTER_TEMPLATE_REPLACEMENT, register)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the index of the first wide literal instruction with the given value.
|
* Find the index of the first wide literal instruction with the given value.
|
||||||
*
|
*
|
||||||
|
@ -277,6 +277,10 @@ Limitations:
|
|||||||
<string name="revanced_enable_tablet_mini_player_title">Enable tablet mini player</string>
|
<string name="revanced_enable_tablet_mini_player_title">Enable tablet mini player</string>
|
||||||
<string name="revanced_enable_tablet_mini_player_summary_on">Tablet mini player is enabled.</string>
|
<string name="revanced_enable_tablet_mini_player_summary_on">Tablet mini player is enabled.</string>
|
||||||
<string name="revanced_enable_tablet_mini_player_summary_off">Tablet mini player is disabled.</string>
|
<string name="revanced_enable_tablet_mini_player_summary_off">Tablet mini player is disabled.</string>
|
||||||
|
<string name="revanced_enable_modern_mini_player_title">Enable modern mini player</string>
|
||||||
|
<string name="revanced_enable_modern_mini_player_summary_on">Modern mini player is enabled.</string>
|
||||||
|
<string name="revanced_enable_modern_mini_player_summary_off">Modern mini player is disabled.</string>
|
||||||
|
|
||||||
<string name="revanced_hide_floating_microphone_title">Hide floating microphone button</string>
|
<string name="revanced_hide_floating_microphone_title">Hide floating microphone button</string>
|
||||||
<string name="revanced_hide_floating_microphone_summary_on">Floating microphone button is hidden.</string>
|
<string name="revanced_hide_floating_microphone_summary_on">Floating microphone button is hidden.</string>
|
||||||
<string name="revanced_hide_floating_microphone_summary_off">Floating microphone button is shown.</string>
|
<string name="revanced_hide_floating_microphone_summary_off">Floating microphone button is shown.</string>
|
||||||
|
@ -171,6 +171,8 @@
|
|||||||
|
|
||||||
<!-- SETTINGS: ENABLE_TABLET_MINI_PLAYER
|
<!-- SETTINGS: ENABLE_TABLET_MINI_PLAYER
|
||||||
<SwitchPreference android:title="@string/revanced_enable_tablet_mini_player_title" android:key="revanced_enable_tablet_mini_player" android:defaultValue="false" android:summaryOn="@string/revanced_enable_tablet_mini_player_summary_on" android:summaryOff="@string/revanced_enable_tablet_mini_player_summary_off" />SETTINGS: ENABLE_TABLET_MINI_PLAYER -->
|
<SwitchPreference android:title="@string/revanced_enable_tablet_mini_player_title" android:key="revanced_enable_tablet_mini_player" android:defaultValue="false" android:summaryOn="@string/revanced_enable_tablet_mini_player_summary_on" android:summaryOff="@string/revanced_enable_tablet_mini_player_summary_off" />SETTINGS: ENABLE_TABLET_MINI_PLAYER -->
|
||||||
|
<!-- SETTINGS: ENABLE_MODERN_MINI_PLAYER
|
||||||
|
<SwitchPreference android:title="@string/revanced_enable_modern_mini_player_title" android:key="revanced_enable_modern_mini_player" android:defaultValue="false" android:summaryOn="@string/revanced_enable_modern_mini_player_summary_on" android:summaryOff="@string/revanced_enable_modern_mini_player_summary_off" />SETTINGS: ENABLE_MODERN_MINI_PLAYER -->
|
||||||
|
|
||||||
<!-- SETTINGS: HIDE_LAYOUT_COMPONENTS
|
<!-- SETTINGS: HIDE_LAYOUT_COMPONENTS
|
||||||
<SwitchPreference android:title="@string/revanced_hide_floating_microphone_title" android:key="revanced_hide_floating_microphone" android:defaultValue="true" android:summaryOn="@string/revanced_hide_floating_microphone_summary_on" android:summaryOff="@string/revanced_hide_floating_microphone_summary_off" />
|
<SwitchPreference android:title="@string/revanced_hide_floating_microphone_title" android:key="revanced_hide_floating_microphone" android:defaultValue="true" android:summaryOn="@string/revanced_hide_floating_microphone_summary_on" android:summaryOff="@string/revanced_hide_floating_microphone_summary_off" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user