Compare commits

..

3 Commits

Author SHA1 Message Date
oSumAtrIX
d97e792d81 Apply suggestions from code review 2025-05-28 21:34:56 +02:00
Jeff Jankowski
2a3408599b Wrap dex file stream with use block 2025-05-27 13:12:51 -07:00
Jeff Jankowski
38ff123296 creating dex file stream on-demand instead of passing it around 2025-05-14 20:24:58 -07:00
10 changed files with 19 additions and 45 deletions

View File

@@ -1,17 +1,3 @@
# [3.2.0-dev.1](https://github.com/ReVanced/revanced-library/compare/v3.1.1-dev.1...v3.2.0-dev.1) (2025-05-27)
### Features
* Request the update ownership enforcement ([#71](https://github.com/ReVanced/revanced-library/issues/71)) ([be0f6bf](https://github.com/ReVanced/revanced-library/commit/be0f6bf247461d16fbf649a9f2dc6facbb5b0c93))
## [3.1.1-dev.1](https://github.com/ReVanced/revanced-library/compare/v3.1.0...v3.1.1-dev.1) (2025-05-02)
### Bug Fixes
* Interpret package name as a string instead of Regex when using grep ([#68](https://github.com/ReVanced/revanced-library/issues/68)) ([254f36d](https://github.com/ReVanced/revanced-library/commit/254f36d03cc8fd3e2508a5e8f69bb5c8e1eb9775))
# [3.1.0](https://github.com/ReVanced/revanced-library/compare/v3.0.2...v3.1.0) (2024-11-27) # [3.1.0](https://github.com/ReVanced/revanced-library/compare/v3.0.2...v3.1.0) (2024-11-27)

View File

@@ -1,4 +1,4 @@
version = 3.2.0-dev.1 version = 3.1.0
#Gradle #Gradle
org.gradle.jvmargs = -Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options="-Xmx2048M" org.gradle.jvmargs = -Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options="-Xmx2048M"
org.gradle.caching = true org.gradle.caching = true

View File

@@ -4,7 +4,7 @@ bcpkix-jdk18on = "1.77"
binary-compatibility-validator = "0.15.1" binary-compatibility-validator = "0.15.1"
core-ktx = "1.15.0" core-ktx = "1.15.0"
guava = "33.2.1-jre" guava = "33.2.1-jre"
jadb = "1.2.1.1" jadb = "1.2.1"
kotlin = "2.0.20" kotlin = "2.0.20"
kotlinx-coroutines = "1.8.1" kotlinx-coroutines = "1.8.1"
kotlinx-serialization = "1.7.1" kotlinx-serialization = "1.7.1"

View File

@@ -8,7 +8,6 @@ import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.pm.PackageInstaller import android.content.pm.PackageInstaller
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import app.revanced.library.installation.installer.Installer.Apk import app.revanced.library.installation.installer.Installer.Apk
import java.io.Closeable import java.io.Closeable
@@ -86,13 +85,10 @@ class LocalInstaller(
override fun close() = context.unregisterReceiver(broadcastReceiver) override fun close() = context.unregisterReceiver(broadcastReceiver)
@SuppressLint("MissingPermission")
companion object { companion object {
private val sessionParams = PackageInstaller.SessionParams( private val sessionParams = PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL, PackageInstaller.SessionParams.MODE_FULL_INSTALL,
).apply { ).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
setRequestUpdateOwnership(true)
setInstallReason(PackageManager.INSTALL_REASON_USER) setInstallReason(PackageManager.INSTALL_REASON_USER)
} }

View File

@@ -54,6 +54,7 @@ object ApkUtils {
ZFile.openReadWrite(apkFile, zFileOptions).use { targetApkZFile -> ZFile.openReadWrite(apkFile, zFileOptions).use { targetApkZFile ->
dexFiles.forEach { dexFile -> dexFiles.forEach { dexFile ->
targetApkZFile.add(dexFile.name, dexFile.stream) targetApkZFile.add(dexFile.name, dexFile.stream)
dexFile.stream.close()
} }
resources?.let { resources -> resources?.let { resources ->

View File

@@ -35,7 +35,7 @@ class AdbShellCommandRunner : ShellCommandRunner {
override fun runCommand(command: String) = device.shellProcessBuilder(command).start().let { process -> override fun runCommand(command: String) = device.shellProcessBuilder(command).start().let { process ->
object : RunResult { object : RunResult {
override val exitCode by lazy { process.waitFor() } override val exitCode by lazy { process.waitFor() }
override val output by lazy { process.inputStream.bufferedReader().readText().removeSuffix("\n") } override val output by lazy { process.inputStream.bufferedReader().readText() }
override val error by lazy { process.errorStream.bufferedReader().readText() } override val error by lazy { process.errorStream.bufferedReader().readText() }
override fun waitFor() { override fun waitFor() {
@@ -44,7 +44,7 @@ class AdbShellCommandRunner : ShellCommandRunner {
} }
} }
override fun hasRootPermission(): Boolean = invoke("su -c whoami").exitCode == 0 override fun hasRootPermission(): Boolean = invoke("whoami").exitCode == 0
override fun write(content: InputStream, targetFilePath: String) = override fun write(content: InputStream, targetFilePath: String) =
device.push(content, System.currentTimeMillis(), 644, RemoteFile(targetFilePath)) device.push(content, System.currentTimeMillis(), 644, RemoteFile(targetFilePath))

View File

@@ -55,5 +55,5 @@ abstract class ShellCommandRunner internal constructor() {
*/ */
internal operator fun invoke( internal operator fun invoke(
command: String, command: String,
) = runCommand(command) ) = runCommand("su -c \'$command\'")
} }

View File

@@ -1,13 +1,11 @@
package app.revanced.library.installation.installer package app.revanced.library.installation.installer
import app.revanced.library.installation.command.AdbShellCommandRunner import app.revanced.library.installation.command.AdbShellCommandRunner
import app.revanced.library.installation.command.ShellCommandRunner
import app.revanced.library.installation.installer.Constants.GET_SDK_VERSION
import app.revanced.library.installation.installer.Constants.INSTALLED_APK_PATH import app.revanced.library.installation.installer.Constants.INSTALLED_APK_PATH
import app.revanced.library.installation.installer.Installer.Apk
import se.vidstige.jadb.JadbException import se.vidstige.jadb.JadbException
import se.vidstige.jadb.managers.Package import se.vidstige.jadb.managers.Package
import se.vidstige.jadb.managers.PackageManager import se.vidstige.jadb.managers.PackageManager
import se.vidstige.jadb.managers.PackageManager.UPDATE_OWNERSHIP
/** /**
* [AdbInstaller] for installing and uninstalling [Apk] files using ADB. * [AdbInstaller] for installing and uninstalling [Apk] files using ADB.
@@ -19,23 +17,18 @@ import se.vidstige.jadb.managers.PackageManager.UPDATE_OWNERSHIP
class AdbInstaller( class AdbInstaller(
deviceSerial: String? = null, deviceSerial: String? = null,
) : Installer<AdbInstallerResult, Installation>() { ) : Installer<AdbInstallerResult, Installation>() {
private val shellCommandRunner: ShellCommandRunner private val device = getDevice(deviceSerial, logger)
private val packageManager: PackageManager private val adbShellCommandRunner = AdbShellCommandRunner(device)
private val packageManager = PackageManager(device)
init { init {
val device = getDevice(deviceSerial, logger)
shellCommandRunner = AdbShellCommandRunner(device)
packageManager = PackageManager(device)
logger.fine("Connected to $deviceSerial") logger.fine("Connected to $deviceSerial")
} }
override suspend fun install(apk: Apk): AdbInstallerResult { override suspend fun install(apk: Apk): AdbInstallerResult {
return runPackageManager { logger.info("Installing ${apk.file.name}")
val sdkVersion = shellCommandRunner(GET_SDK_VERSION).output.toInt()
if (sdkVersion < 34) install(apk.file) return runPackageManager { install(apk.file) }
else installWithOptions(apk.file, listOf(UPDATE_OWNERSHIP))
}
} }
override suspend fun uninstall(packageName: String): AdbInstallerResult { override suspend fun uninstall(packageName: String): AdbInstallerResult {
@@ -46,7 +39,7 @@ class AdbInstaller(
override suspend fun getInstallation(packageName: String): Installation? = packageManager.packages.find { override suspend fun getInstallation(packageName: String): Installation? = packageManager.packages.find {
it.toString() == packageName it.toString() == packageName
}?.let { Installation(shellCommandRunner(INSTALLED_APK_PATH).output) } }?.let { Installation(adbShellCommandRunner(INSTALLED_APK_PATH).output) }
private fun runPackageManager(block: PackageManager.() -> Unit) = try { private fun runPackageManager(block: PackageManager.() -> Unit) = try {
packageManager.run(block) packageManager.run(block)

View File

@@ -4,28 +4,26 @@ package app.revanced.library.installation.installer
internal object Constants { internal object Constants {
const val PLACEHOLDER = "PLACEHOLDER" const val PLACEHOLDER = "PLACEHOLDER"
const val SELINUX_CONTEXT = "u:object_r:apk_data_file:s0"
const val TMP_FILE_PATH = "/data/local/tmp/revanced.tmp" const val TMP_FILE_PATH = "/data/local/tmp/revanced.tmp"
const val MOUNT_PATH = "/data/adb/revanced/" const val MOUNT_PATH = "/data/adb/revanced/"
const val MOUNTED_APK_PATH = "$MOUNT_PATH$PLACEHOLDER.apk" const val MOUNTED_APK_PATH = "$MOUNT_PATH$PLACEHOLDER.apk"
const val MOUNT_SCRIPT_PATH = "/data/adb/service.d/mount_revanced_$PLACEHOLDER.sh" const val MOUNT_SCRIPT_PATH = "/data/adb/service.d/mount_revanced_$PLACEHOLDER.sh"
const val EXISTS = "[[ -f $PLACEHOLDER ]] || exit 1" const val EXISTS = "[[ -f $PLACEHOLDER ]] || exit 1"
const val MOUNT_GREP = "grep -F $PLACEHOLDER /proc/mounts" const val MOUNT_GREP = "grep $PLACEHOLDER /proc/mounts"
const val DELETE = "rm -rf $PLACEHOLDER" const val DELETE = "rm -rf $PLACEHOLDER"
const val CREATE_DIR = "mkdir -p" const val CREATE_DIR = "mkdir -p"
const val RESTART = "am start -S $PLACEHOLDER" const val RESTART = "am start -S $PLACEHOLDER"
const val KILL = "am force-stop $PLACEHOLDER" const val KILL = "am force-stop $PLACEHOLDER"
const val INSTALLED_APK_PATH = "pm path $PLACEHOLDER" const val INSTALLED_APK_PATH = "pm path $PLACEHOLDER"
const val CREATE_INSTALLATION_PATH = "$CREATE_DIR $MOUNT_PATH" const val CREATE_INSTALLATION_PATH = "$CREATE_DIR $MOUNT_PATH"
const val GET_SDK_VERSION = "getprop ro.build.version.sdk"
const val MOUNT_APK = const val MOUNT_APK =
"base_path=\"$MOUNTED_APK_PATH\" && " + "base_path=\"$MOUNTED_APK_PATH\" && " +
"mv $TMP_FILE_PATH \$base_path && " + "mv $TMP_FILE_PATH \$base_path && " +
"chmod 644 \$base_path && " + "chmod 644 \$base_path && " +
"chown system:system \$base_path && " + "chown system:system \$base_path && " +
"chcon $SELINUX_CONTEXT \$base_path" "chcon u:object_r:apk_data_file:s0 \$base_path"
const val UMOUNT = const val UMOUNT =
"grep $PLACEHOLDER /proc/mounts | " + "grep $PLACEHOLDER /proc/mounts | " +
@@ -54,7 +52,7 @@ internal object Constants {
base_path="$MOUNTED_APK_PATH" base_path="$MOUNTED_APK_PATH"
chcon $SELINUX_CONTEXT ${'$'}base_path chcon u:object_r:apk_data_file:s0 ${'$'}base_path
# Use Magisk mirror, if possible. # Use Magisk mirror, if possible.
if command -v magisk &> /dev/null; then if command -v magisk &> /dev/null; then

View File

@@ -100,7 +100,7 @@ abstract class RootInstaller internal constructor(
/** /**
* Runs a command on the device. * Runs a command on the device.
*/ */
protected operator fun String.invoke() = shellCommandRunner("su -c \'$this\'") protected operator fun String.invoke() = shellCommandRunner(this)
/** /**
* Moves the given file to the given [targetFilePath]. * Moves the given file to the given [targetFilePath].