fix(YouTube - Downloads): Use new task context (#2841)
This commit is contained in:
parent
f24adf753e
commit
6d88cb49ec
|
@ -1748,6 +1748,7 @@ public final class app/revanced/util/BytecodeUtilsKt {
|
||||||
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
|
public static final fun indexOfFirstInstruction (Lcom/android/tools/smali/dexlib2/iface/Method;Lkotlin/jvm/functions/Function1;)I
|
||||||
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
public static final fun indexOfFirstWideLiteralInstructionValue (Lcom/android/tools/smali/dexlib2/iface/Method;J)I
|
||||||
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
|
public static final fun injectHideViewCall (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableMethod;IILjava/lang/String;Ljava/lang/String;)V
|
||||||
|
public static final fun resultOrThrow (Lapp/revanced/patcher/fingerprint/MethodFingerprint;)Lapp/revanced/patcher/fingerprint/MethodFingerprintResult;
|
||||||
public static final fun returnEarly (Ljava/util/List;Z)V
|
public static final fun returnEarly (Ljava/util/List;Z)V
|
||||||
public static synthetic fun returnEarly$default (Ljava/util/List;ZILjava/lang/Object;)V
|
public static synthetic fun returnEarly$default (Ljava/util/List;ZILjava/lang/Object;)V
|
||||||
public static final fun transformMethods (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V
|
public static final fun transformMethods (Lapp/revanced/patcher/util/proxy/mutableTypes/MutableClass;Lkotlin/jvm/functions/Function1;)V
|
||||||
|
|
|
@ -64,8 +64,8 @@ abstract class BaseIntegrationsPatch(
|
||||||
|
|
||||||
method.addInstruction(
|
method.addInstruction(
|
||||||
0,
|
0,
|
||||||
"sput-object v$contextRegister, " +
|
"invoke-static/range { v$contextRegister .. v$contextRegister }, " +
|
||||||
"$integrationsDescriptor->context:Landroid/content/Context;",
|
"$integrationsDescriptor->setContext(Landroid/content/Context;)V",
|
||||||
)
|
)
|
||||||
} ?: throw PatchException("Could not find hook target fingerprint.")
|
} ?: throw PatchException("Could not find hook target fingerprint.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
package app.revanced.patches.youtube.interaction.downloads
|
package app.revanced.patches.youtube.interaction.downloads
|
||||||
|
|
||||||
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.addInstructionsWithLabels
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructionsWithLabels
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
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.smali.ExternalLabel
|
import app.revanced.patches.youtube.interaction.downloads.fingerprints.DownloadActionCommandResolverFingerprint
|
||||||
import app.revanced.patches.youtube.interaction.downloads.fingerprints.DownloadButtonActionFingerprint
|
import app.revanced.patches.youtube.interaction.downloads.fingerprints.DownloadActionCommandResolverParentFingerprint
|
||||||
|
import app.revanced.patches.youtube.interaction.downloads.fingerprints.LegacyDownloadCommandResolverFingerprint
|
||||||
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
|
import app.revanced.patches.youtube.misc.playercontrols.PlayerControlsBytecodePatch
|
||||||
|
import app.revanced.patches.youtube.shared.fingerprints.MainActivityFingerprint
|
||||||
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
import app.revanced.patches.youtube.video.information.VideoInformationPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.resultOrThrow
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
name = "Downloads",
|
name = "Downloads",
|
||||||
|
@ -39,8 +41,10 @@ import app.revanced.util.exception
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object DownloadsPatch : BytecodePatch(
|
object DownloadsPatch : BytecodePatch(
|
||||||
setOf(
|
setOf(
|
||||||
DownloadButtonActionFingerprint,
|
DownloadActionCommandResolverParentFingerprint,
|
||||||
),
|
LegacyDownloadCommandResolverFingerprint,
|
||||||
|
MainActivityFingerprint
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/DownloadsPatch;"
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/DownloadsPatch;"
|
||||||
private const val BUTTON_DESCRIPTOR = "Lapp/revanced/integrations/youtube/videoplayer/ExternalDownloadButton;"
|
private const val BUTTON_DESCRIPTOR = "Lapp/revanced/integrations/youtube/videoplayer/ExternalDownloadButton;"
|
||||||
|
@ -49,19 +53,46 @@ object DownloadsPatch : BytecodePatch(
|
||||||
PlayerControlsBytecodePatch.initializeControl("$BUTTON_DESCRIPTOR->initializeButton(Landroid/view/View;)V")
|
PlayerControlsBytecodePatch.initializeControl("$BUTTON_DESCRIPTOR->initializeButton(Landroid/view/View;)V")
|
||||||
PlayerControlsBytecodePatch.injectVisibilityCheckCall("$BUTTON_DESCRIPTOR->changeVisibility(Z)V")
|
PlayerControlsBytecodePatch.injectVisibilityCheckCall("$BUTTON_DESCRIPTOR->changeVisibility(Z)V")
|
||||||
|
|
||||||
DownloadButtonActionFingerprint.result?.let {
|
// Main activity is used to launch downloader intent.
|
||||||
it.mutableMethod.apply {
|
MainActivityFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
addInstructionsWithLabels(
|
addInstruction(
|
||||||
2,
|
implementation!!.instructions.lastIndex,
|
||||||
"""
|
"invoke-static { p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->activityCreated(Landroid/app/Activity;)V"
|
||||||
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick()Z
|
)
|
||||||
move-result v0
|
}
|
||||||
if-eqz v0, :show_dialog
|
|
||||||
return-void
|
val commonInstructions = """
|
||||||
""",
|
move-result v0
|
||||||
ExternalLabel("show_dialog", getInstruction(2)),
|
if-eqz v0, :show_native_downloader
|
||||||
|
return-void
|
||||||
|
:show_native_downloader
|
||||||
|
nop
|
||||||
|
"""
|
||||||
|
|
||||||
|
DownloadActionCommandResolverFingerprint.resolve(context,
|
||||||
|
DownloadActionCommandResolverParentFingerprint.resultOrThrow().classDef)
|
||||||
|
DownloadActionCommandResolverFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static {}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadButtonOnClick()Z
|
||||||
|
$commonInstructions
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy fingerprint is used for old spoofed versions,
|
||||||
|
// or if download playlist is pressed on any version.
|
||||||
|
// Downloading playlists is not yet supported,
|
||||||
|
// as the code this hooks does not easily expost the playlist id.
|
||||||
|
LegacyDownloadCommandResolverFingerprint.resultOrThrow().mutableMethod.apply {
|
||||||
|
addInstructionsWithLabels(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static/range {p1 .. p1}, $INTEGRATIONS_CLASS_DESCRIPTOR->inAppDownloadPlaylistLegacyOnClick(Ljava/lang/String;)Z
|
||||||
|
$commonInstructions
|
||||||
|
"""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} ?: throw DownloadButtonActionFingerprint.exception
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,8 @@ internal object DownloadsResourcePatch : ResourcePatch() {
|
||||||
sorting = Sorting.UNSORTED,
|
sorting = Sorting.UNSORTED,
|
||||||
preferences = setOf(
|
preferences = setOf(
|
||||||
SwitchPreference("revanced_external_downloader"),
|
SwitchPreference("revanced_external_downloader"),
|
||||||
|
SwitchPreference("revanced_external_downloader_action_button"),
|
||||||
TextPreference("revanced_external_downloader_name", inputType = InputType.TEXT),
|
TextPreference("revanced_external_downloader_name", inputType = InputType.TEXT),
|
||||||
SwitchPreference("revanced_use_in_app_download_button"),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package app.revanced.patches.youtube.interaction.downloads.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves to the class found in [DownloadActionCommandResolverParentFingerprint].
|
||||||
|
*/
|
||||||
|
internal object DownloadActionCommandResolverFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
returnType = "V",
|
||||||
|
parameters = listOf("L", "Ljava/util/Map;")
|
||||||
|
)
|
|
@ -0,0 +1,17 @@
|
||||||
|
package app.revanced.patches.youtube.interaction.downloads.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.util.patch.LiteralValueFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal object DownloadActionCommandResolverParentFingerprint : LiteralValueFingerprint(
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
returnType = "V",
|
||||||
|
parameters = listOf("L", "L"),
|
||||||
|
strings = listOf(
|
||||||
|
// Strings are not unique and found in other methods.
|
||||||
|
"com.google.android.libraries.youtube.logging.interaction_logger",
|
||||||
|
"Unknown command"
|
||||||
|
),
|
||||||
|
literalSupplier = { 16 }
|
||||||
|
)
|
|
@ -1,7 +0,0 @@
|
||||||
package app.revanced.patches.youtube.interaction.downloads.fingerprints
|
|
||||||
|
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
|
||||||
|
|
||||||
internal object DownloadButtonActionFingerprint : MethodFingerprint(
|
|
||||||
strings = listOf("offline/get_download_action"),
|
|
||||||
)
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package app.revanced.patches.youtube.interaction.downloads.fingerprints
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
import com.android.tools.smali.dexlib2.Opcode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For spoofing to older versions. Also called if download playlist is pressed for any version.
|
||||||
|
*/
|
||||||
|
internal object LegacyDownloadCommandResolverFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PRIVATE or AccessFlags.FINAL,
|
||||||
|
returnType = "V",
|
||||||
|
parameters = listOf("Ljava/lang/String;", "Ljava/lang/String;", "L", "L"),
|
||||||
|
strings = listOf(""),
|
||||||
|
opcodes = listOf(
|
||||||
|
Opcode.MOVE_OBJECT_FROM16,
|
||||||
|
Opcode.MOVE_OBJECT_FROM16,
|
||||||
|
Opcode.NEW_INSTANCE,
|
||||||
|
Opcode.INVOKE_DIRECT,
|
||||||
|
Opcode.IGET_OBJECT,
|
||||||
|
Opcode.IF_NEZ,
|
||||||
|
)
|
||||||
|
)
|
|
@ -32,6 +32,7 @@ import app.revanced.patches.youtube.video.videoid.VideoIdPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.exception
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
import app.revanced.util.indexOfFirstInstruction
|
import app.revanced.util.indexOfFirstInstruction
|
||||||
|
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.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
|
||||||
|
@ -88,8 +89,6 @@ object ReturnYouTubeDislikePatch : BytecodePatch(
|
||||||
private const val FILTER_CLASS_DESCRIPTOR =
|
private const val FILTER_CLASS_DESCRIPTOR =
|
||||||
"Lapp/revanced/integrations/youtube/patches/components/ReturnYouTubeDislikeFilterPatch;"
|
"Lapp/revanced/integrations/youtube/patches/components/ReturnYouTubeDislikeFilterPatch;"
|
||||||
|
|
||||||
private fun MethodFingerprint.resultOrThrow() = result ?: throw exception
|
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
// region Inject newVideoLoaded event handler to update dislikes when a new video is loaded.
|
// region Inject newVideoLoaded event handler to update dislikes when a new video is loaded.
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.reques
|
||||||
import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnSucceededFingerprint
|
import app.revanced.patches.youtube.layout.thumbnails.fingerprints.cronet.request.callback.OnSucceededFingerprint
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
import app.revanced.patches.youtube.misc.settings.SettingsPatch
|
||||||
import app.revanced.util.exception
|
import app.revanced.util.resultOrThrow
|
||||||
import com.android.tools.smali.dexlib2.AccessFlags
|
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.builder.MutableMethodImplementation
|
import com.android.tools.smali.dexlib2.builder.MutableMethodImplementation
|
||||||
|
@ -144,11 +144,8 @@ object AlternativeThumbnailsPatch : BytecodePatch(
|
||||||
NonInteractivePreference("revanced_alt_thumbnail_stills_about"),
|
NonInteractivePreference("revanced_alt_thumbnail_stills_about"),
|
||||||
)
|
)
|
||||||
|
|
||||||
fun MethodFingerprint.getResultOrThrow() =
|
|
||||||
result ?: throw exception
|
|
||||||
|
|
||||||
fun MethodFingerprint.alsoResolve(fingerprint: MethodFingerprint) =
|
fun MethodFingerprint.alsoResolve(fingerprint: MethodFingerprint) =
|
||||||
also { resolve(context, fingerprint.getResultOrThrow().classDef) }.getResultOrThrow()
|
also { resolve(context, fingerprint.resultOrThrow().classDef) }.resultOrThrow()
|
||||||
|
|
||||||
fun MethodFingerprint.resolveAndLetMutableMethod(
|
fun MethodFingerprint.resolveAndLetMutableMethod(
|
||||||
fingerprint: MethodFingerprint,
|
fingerprint: MethodFingerprint,
|
||||||
|
@ -172,7 +169,7 @@ object AlternativeThumbnailsPatch : BytecodePatch(
|
||||||
|
|
||||||
// The URL is required for the failure callback hook, but the URL field is obfuscated.
|
// The URL is required for the failure callback hook, but the URL field is obfuscated.
|
||||||
// Add a helper get method that returns the URL field.
|
// Add a helper get method that returns the URL field.
|
||||||
RequestFingerprint.getResultOrThrow().apply {
|
RequestFingerprint.resultOrThrow().apply {
|
||||||
// The url is the only string field that is set inside the constructor.
|
// The url is the only string field that is set inside the constructor.
|
||||||
val urlFieldInstruction = mutableMethod.getInstructions().first {
|
val urlFieldInstruction = mutableMethod.getInstructions().first {
|
||||||
if (it.opcode != Opcode.IPUT_OBJECT) return@first false
|
if (it.opcode != Opcode.IPUT_OBJECT) return@first false
|
||||||
|
|
|
@ -3,30 +3,31 @@ package app.revanced.patches.youtube.misc.playeroverlay
|
||||||
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.addInstruction
|
||||||
import app.revanced.patcher.patch.BytecodePatch
|
import app.revanced.patcher.patch.BytecodePatch
|
||||||
import app.revanced.patcher.patch.annotation.CompatiblePackage
|
|
||||||
import app.revanced.patcher.patch.annotation.Patch
|
import app.revanced.patcher.patch.annotation.Patch
|
||||||
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
import app.revanced.patches.youtube.misc.integrations.IntegrationsPatch
|
||||||
import app.revanced.patches.youtube.misc.playeroverlay.fingerprint.PlayerOverlaysOnFinishInflateFingerprint
|
import app.revanced.patches.youtube.misc.playeroverlay.fingerprint.PlayerOverlaysOnFinishInflateFingerprint
|
||||||
|
import app.revanced.util.exception
|
||||||
|
|
||||||
@Patch(
|
@Patch(
|
||||||
description = "Hook for adding custom overlays to the video player.",
|
description = "Hook for the video player overlay",
|
||||||
dependencies = [IntegrationsPatch::class],
|
dependencies = [IntegrationsPatch::class],
|
||||||
compatiblePackages = [
|
|
||||||
CompatiblePackage("com.google.android.youtube", [
|
|
||||||
"18.32.39"
|
|
||||||
])
|
|
||||||
]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit: This patch is not in use and may not work.
|
||||||
|
*/
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
object PlayerOverlaysHookPatch : BytecodePatch( // TODO: delete this unused outdated patch and its integration code.
|
object PlayerOverlaysHookPatch : BytecodePatch(
|
||||||
setOf(PlayerOverlaysOnFinishInflateFingerprint)
|
setOf(PlayerOverlaysOnFinishInflateFingerprint)
|
||||||
) {
|
) {
|
||||||
|
private const val INTEGRATIONS_CLASS_DESCRIPTOR = "Lapp/revanced/integrations/youtube/patches/PlayerOverlaysHookPatch;"
|
||||||
|
|
||||||
override fun execute(context: BytecodeContext) {
|
override fun execute(context: BytecodeContext) {
|
||||||
// hook YouTubePlayerOverlaysLayout.onFinishInflate()
|
PlayerOverlaysOnFinishInflateFingerprint.result?.mutableMethod?.apply {
|
||||||
val method = PlayerOverlaysOnFinishInflateFingerprint.result!!.mutableMethod
|
addInstruction(
|
||||||
method.addInstruction(
|
implementation!!.instructions.lastIndex,
|
||||||
method.implementation!!.instructions.size - 2,
|
"invoke-static { p0 }, $INTEGRATIONS_CLASS_DESCRIPTOR->playerOverlayInflated(Landroid/view/ViewGroup;)V"
|
||||||
"invoke-static { p0 }, Lapp/revanced/integrations/youtube/patches/PlayerOverlaysHookPatch;->YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava/lang/Object;)V"
|
|
||||||
)
|
)
|
||||||
|
} ?: throw PlayerOverlaysOnFinishInflateFingerprint.exception
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,14 @@
|
||||||
package app.revanced.patches.youtube.misc.playeroverlay.fingerprint
|
package app.revanced.patches.youtube.misc.playeroverlay.fingerprint
|
||||||
|
|
||||||
|
import app.revanced.patcher.extensions.or
|
||||||
import app.revanced.patcher.fingerprint.MethodFingerprint
|
import app.revanced.patcher.fingerprint.MethodFingerprint
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
internal object PlayerOverlaysOnFinishInflateFingerprint : MethodFingerprint(
|
internal object PlayerOverlaysOnFinishInflateFingerprint : MethodFingerprint(
|
||||||
|
accessFlags = AccessFlags.PUBLIC or AccessFlags.FINAL,
|
||||||
|
returnType = "V",
|
||||||
customFingerprint = { methodDef, _ ->
|
customFingerprint = { methodDef, _ ->
|
||||||
methodDef.definingClass.endsWith("YouTubePlayerOverlaysLayout;") && methodDef.name == "onFinishInflate"
|
methodDef.definingClass.endsWith("/YouTubePlayerOverlaysLayout;")
|
||||||
}
|
&& methodDef.name == "onFinishInflate"
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,6 +15,9 @@ import com.android.tools.smali.dexlib2.iface.instruction.WideLiteralInstruction
|
||||||
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
import com.android.tools.smali.dexlib2.iface.reference.Reference
|
||||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||||
|
|
||||||
|
|
||||||
|
fun MethodFingerprint.resultOrThrow() = result ?: throw exception
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The [PatchException] of failing to resolve a [MethodFingerprint].
|
* The [PatchException] of failing to resolve a [MethodFingerprint].
|
||||||
*
|
*
|
||||||
|
|
|
@ -232,12 +232,12 @@
|
||||||
<string name="revanced_external_downloader_title">Show external download button</string>
|
<string name="revanced_external_downloader_title">Show external download button</string>
|
||||||
<string name="revanced_external_downloader_summary_on">Download button shown in player</string>
|
<string name="revanced_external_downloader_summary_on">Download button shown in player</string>
|
||||||
<string name="revanced_external_downloader_summary_off">Download button not shown in player</string>
|
<string name="revanced_external_downloader_summary_off">Download button not shown in player</string>
|
||||||
|
<string name="revanced_external_downloader_action_button_title">Override download action button</string>
|
||||||
|
<string name="revanced_external_downloader_action_button_summary_on">Download button opens your external downloader</string>
|
||||||
|
<string name="revanced_external_downloader_action_button_summary_off">Download button opens the native in-app downloader</string>
|
||||||
<string name="revanced_external_downloader_name_title">Downloader package name</string>
|
<string name="revanced_external_downloader_name_title">Downloader package name</string>
|
||||||
<string name="revanced_external_downloader_name_summary">Package name of your installed external downloader app, such as NewPipe or Seal</string>
|
<string name="revanced_external_downloader_name_summary">Package name of your installed external downloader app, such as NewPipe or Seal</string>
|
||||||
<string name="revanced_external_downloader_not_installed_warning">%s is not installed. Please install it.</string>
|
<string name="revanced_external_downloader_not_installed_warning">%s is not installed. Please install it.</string>
|
||||||
<string name="revanced_use_in_app_download_button_title">Use in-app download button</string>
|
|
||||||
<string name="revanced_use_in_app_download_button_summary_on">Button will launch the external downloader</string>
|
|
||||||
<string name="revanced_use_in_app_download_button_summary_off">Button will launch the native in-app downloader</string>
|
|
||||||
</patch>
|
</patch>
|
||||||
<patch id="interaction.seekbar.DisablePreciseSeekingGesturePatch">
|
<patch id="interaction.seekbar.DisablePreciseSeekingGesturePatch">
|
||||||
<string name="revanced_disable_precise_seeking_gesture_title">Disable precise seeking gesture</string>
|
<string name="revanced_disable_precise_seeking_gesture_title">Disable precise seeking gesture</string>
|
||||||
|
|
Loading…
Reference in a new issue