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

Commit

Permalink
feat: --uninstall switch (ReVanced#84)
Browse files Browse the repository at this point in the history
This moves the move unmount script to a command
  • Loading branch information
Itroublve committed Jul 10, 2022
1 parent 8e91c12 commit 131100e
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 50 deletions.
62 changes: 45 additions & 17 deletions src/main/kotlin/app/revanced/cli/command/MainCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ internal object MainCommand : Runnable {
lateinit var args: Args

class Args {
@Option(names = ["-a", "--apk"], description = ["Input file to be patched"], required = true)
lateinit var inputFile: File

@Option(names = ["--uninstall"], description = ["Uninstall the mount variant"])
var uninstall: Boolean = false

@Option(names = ["-d", "--deploy-on"], description = ["If specified, deploy to adb device with given name"])
var deploy: String? = null

@ArgGroup(exclusive = false)
var sArgs: StartPatcherArgs? = null
}

class StartPatcherArgs {
@Option(names = ["-b", "--bundles"], description = ["One or more bundles of patches"], required = true)
var patchBundles = arrayOf<String>()

Expand All @@ -58,9 +72,6 @@ internal object MainCommand : Runnable {
}

class PatchingArgs {
@Option(names = ["-a", "--apk"], description = ["Input file to be patched"], required = true)
lateinit var inputFile: File

@Option(names = ["-o", "--out"], description = ["Output file path"], required = true)
lateinit var outputPath: String

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

@Option(names = ["-d", "--deploy-on"], description = ["If specified, deploy to adb device with given name"])
var deploy: String? = null

@Option(names = ["-t", "--temp-dir"], description = ["Temporal resource cache directory"])
var cacheDirectory = "revanced-cache"

Expand All @@ -108,16 +116,37 @@ internal object MainCommand : Runnable {
}

override fun run() {
if (args.lArgs?.listOnly == true) {
if (args.sArgs?.lArgs?.listOnly == true) {
printListOfPatches()
return
}

val args = args.pArgs ?: return
if (args.uninstall) {
// temporarily get package name using Patcher method
// fix: abstract options in patcher
val patcher = app.revanced.patcher.Patcher(
PatcherOptions(
args.inputFile,
"uninstaller-cache",
false
)
)
File("uninstaller-cache").deleteRecursively()

val adb: Adb? = args.deploy?.let {
Adb(File("placeholder_file"), patcher.data.packageMetadata.packageName, args.deploy!!, false)
}
adb?.uninstall()

return
}

val _args = args
val args = args.sArgs?.pArgs ?: return

val patcher = app.revanced.patcher.Patcher(
PatcherOptions(
args.inputFile,
_args.inputFile,
args.cacheDirectory,
!args.disableResourcePatching,
logger = PatcherLogger
Expand All @@ -126,10 +155,9 @@ internal object MainCommand : Runnable {

val outputFile = File(args.outputPath)

val adb: Adb? = args.deploy?.let {
Adb(outputFile, patcher.data.packageMetadata.packageName, args.deploy!!, !args.mount)
val adb: Adb? = _args.deploy?.let {
Adb(outputFile, patcher.data.packageMetadata.packageName, _args.deploy!!, !args.mount)
}

val patchedFile = if (args.mount) outputFile
else File(args.cacheDirectory).resolve("${outputFile.nameWithoutExtension}_raw.apk")

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

adb?.deploy()

if (args.clean && args.deploy != null) Files.delete(outputFile.toPath())
if (args.clean && _args.deploy != null) Files.delete(outputFile.toPath())

logger.info("Finished")
}

private fun printListOfPatches() {
for (patchBundlePath in args.patchBundles) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) {
for (patchBundlePath in args.sArgs?.patchBundles!!) for (patch in JarPatchBundle(patchBundlePath).loadPatches()) {
for (compatiblePackage in patch.compatiblePackages!!) {
val packageEntryStr = buildString {
// Add package if flag is set
if (args.lArgs?.withPackages == true) {
if (args.sArgs?.lArgs?.withPackages == true) {
val packageName = compatiblePackage.name.substringAfterLast(".").padStart(10)
append(packageName)
append("\t")
Expand All @@ -172,12 +200,12 @@ internal object MainCommand : Runnable {
val patchName = patch.patchName.padStart(25)
append(patchName)
// Add description if flag is set.
if (args.lArgs?.withDescriptions == true) {
if (args.sArgs?.lArgs?.withDescriptions == true) {
append("\t")
append(patch.description)
}
// Add compatible versions, if flag is set
if (args.lArgs?.withVersions == true) {
if (args.sArgs?.lArgs?.withVersions == true) {
val compatibleVersions = compatiblePackage.versions.joinToString(separator = ", ")
append("\t")
append(compatibleVersions)
Expand Down
5 changes: 3 additions & 2 deletions src/main/kotlin/app/revanced/cli/patcher/Patcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import java.nio.file.Files

internal object Patcher {
internal fun start(patcher: app.revanced.patcher.Patcher, output: File) {
val args = args.pArgs!!
val inputFile = args.inputFile
val args = args.sArgs?.pArgs!!

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

// write output file
if (output.exists()) Files.delete(output.toPath())
args.inputFile.copyTo(output)
inputFile.copyTo(output)

val result = patcher.save()
ZipFileSystemUtils(output).use { outputFileSystem ->
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/app/revanced/cli/signing/Signing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import java.io.File

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

Expand Down
29 changes: 18 additions & 11 deletions src/main/kotlin/app/revanced/utils/adb/Adb.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class Adb(
?: throw IllegalArgumentException("No such device with name $deviceName")

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

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

// create revanced path
// create revanced folder path
device.run("${Constants.COMMAND_CREATE_DIR} ${Constants.PATH_REVANCED}")

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

// push umount script
device.createFile(
Constants.PATH_INIT_PUSH,
Constants.CONTENT_UMOUNT_SCRIPT.replacePlaceholder()
)
// install unmount script
device.run(Constants.COMMAND_INSTALL_UMOUNT.replacePlaceholder())

// unmount the apk for sanity
device.run(Constants.PATH_UMOUNT.replacePlaceholder())
device.run(Constants.COMMAND_UMOUNT.replacePlaceholder())
// mount the apk
device.run(Constants.PATH_MOUNT.replacePlaceholder())

Expand All @@ -74,6 +66,21 @@ internal class Adb(
}
}

internal fun uninstall() {
logger.info("Uninstalling by unmounting")

// unmount the apk
device.run(Constants.COMMAND_UMOUNT.replacePlaceholder())

// delete revanced app
device.run(Constants.COMMAND_DELETE.replacePlaceholder(Constants.PATH_REVANCED_APP).replacePlaceholder())

// delete mount script
device.run(Constants.COMMAND_DELETE.replacePlaceholder(Constants.PATH_MOUNT).replacePlaceholder())

logger.info("Finished uninstalling")
}

private fun log() {
val executor = Executors.newSingleThreadExecutor()
val pipe = if (logging) {
Expand Down
24 changes: 9 additions & 15 deletions src/main/kotlin/app/revanced/utils/adb/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,25 @@ internal object Constants {
internal const val PATH_REVANCED = "/data/adb/revanced/"

// revanced apk path
private const val PATH_REVANCED_APP = "$PATH_REVANCED$PLACEHOLDER.apk"
internal const val PATH_REVANCED_APP = "$PATH_REVANCED$PLACEHOLDER.apk"

// (un)mount script paths
// delete command
internal const val COMMAND_DELETE = "rm -rf $PLACEHOLDER"

// mount script path
internal const val PATH_MOUNT = "/data/adb/service.d/$NAME_MOUNT_SCRIPT"
internal const val PATH_UMOUNT = "/data/adb/post-fs-data.d/un$NAME_MOUNT_SCRIPT"

// move to revanced apk path & set permissions
internal const val COMMAND_PREPARE_MOUNT_APK =
"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"

// unmount command
internal const val COMMAND_UMOUNT =
"stock_path=${'$'}( pm path $PLACEHOLDER | grep base | sed 's/package://g' ) && umount -l ${'$'}stock_path"

// install mount script & set permissions
internal const val COMMAND_INSTALL_MOUNT = "mv $PATH_INIT_PUSH $PATH_MOUNT && $COMMAND_CHMOD_MOUNT $PATH_MOUNT"

// install umount script & set permissions
internal const val COMMAND_INSTALL_UMOUNT = "mv $PATH_INIT_PUSH $PATH_UMOUNT && $COMMAND_CHMOD_MOUNT $PATH_UMOUNT"

// unmount script
internal val CONTENT_UMOUNT_SCRIPT =
"""
#!/system/bin/sh
stock_path=${'$'}( pm path $PLACEHOLDER | grep base | sed 's/package://g' )
umount -l ${'$'}stock_path
""".trimIndent()

// mount script
internal val CONTENT_MOUNT_SCRIPT =
"""
Expand Down
8 changes: 4 additions & 4 deletions src/main/kotlin/app/revanced/utils/patcher/Patcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ fun Patcher.addPatchesFiltered() {
val packageName = this.data.packageMetadata.packageName
val packageVersion = this.data.packageMetadata.packageVersion

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

val prefix = "Skipping $patchName"

val args = MainCommand.args.pArgs!!
val args = MainCommand.args.sArgs?.pArgs!!

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

fun Patcher.mergeFiles() {
this.addFiles(args.pArgs!!.mergeFiles) { file ->
this.addFiles(args.sArgs?.pArgs!!.mergeFiles) { file ->
logger.info("Merging $file")
}
}
}

0 comments on commit 131100e

Please sign in to comment.