mirror of
https://github.com/revanced/revanced-cli.git
synced 2024-11-19 01:59:25 +01:00
fix: deploy to adb
Signed-off-by: oSumAtrIX <johan.melkonyan1@web.de>
This commit is contained in:
parent
3776ab9a0b
commit
f9b987e858
@ -2,7 +2,7 @@ package app.revanced.cli
|
|||||||
|
|
||||||
import app.revanced.patch.PatchLoader
|
import app.revanced.patch.PatchLoader
|
||||||
import app.revanced.patch.Patches
|
import app.revanced.patch.Patches
|
||||||
import picocli.CommandLine
|
import app.revanced.utils.adb.Adb
|
||||||
import picocli.CommandLine.*
|
import picocli.CommandLine.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@ -10,24 +10,26 @@ import java.io.File
|
|||||||
name = "ReVanced-CLI", version = ["1.0.0"], mixinStandardHelpOptions = true
|
name = "ReVanced-CLI", version = ["1.0.0"], mixinStandardHelpOptions = true
|
||||||
)
|
)
|
||||||
internal object MainCommand : Runnable {
|
internal object MainCommand : Runnable {
|
||||||
@Option(names = ["-p", "--patches"], description = ["One or more bundles of patches"])
|
|
||||||
internal var patchBundles = arrayOf<File>()
|
|
||||||
|
|
||||||
@Parameters(
|
@Parameters(
|
||||||
paramLabel = "INCLUDE",
|
paramLabel = "INCLUDE",
|
||||||
description = ["Which patches to include. If none is specified, all compatible patches will be included"]
|
description = ["Which patches to include. If none is specified, all compatible patches will be included"]
|
||||||
)
|
)
|
||||||
internal var includedPatches = arrayOf<String>()
|
internal var includedPatches = arrayOf<String>()
|
||||||
|
|
||||||
@Option(names = ["-c", "--cache"], description = ["Output resource cache directory"], required = true)
|
@Option(names = ["-p", "--patches"], description = ["One or more bundles of patches"])
|
||||||
|
internal var patchBundles = arrayOf<File>()
|
||||||
|
|
||||||
|
@Option(names = ["-t", "--temp-dir"], description = ["Temporal resource cache directory"], required = true)
|
||||||
internal lateinit var cacheDirectory: String
|
internal lateinit var cacheDirectory: String
|
||||||
|
|
||||||
@Option(names = ["-r", "--resource-patcher"], description = ["Enable patching resources"])
|
@Option(names = ["-r", "--resource-patcher"], description = ["Enable patching resources"])
|
||||||
internal var patchResources: Boolean = false
|
internal var patchResources: Boolean = false
|
||||||
|
|
||||||
@Option(names = ["-w", "--wipe-after"], description = ["Wipe the temporal directory before exiting the patcher"])
|
@Option(
|
||||||
internal var wipe: Boolean = false
|
names = ["-c", "--clean"],
|
||||||
|
description = ["Clean the temporal resource cache directory. This will be done anyways when running the patcher"]
|
||||||
|
)
|
||||||
|
internal var clean: Boolean = false
|
||||||
|
|
||||||
@Option(names = ["-l", "--list"], description = ["List patches only"])
|
@Option(names = ["-l", "--list"], description = ["List patches only"])
|
||||||
internal var listOnly: Boolean = false
|
internal var listOnly: Boolean = false
|
||||||
@ -44,7 +46,6 @@ internal object MainCommand : Runnable {
|
|||||||
@Option(names = ["-d", "--deploy-on"], description = ["If specified, deploy to adb device with given name"])
|
@Option(names = ["-d", "--deploy-on"], description = ["If specified, deploy to adb device with given name"])
|
||||||
internal var deploy: String? = null
|
internal var deploy: String? = null
|
||||||
|
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
if (listOnly) {
|
if (listOnly) {
|
||||||
patchBundles.forEach {
|
patchBundles.forEach {
|
||||||
@ -61,17 +62,23 @@ internal object MainCommand : Runnable {
|
|||||||
cacheDirectory,
|
cacheDirectory,
|
||||||
patchResources
|
patchResources
|
||||||
)
|
)
|
||||||
|
|
||||||
Patcher.start(patcher)
|
Patcher.start(patcher)
|
||||||
|
|
||||||
if (!wipe) return
|
if (clean) {
|
||||||
File(cacheDirectory).deleteRecursively()
|
File(cacheDirectory).deleteRecursively()
|
||||||
|
}
|
||||||
|
|
||||||
|
val outputFile = File(outputPath)
|
||||||
|
|
||||||
deploy?.let {
|
deploy?.let {
|
||||||
Adb(
|
Adb(
|
||||||
File(outputPath),
|
outputFile,
|
||||||
patcher.packageName,
|
patcher.packageName,
|
||||||
deploy!!
|
deploy!!
|
||||||
).deploy()
|
).deploy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clean) outputFile.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,40 +17,49 @@ internal class Adb(
|
|||||||
device = JadbConnection().devices.find { it.serial == deviceName }
|
device = JadbConnection().devices.find { it.serial == deviceName }
|
||||||
?: throw IllegalArgumentException("No such device with name $deviceName")
|
?: throw IllegalArgumentException("No such device with name $deviceName")
|
||||||
|
|
||||||
if (device.run("su -h") == 0)
|
if (device.run("su -h", false) != 0)
|
||||||
throw IllegalArgumentException("Root required on $deviceName. Deploying failed.")
|
throw IllegalArgumentException("Root required on $deviceName. Deploying failed.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun String.replacePlaceholder(): String {
|
||||||
|
return this.replace(Constants.PLACEHOLDER, packageName)
|
||||||
|
}
|
||||||
|
|
||||||
internal fun deploy() {
|
internal fun deploy() {
|
||||||
// create revanced path
|
// create revanced path
|
||||||
device.run(Constants.COMMAND_CREATE_DIR + Constants.PATH_DATA)
|
device.run("${Constants.COMMAND_CREATE_DIR} ${Constants.PATH_REVANCED}")
|
||||||
|
|
||||||
// create mount script
|
|
||||||
device.createFile(
|
|
||||||
Constants.PATH_INIT_PUSH,
|
|
||||||
Constants.CONTENT_MOUNT_SCRIPT.replace(Constants.PLACEHOLDER, packageName)
|
|
||||||
)
|
|
||||||
|
|
||||||
// move the mount script to the revanced path
|
|
||||||
device.run(Constants.COMMAND_MOVE_MOUNT)
|
|
||||||
// make the mount script executable
|
|
||||||
device.run(Constants.COMMAND_CHMOD_MOUNT + Constants.NAME_MOUNT_SCRIPT)
|
|
||||||
|
|
||||||
// push patched file
|
// push patched file
|
||||||
device.copy(Constants.PATH_INIT_PUSH, apk)
|
device.copy(Constants.PATH_INIT_PUSH, apk)
|
||||||
// move patched file to revanced path
|
// install apk
|
||||||
device.run(Constants.COMMAND_MOVE_BASE)
|
device.run(Constants.COMMAND_INSTALL_APK.replacePlaceholder())
|
||||||
|
|
||||||
// kill, mount & run app
|
// push mount script
|
||||||
device.run(Constants.COMMAND_KILL_APP.replace(Constants.PLACEHOLDER, packageName))
|
device.createFile(
|
||||||
device.run(Constants.COMMAND_MOUNT)
|
Constants.PATH_INIT_PUSH,
|
||||||
device.run(Constants.COMMAND_RUN_APP.replace(Constants.PLACEHOLDER, packageName))
|
Constants.CONTENT_MOUNT_SCRIPT.replacePlaceholder()
|
||||||
|
)
|
||||||
|
// 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 mount script
|
||||||
|
device.run(Constants.COMMAND_INSTALL_UMOUNT.replacePlaceholder())
|
||||||
|
|
||||||
|
// unmount the apk for sanity
|
||||||
|
device.run(Constants.PATH_UMOUNT.replacePlaceholder())
|
||||||
|
// mount the apk
|
||||||
|
device.run(Constants.PATH_MOUNT.replacePlaceholder())
|
||||||
|
|
||||||
|
// relaunch app
|
||||||
|
device.run(Constants.COMMAND_RESTART.replacePlaceholder())
|
||||||
|
|
||||||
// log the app
|
// log the app
|
||||||
log()
|
log()
|
||||||
|
|
||||||
// unmount it, after it closes
|
|
||||||
device.run(Constants.COMMAND_UNMOUNT.replace(Constants.PLACEHOLDER, packageName))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun log() {
|
private fun log() {
|
||||||
@ -61,16 +70,16 @@ internal class Adb(
|
|||||||
ProcessBuilder.Redirect.PIPE
|
ProcessBuilder.Redirect.PIPE
|
||||||
}
|
}
|
||||||
|
|
||||||
val process = device.buildCommand(Constants.COMMAND_LOGCAT.replace(Constants.PLACEHOLDER, packageName))
|
val process = device.buildCommand(Constants.COMMAND_LOGCAT.replacePlaceholder())
|
||||||
.redirectOutput(pipe)
|
.redirectOutput(pipe)
|
||||||
.redirectError(pipe)
|
.redirectError(pipe)
|
||||||
.useExecutor(executor)
|
.useExecutor(executor)
|
||||||
.start()
|
.start()
|
||||||
|
|
||||||
Thread.sleep(250) // give the app some time to start up.
|
Thread.sleep(500) // give the app some time to start up.
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
while (device.run(Constants.COMMAND_PID_OF + packageName) == 0) {
|
while (device.run("${Constants.COMMAND_PID_OF} $packageName") == 0) {
|
||||||
Thread.sleep(1000)
|
Thread.sleep(1000)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
@ -6,6 +6,10 @@ import se.vidstige.jadb.ShellProcessBuilder
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal fun JadbDevice.buildCommand(command: String, su: Boolean = true): ShellProcessBuilder {
|
internal fun JadbDevice.buildCommand(command: String, su: Boolean = true): ShellProcessBuilder {
|
||||||
|
if (su) {
|
||||||
|
return shellProcessBuilder("su -c \'$command\'")
|
||||||
|
}
|
||||||
|
|
||||||
val args = command.split(" ") as ArrayList<String>
|
val args = command.split(" ") as ArrayList<String>
|
||||||
val cmd = args.removeFirst()
|
val cmd = args.removeFirst()
|
||||||
|
|
||||||
@ -13,13 +17,13 @@ internal fun JadbDevice.buildCommand(command: String, su: Boolean = true): Shell
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun JadbDevice.run(command: String, su: Boolean = true): Int {
|
internal fun JadbDevice.run(command: String, su: Boolean = true): Int {
|
||||||
return this.buildCommand(command).start().waitFor()
|
return this.buildCommand(command, su).start().waitFor()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun JadbDevice.copy(targetPath: String, file: File) {
|
internal fun JadbDevice.copy(targetPath: String, file: File) {
|
||||||
push(file, RemoteFile(targetPath))
|
push(file, RemoteFile(targetPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun JadbDevice.createFile(targetFile: String, content: String, su: Boolean = true) {
|
internal fun JadbDevice.createFile(targetFile: String, content: String) {
|
||||||
push(content.byteInputStream(), System.currentTimeMillis(), 644, RemoteFile(targetFile))
|
push(content.byteInputStream(), System.currentTimeMillis(), 644, RemoteFile(targetFile))
|
||||||
}
|
}
|
@ -1,34 +1,57 @@
|
|||||||
package app.revanced.utils.adb
|
package app.revanced.utils.adb
|
||||||
|
|
||||||
internal object Constants {
|
internal object Constants {
|
||||||
|
// template placeholder to replace a string in commands
|
||||||
internal const val PLACEHOLDER = "TEMPLATE_PACKAGE_NAME"
|
internal const val PLACEHOLDER = "TEMPLATE_PACKAGE_NAME"
|
||||||
|
|
||||||
internal const val NAME_MOUNT_SCRIPT = "mount.sh"
|
// utility commands
|
||||||
|
private const val COMMAND_CHMOD_MOUNT = "chmod +x"
|
||||||
internal const val PATH_DATA = "/data/adb/revanced/"
|
internal const val COMMAND_PID_OF = "pidof -s"
|
||||||
internal const val PATH_INIT_PUSH = "/sdcard/revanced"
|
internal const val COMMAND_CREATE_DIR = "mkdir -p"
|
||||||
|
|
||||||
internal const val COMMAND_PID_OF = "pidof -s "
|
|
||||||
internal const val COMMAND_CREATE_DIR = "mkdir -p "
|
|
||||||
internal const val COMMAND_MOVE_BASE = "mv $PATH_INIT_PUSH $PATH_DATA/base.apk"
|
|
||||||
internal const val COMMAND_MOVE_MOUNT = "mv $PATH_INIT_PUSH $PATH_DATA/$NAME_MOUNT_SCRIPT"
|
|
||||||
internal const val COMMAND_CHMOD_MOUNT = "chmod +x $PATH_DATA"
|
|
||||||
internal const val COMMAND_MOUNT = "./$PATH_DATA/$NAME_MOUNT_SCRIPT"
|
|
||||||
internal const val COMMAND_UNMOUNT = "umount -l $(pm path $PLACEHOLDER | grep base | sed 's/package://g')"
|
|
||||||
internal const val COMMAND_LOGCAT = "logcat -c && logcat --pid=$($COMMAND_PID_OF $PLACEHOLDER)"
|
internal const val COMMAND_LOGCAT = "logcat -c && logcat --pid=$($COMMAND_PID_OF $PLACEHOLDER)"
|
||||||
internal const val COMMAND_RUN_APP = "monkey -p $PLACEHOLDER 1"
|
internal const val COMMAND_RESTART = "monkey -p $PLACEHOLDER 1 && kill ${'$'}($COMMAND_PID_OF $PLACEHOLDER)"
|
||||||
internal const val COMMAND_KILL_APP = "kill \$($COMMAND_PID_OF $PLACEHOLDER)"
|
|
||||||
|
|
||||||
|
// default mount file name
|
||||||
|
private const val NAME_MOUNT_SCRIPT = "mount_$PLACEHOLDER.sh"
|
||||||
|
|
||||||
|
// initial directory to push files to via adb push
|
||||||
|
internal const val PATH_INIT_PUSH = "/sdcard/revanced.delete"
|
||||||
|
|
||||||
|
// revanced path
|
||||||
|
internal const val PATH_REVANCED = "/data/adb/revanced/"
|
||||||
|
|
||||||
|
// revanced apk path
|
||||||
|
private const val PATH_REVANCED_APP = "$PATH_REVANCED$PLACEHOLDER.apk"
|
||||||
|
|
||||||
|
// (un)mount script paths
|
||||||
|
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_INSTALL_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"
|
||||||
|
|
||||||
|
// 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
|
||||||
|
while read line; do echo ${'$'}{line} | grep $PLACEHOLDER | awk '{print ${'$'}2}' | xargs umount -l; done< /proc/mounts
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
// mount script
|
||||||
internal val CONTENT_MOUNT_SCRIPT =
|
internal val CONTENT_MOUNT_SCRIPT =
|
||||||
"""
|
"""
|
||||||
base_path="$PATH_DATA/base.apk"
|
#!/system/bin/sh
|
||||||
|
while [ "${'$'}(getprop sys.boot_completed | tr -d '\r')" != "1" ]; do sleep 1; done
|
||||||
|
|
||||||
|
base_path="$PATH_REVANCED_APP"
|
||||||
stock_path=${'$'}{ pm path $PLACEHOLDER | grep base | sed 's/package://g' }
|
stock_path=${'$'}{ pm path $PLACEHOLDER | grep base | sed 's/package://g' }
|
||||||
umount -l ${'$'}stock_path
|
|
||||||
rm ${'$'}base_path
|
|
||||||
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
|
|
||||||
mount -o bind ${'$'}base_path ${'$'}stock_path
|
mount -o bind ${'$'}base_path ${'$'}stock_path
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user