Skip to content
This repository was archived by the owner on Apr 15, 2024. It is now read-only.

Commit 131100e

Browse files
author
Itroublve
authored
feat: --uninstall switch (ReVanced#84)
This moves the move unmount script to a command
1 parent 8e91c12 commit 131100e

File tree

6 files changed

+80
-50
lines changed

6 files changed

+80
-50
lines changed

src/main/kotlin/app/revanced/cli/command/MainCommand.kt

+45-17
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ internal object MainCommand : Runnable {
3333
lateinit var args: Args
3434

3535
class Args {
36+
@Option(names = ["-a", "--apk"], description = ["Input file to be patched"], required = true)
37+
lateinit var inputFile: File
38+
39+
@Option(names = ["--uninstall"], description = ["Uninstall the mount variant"])
40+
var uninstall: Boolean = false
41+
42+
@Option(names = ["-d", "--deploy-on"], description = ["If specified, deploy to adb device with given name"])
43+
var deploy: String? = null
44+
45+
@ArgGroup(exclusive = false)
46+
var sArgs: StartPatcherArgs? = null
47+
}
48+
49+
class StartPatcherArgs {
3650
@Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"], required = true)
3751
var patchBundles = arrayOf<String>()
3852

@@ -58,9 +72,6 @@ internal object MainCommand : Runnable {
5872
}
5973

6074
class PatchingArgs {
61-
@Option(names = ["-a", "--apk"], description = ["Input file to be patched"], required = true)
62-
lateinit var inputFile: File
63-
6475
@Option(names = ["-o", "--out"], description = ["Output file path"], required = true)
6576
lateinit var outputPath: String
6677

@@ -94,9 +105,6 @@ internal object MainCommand : Runnable {
94105
@Option(names = ["-p", "--password"], description = ["Overwrite the default password for the signed file"])
95106
var password = "ReVanced"
96107

97-
@Option(names = ["-d", "--deploy-on"], description = ["If specified, deploy to adb device with given name"])
98-
var deploy: String? = null
99-
100108
@Option(names = ["-t", "--temp-dir"], description = ["Temporal resource cache directory"])
101109
var cacheDirectory = "revanced-cache"
102110

@@ -108,16 +116,37 @@ internal object MainCommand : Runnable {
108116
}
109117

110118
override fun run() {
111-
if (args.lArgs?.listOnly == true) {
119+
if (args.sArgs?.lArgs?.listOnly == true) {
112120
printListOfPatches()
113121
return
114122
}
115123

116-
val args = args.pArgs ?: return
124+
if (args.uninstall) {
125+
// temporarily get package name using Patcher method
126+
// fix: abstract options in patcher
127+
val patcher = app.revanced.patcher.Patcher(
128+
PatcherOptions(
129+
args.inputFile,
130+
"uninstaller-cache",
131+
false
132+
)
133+
)
134+
File("uninstaller-cache").deleteRecursively()
135+
136+
val adb: Adb? = args.deploy?.let {
137+
Adb(File("placeholder_file"), patcher.data.packageMetadata.packageName, args.deploy!!, false)
138+
}
139+
adb?.uninstall()
140+
141+
return
142+
}
143+
144+
val _args = args
145+
val args = args.sArgs?.pArgs ?: return
117146

118147
val patcher = app.revanced.patcher.Patcher(
119148
PatcherOptions(
120-
args.inputFile,
149+
_args.inputFile,
121150
args.cacheDirectory,
122151
!args.disableResourcePatching,
123152
logger = PatcherLogger
@@ -126,10 +155,9 @@ internal object MainCommand : Runnable {
126155

127156
val outputFile = File(args.outputPath)
128157

129-
val adb: Adb? = args.deploy?.let {
130-
Adb(outputFile, patcher.data.packageMetadata.packageName, args.deploy!!, !args.mount)
158+
val adb: Adb? = _args.deploy?.let {
159+
Adb(outputFile, patcher.data.packageMetadata.packageName, _args.deploy!!, !args.mount)
131160
}
132-
133161
val patchedFile = if (args.mount) outputFile
134162
else File(args.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk")
135163

@@ -153,17 +181,17 @@ internal object MainCommand : Runnable {
153181

154182
adb?.deploy()
155183

156-
if (args.clean && args.deploy != null) Files.delete(outputFile.toPath())
184+
if (args.clean && _args.deploy != null) Files.delete(outputFile.toPath())
157185

158186
logger.info("Finished")
159187
}
160188

161189
private fun printListOfPatches() {
162-
for (patchBundlePath in args.patchBundles) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) {
190+
for (patchBundlePath in args.sArgs?.patchBundles!!) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) {
163191
for (compatiblePackage in patch.compatiblePackages!!) {
164192
val packageEntryStr = buildString {
165193
// Add package if flag is set
166-
if (args.lArgs?.withPackages == true) {
194+
if (args.sArgs?.lArgs?.withPackages == true) {
167195
val packageName = compatiblePackage.name.substringAfterLast(".").padStart(10)
168196
append(packageName)
169197
append("\t")
@@ -172,12 +200,12 @@ internal object MainCommand : Runnable {
172200
val patchName = patch.patchName.padStart(25)
173201
append(patchName)
174202
// Add description if flag is set.
175-
if (args.lArgs?.withDescriptions == true) {
203+
if (args.sArgs?.lArgs?.withDescriptions == true) {
176204
append("\t")
177205
append(patch.description)
178206
}
179207
// Add compatible versions, if flag is set
180-
if (args.lArgs?.withVersions == true) {
208+
if (args.sArgs?.lArgs?.withVersions == true) {
181209
val compatibleVersions = compatiblePackage.versions.joinToString(separator = ", ")
182210
append("\t")
183211
append(compatibleVersions)

src/main/kotlin/app/revanced/cli/patcher/Patcher.kt

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import java.nio.file.Files
1111

1212
internal object Patcher {
1313
internal fun start(patcher: app.revanced.patcher.Patcher, output: File) {
14-
val args = args.pArgs!!
14+
val inputFile = args.inputFile
15+
val args = args.sArgs?.pArgs!!
1516

1617
// merge files like necessary integrations
1718
patcher.mergeFiles()
@@ -22,7 +23,7 @@ internal object Patcher {
2223

2324
// write output file
2425
if (output.exists()) Files.delete(output.toPath())
25-
args.inputFile.copyTo(output)
26+
inputFile.copyTo(output)
2627

2728
val result = patcher.save()
2829
ZipFileSystemUtils(output).use { outputFileSystem ->

src/main/kotlin/app/revanced/cli/signing/Signing.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import java.io.File
88

99
object Signing {
1010
fun start(inputFile: File, outputFile: File, signingOptions: SigningOptions) {
11-
val cacheDirectory = File(args.pArgs!!.cacheDirectory)
11+
val cacheDirectory = File(args.sArgs?.pArgs?.cacheDirectory)
1212
val alignedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_aligned.apk")
1313
val signedOutput = cacheDirectory.resolve("${outputFile.nameWithoutExtension}_signed.apk")
1414

src/main/kotlin/app/revanced/utils/adb/Adb.kt

+18-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ internal class Adb(
2121
?: throw IllegalArgumentException("No such device with name $deviceName")
2222

2323
if (!modeInstall && device.run("su -h", false) != 0)
24-
throw IllegalArgumentException("Root required on $deviceName. Deploying failed")
24+
throw IllegalArgumentException("Root required on $deviceName. Task failed")
2525
}
2626

2727
private fun String.replacePlaceholder(with: String? = null): String {
@@ -39,7 +39,7 @@ internal class Adb(
3939
// push patched file
4040
device.copy(Constants.PATH_INIT_PUSH, file)
4141

42-
// create revanced path
42+
// create revanced folder path
4343
device.run("${Constants.COMMAND_CREATE_DIR} ${Constants.PATH_REVANCED}")
4444

4545
// prepare mounting the apk
@@ -53,16 +53,8 @@ internal class Adb(
5353
// install mount script
5454
device.run(Constants.COMMAND_INSTALL_MOUNT.replacePlaceholder())
5555

56-
// push umount script
57-
device.createFile(
58-
Constants.PATH_INIT_PUSH,
59-
Constants.CONTENT_UMOUNT_SCRIPT.replacePlaceholder()
60-
)
61-
// install unmount script
62-
device.run(Constants.COMMAND_INSTALL_UMOUNT.replacePlaceholder())
63-
6456
// unmount the apk for sanity
65-
device.run(Constants.PATH_UMOUNT.replacePlaceholder())
57+
device.run(Constants.COMMAND_UMOUNT.replacePlaceholder())
6658
// mount the apk
6759
device.run(Constants.PATH_MOUNT.replacePlaceholder())
6860

@@ -74,6 +66,21 @@ internal class Adb(
7466
}
7567
}
7668

69+
internal fun uninstall() {
70+
logger.info("Uninstalling by unmounting")
71+
72+
// unmount the apk
73+
device.run(Constants.COMMAND_UMOUNT.replacePlaceholder())
74+
75+
// delete revanced app
76+
device.run(Constants.COMMAND_DELETE.replacePlaceholder(Constants.PATH_REVANCED_APP).replacePlaceholder())
77+
78+
// delete mount script
79+
device.run(Constants.COMMAND_DELETE.replacePlaceholder(Constants.PATH_MOUNT).replacePlaceholder())
80+
81+
logger.info("Finished uninstalling")
82+
}
83+
7784
private fun log() {
7885
val executor = Executors.newSingleThreadExecutor()
7986
val pipe = if (logging) {

src/main/kotlin/app/revanced/utils/adb/Constants.kt

+9-15
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,25 @@ internal object Constants {
2121
internal const val PATH_REVANCED = "/data/adb/revanced/"
2222

2323
// revanced apk path
24-
private const val PATH_REVANCED_APP = "$PATH_REVANCED$PLACEHOLDER.apk"
24+
internal const val PATH_REVANCED_APP = "$PATH_REVANCED$PLACEHOLDER.apk"
2525

26-
// (un)mount script paths
26+
// delete command
27+
internal const val COMMAND_DELETE = "rm -rf $PLACEHOLDER"
28+
29+
// mount script path
2730
internal const val PATH_MOUNT = "/data/adb/service.d/$NAME_MOUNT_SCRIPT"
28-
internal const val PATH_UMOUNT = "/data/adb/post-fs-data.d/un$NAME_MOUNT_SCRIPT"
2931

3032
// move to revanced apk path & set permissions
3133
internal const val COMMAND_PREPARE_MOUNT_APK =
3234
"base_path=\"$PATH_REVANCED_APP\" && mv $PATH_INIT_PUSH ${'$'}base_path && chmod 644 ${'$'}base_path && chown system:system ${'$'}base_path && chcon u:object_r:apk_data_file:s0 ${'$'}base_path"
3335

36+
// unmount command
37+
internal const val COMMAND_UMOUNT =
38+
"stock_path=${'$'}( pm path $PLACEHOLDER | grep base | sed 's/package://g' ) && umount -l ${'$'}stock_path"
39+
3440
// install mount script & set permissions
3541
internal const val COMMAND_INSTALL_MOUNT = "mv $PATH_INIT_PUSH $PATH_MOUNT && $COMMAND_CHMOD_MOUNT $PATH_MOUNT"
3642

37-
// install umount script & set permissions
38-
internal const val COMMAND_INSTALL_UMOUNT = "mv $PATH_INIT_PUSH $PATH_UMOUNT && $COMMAND_CHMOD_MOUNT $PATH_UMOUNT"
39-
40-
// unmount script
41-
internal val CONTENT_UMOUNT_SCRIPT =
42-
"""
43-
#!/system/bin/sh
44-
45-
stock_path=${'$'}( pm path $PLACEHOLDER | grep base | sed 's/package://g' )
46-
umount -l ${'$'}stock_path
47-
""".trimIndent()
48-
4943
// mount script
5044
internal val CONTENT_MOUNT_SCRIPT =
5145
"""

src/main/kotlin/app/revanced/utils/patcher/Patcher.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ fun Patcher.addPatchesFiltered() {
1515
val packageName = this.data.packageMetadata.packageName
1616
val packageVersion = this.data.packageMetadata.packageVersion
1717

18-
args.patchBundles.forEach { bundle ->
18+
args.sArgs?.patchBundles!!.forEach { bundle ->
1919
val includedPatches = mutableListOf<Class<out Patch<Data>>>()
2020
JarPatchBundle(bundle).loadPatches().forEach patch@{ patch ->
2121
val compatiblePackages = patch.compatiblePackages
2222
val patchName = patch.patchName
2323

2424
val prefix = "Skipping $patchName"
2525

26-
val args = MainCommand.args.pArgs!!
26+
val args = MainCommand.args.sArgs?.pArgs!!
2727

2828
if (excludePatches && args.excludedPatches.contains(patchName)) {
2929
logger.info("$prefix: Explicitely excluded")
@@ -72,7 +72,7 @@ fun Patcher.applyPatchesVerbose() {
7272
}
7373

7474
fun Patcher.mergeFiles() {
75-
this.addFiles(args.pArgs!!.mergeFiles) { file ->
75+
this.addFiles(args.sArgs?.pArgs!!.mergeFiles) { file ->
7676
logger.info("Merging $file")
7777
}
78-
}
78+
}

0 commit comments

Comments
 (0)