mirror of
https://github.com/revanced/revanced-patches.git
synced 2025-06-12 05:07:45 +02:00
feat: Add Internal data documents provider patch (#3830)
Co-authored-by: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
@ -60,6 +60,10 @@ public final class app/revanced/patches/all/misc/directory/ChangeDataDirectoryLo
|
||||
public static final fun getChangeDataDirectoryLocationPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/misc/directory/documentsprovider/ExportInternalDataDocumentsProviderPatchKt {
|
||||
public static final fun getExportInternalDataDocumentsProviderPatch ()Lapp/revanced/patcher/patch/ResourcePatch;
|
||||
}
|
||||
|
||||
public final class app/revanced/patches/all/misc/hex/HexPatchKt {
|
||||
public static final fun getHexPatch ()Lapp/revanced/patcher/patch/RawResourcePatch;
|
||||
}
|
||||
|
@ -1,58 +1,19 @@
|
||||
package app.revanced.patches.all.misc.directory
|
||||
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patches.all.misc.transformation.transformInstructionsPatch
|
||||
import app.revanced.util.getReference
|
||||
import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c
|
||||
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||
import com.android.tools.smali.dexlib2.immutable.reference.ImmutableMethodReference
|
||||
import com.android.tools.smali.dexlib2.util.MethodUtil
|
||||
import app.revanced.patches.all.misc.directory.documentsprovider.exportInternalDataDocumentsProviderPatch
|
||||
|
||||
@Suppress("unused")
|
||||
@Deprecated(
|
||||
"Superseded by internalDataDocumentsProviderPatch",
|
||||
ReplaceWith("internalDataDocumentsProviderPatch"),
|
||||
)
|
||||
val changeDataDirectoryLocationPatch = bytecodePatch(
|
||||
name = "Change data directory location",
|
||||
// name = "Change data directory location",
|
||||
description = "Changes the data directory in the application from " +
|
||||
"the app internal storage directory to /sdcard/android/data accessible by root-less devices." +
|
||||
"Using this patch can cause unexpected issues with some apps.",
|
||||
use = false,
|
||||
) {
|
||||
dependsOn(
|
||||
transformInstructionsPatch(
|
||||
filterMap = filter@{ _, _, instruction, instructionIndex ->
|
||||
val reference = instruction.getReference<MethodReference>() ?: return@filter null
|
||||
|
||||
if (!MethodUtil.methodSignaturesMatch(reference, MethodCall.GetDir.reference)) {
|
||||
return@filter null
|
||||
}
|
||||
|
||||
return@filter instructionIndex
|
||||
},
|
||||
transform = { method, index ->
|
||||
val getDirInstruction = method.getInstruction<Instruction35c>(index)
|
||||
val contextRegister = getDirInstruction.registerC
|
||||
val dataRegister = getDirInstruction.registerD
|
||||
|
||||
method.replaceInstruction(
|
||||
index,
|
||||
"invoke-virtual { v$contextRegister, v$dataRegister }, " +
|
||||
"Landroid/content/Context;->getExternalFilesDir(Ljava/lang/String;)Ljava/io/File;",
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private enum class MethodCall(
|
||||
val reference: MethodReference,
|
||||
) {
|
||||
GetDir(
|
||||
ImmutableMethodReference(
|
||||
"Landroid/content/Context;",
|
||||
"getDir",
|
||||
listOf("Ljava/lang/String;", "I"),
|
||||
"Ljava/io/File;",
|
||||
),
|
||||
),
|
||||
dependsOn(exportInternalDataDocumentsProviderPatch)
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
package app.revanced.patches.all.misc.directory.documentsprovider
|
||||
|
||||
import app.revanced.patcher.patch.bytecodePatch
|
||||
import app.revanced.patcher.patch.resourcePatch
|
||||
import app.revanced.util.asSequence
|
||||
import app.revanced.util.getNode
|
||||
|
||||
@Suppress("unused")
|
||||
val exportInternalDataDocumentsProviderPatch = resourcePatch(
|
||||
name = "Export internal data documents provider",
|
||||
description = "Exports a documents provider that grants access to the internal data directory of this app " +
|
||||
"to file managers and other apps that support the Storage Access Framework.",
|
||||
use = false,
|
||||
) {
|
||||
dependsOn(
|
||||
bytecodePatch {
|
||||
extendWith("extensions/all/misc/directory/export-internal-data-documents-provider.rve")
|
||||
},
|
||||
)
|
||||
|
||||
execute {
|
||||
val documentsProviderClass =
|
||||
"app.revanced.extension.all.misc.directory.documentsprovider.InternalDataDocumentsProvider"
|
||||
|
||||
document("AndroidManifest.xml").use { document ->
|
||||
// Check if the provider is already declared
|
||||
if (document.getElementsByTagName("provider")
|
||||
.asSequence()
|
||||
.any { it.attributes.getNamedItem("android:name")?.nodeValue == documentsProviderClass }
|
||||
) {
|
||||
return@execute
|
||||
}
|
||||
|
||||
val authority =
|
||||
document.getNode("manifest").attributes.getNamedItem("package").let {
|
||||
// Select a URI authority name that is unique to the current app
|
||||
"${it.nodeValue}.$documentsProviderClass"
|
||||
}
|
||||
|
||||
// Register the documents provider
|
||||
with(document.getNode("application")) {
|
||||
document.createElement("provider").apply {
|
||||
setAttribute("android:name", documentsProviderClass)
|
||||
setAttribute("android:authorities", authority)
|
||||
setAttribute("android:exported", "true")
|
||||
setAttribute("android:grantUriPermissions", "true")
|
||||
setAttribute("android:permission", "android.permission.MANAGE_DOCUMENTS")
|
||||
|
||||
document.createElement("intent-filter").apply {
|
||||
document.createElement("action").apply {
|
||||
setAttribute("android:name", "android.content.action.DOCUMENTS_PROVIDER")
|
||||
}.let(this::appendChild)
|
||||
}.let(this::appendChild)
|
||||
}.let(this::appendChild)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user