0
0
Fork 0
mirror of https://github.com/YTVanced/VancedManager synced 2024-11-22 11:15:10 +00:00

packagemanager code cleanup

This commit is contained in:
X1nto 2022-03-11 19:53:34 +04:00
parent a1662bab5a
commit 9b21751957
4 changed files with 128 additions and 93 deletions

View file

@ -4,7 +4,7 @@ import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.io.SuFile import com.topjohnwu.superuser.io.SuFile
import com.topjohnwu.superuser.io.SuFileOutputStream import com.topjohnwu.superuser.io.SuFileOutputStream
import com.vanced.manager.repository.manager.PackageManagerResult import com.vanced.manager.repository.manager.PackageManagerResult
import com.vanced.manager.repository.manager.PackageManagerStatus import com.vanced.manager.repository.manager.PackageManagerError
import com.vanced.manager.repository.manager.getEnumForInstallFailed import com.vanced.manager.repository.manager.getEnumForInstallFailed
import com.vanced.manager.util.errString import com.vanced.manager.util.errString
import com.vanced.manager.util.outString import com.vanced.manager.util.outString
@ -17,7 +17,7 @@ object PMRoot {
val apk = File(apkPath) val apk = File(apkPath)
val tmpApk = copyApkToTemp(apk).getOrElse { exception -> val tmpApk = copyApkToTemp(apk).getOrElse { exception ->
return PackageManagerResult.Error( return PackageManagerResult.Error(
PackageManagerStatus.SESSION_FAILED_COPY, PackageManagerError.SESSION_FAILED_COPY,
exception.stackTraceToString() exception.stackTraceToString()
) )
} }
@ -38,18 +38,18 @@ object PMRoot {
val installCreate = Shell.su("pm", "install-create", "-r").exec() val installCreate = Shell.su("pm", "install-create", "-r").exec()
if (!installCreate.isSuccess) if (!installCreate.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.SESSION_FAILED_CREATE, installCreate.errString) return PackageManagerResult.Error(PackageManagerError.SESSION_FAILED_CREATE, installCreate.errString)
val sessionId = installCreate.outString val sessionId = installCreate.outString
if (sessionId.toIntOrNull() == null) if (sessionId.toIntOrNull() == null)
return PackageManagerResult.Error(PackageManagerStatus.SESSION_INVALID_ID, installCreate.errString) return PackageManagerResult.Error(PackageManagerError.SESSION_INVALID_ID, installCreate.errString)
for (apkPath in apkPaths) { for (apkPath in apkPaths) {
val apk = File(apkPath) val apk = File(apkPath)
val tmpApk = copyApkToTemp(apk).getOrElse { exception -> val tmpApk = copyApkToTemp(apk).getOrElse { exception ->
return PackageManagerResult.Error( return PackageManagerResult.Error(
PackageManagerStatus.SESSION_FAILED_COPY, PackageManagerError.SESSION_FAILED_COPY,
exception.stackTraceToString() exception.stackTraceToString()
) )
} }
@ -61,7 +61,7 @@ object PMRoot {
tmpApk.delete() tmpApk.delete()
if (!installWrite.isSuccess) if (!installWrite.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.SESSION_FAILED_WRITE, installWrite.errString) return PackageManagerResult.Error(PackageManagerError.SESSION_FAILED_WRITE, installWrite.errString)
} }
val installCommit = Shell.su("pm", "install-commit", sessionId).exec() val installCommit = Shell.su("pm", "install-commit", sessionId).exec()
@ -78,7 +78,7 @@ object PMRoot {
val uninstall = Shell.su("pm", "uninstall", pkg).exec() val uninstall = Shell.su("pm", "uninstall", pkg).exec()
if (!uninstall.isSuccess) if (!uninstall.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.UNINSTALL_FAILED, uninstall.errString) return PackageManagerResult.Error(PackageManagerError.UNINSTALL_FAILED, uninstall.errString)
return PackageManagerResult.Success(null) return PackageManagerResult.Success(null)
} }
@ -89,7 +89,7 @@ object PMRoot {
if (!setInstaller.isSuccess) if (!setInstaller.isSuccess)
return PackageManagerResult.Error( return PackageManagerResult.Error(
PackageManagerStatus.SET_FAILED_INSTALLER, PackageManagerError.SET_FAILED_INSTALLER,
setInstaller.errString setInstaller.errString
) )
@ -100,7 +100,7 @@ object PMRoot {
val stopApp = Shell.su("am", "force-stop", pkg).exec() val stopApp = Shell.su("am", "force-stop", pkg).exec()
if (!stopApp.isSuccess) if (!stopApp.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.APP_FAILED_FORCE_STOP, stopApp.errString) return PackageManagerResult.Error(PackageManagerError.APP_FAILED_FORCE_STOP, stopApp.errString)
return PackageManagerResult.Success(null) return PackageManagerResult.Success(null)
} }
@ -111,7 +111,7 @@ object PMRoot {
if (!dumpsys.isSuccess) if (!dumpsys.isSuccess)
return PackageManagerResult.Error( return PackageManagerResult.Error(
PackageManagerStatus.GET_FAILED_PACKAGE_VERSION_NAME, PackageManagerError.GET_FAILED_PACKAGE_VERSION_NAME,
dumpsys.errString dumpsys.errString
) )
@ -124,7 +124,7 @@ object PMRoot {
if (!dumpsys.isSuccess) if (!dumpsys.isSuccess)
return PackageManagerResult.Error( return PackageManagerResult.Error(
PackageManagerStatus.GET_FAILED_PACKAGE_VERSION_CODE, PackageManagerError.GET_FAILED_PACKAGE_VERSION_CODE,
dumpsys.errString dumpsys.errString
) )
@ -139,7 +139,7 @@ object PMRoot {
val dumpsys = Shell.su("dumpsys", "package", pkg, "|", "grep", keyword).exec() val dumpsys = Shell.su("dumpsys", "package", pkg, "|", "grep", keyword).exec()
if (!dumpsys.isSuccess) if (!dumpsys.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.GET_FAILED_PACKAGE_DIR, dumpsys.errString) return PackageManagerResult.Error(PackageManagerError.GET_FAILED_PACKAGE_DIR, dumpsys.errString)
return PackageManagerResult.Success(dumpsys.outString.removePrefix(keyword)) return PackageManagerResult.Success(dumpsys.outString.removePrefix(keyword))
} }

View file

@ -6,7 +6,7 @@ import com.topjohnwu.superuser.io.SuFileOutputStream
import com.vanced.manager.io.ManagerSuFile import com.vanced.manager.io.ManagerSuFile
import com.vanced.manager.io.SUIOException import com.vanced.manager.io.SUIOException
import com.vanced.manager.repository.manager.PackageManagerResult import com.vanced.manager.repository.manager.PackageManagerResult
import com.vanced.manager.repository.manager.PackageManagerStatus import com.vanced.manager.repository.manager.PackageManagerError
import com.vanced.manager.util.errString import com.vanced.manager.util.errString
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
@ -27,14 +27,14 @@ object Patcher {
val copyServiceDScript = copyScriptToDestination(postFsDataScript, postFsDataScriptPath) val copyServiceDScript = copyScriptToDestination(postFsDataScript, postFsDataScriptPath)
if (copyServiceDScript.isFailure) if (copyServiceDScript.isFailure)
return PackageManagerResult.Error( return PackageManagerResult.Error(
PackageManagerStatus.SCRIPT_FAILED_SETUP_POST_FS, PackageManagerError.SCRIPT_FAILED_SETUP_POST_FS,
copyServiceDScript.exceptionOrNull()!!.stackTraceToString() copyServiceDScript.exceptionOrNull()!!.stackTraceToString()
) )
val copyPostFsDataScript = copyScriptToDestination(serviceDScript, serviceDScriptPath) val copyPostFsDataScript = copyScriptToDestination(serviceDScript, serviceDScriptPath)
if (copyPostFsDataScript.isFailure) if (copyPostFsDataScript.isFailure)
return PackageManagerResult.Error( return PackageManagerResult.Error(
PackageManagerStatus.SCRIPT_FAILED_SETUP_SERVICE_D, PackageManagerError.SCRIPT_FAILED_SETUP_SERVICE_D,
copyPostFsDataScript.exceptionOrNull()!!.stackTraceToString() copyPostFsDataScript.exceptionOrNull()!!.stackTraceToString()
) )
@ -55,16 +55,16 @@ object Patcher {
try { try {
patchApk.copyTo(newPatchApk) patchApk.copyTo(newPatchApk)
} catch (e: IOException) { } catch (e: IOException) {
return PackageManagerResult.Error(PackageManagerStatus.PATCH_FAILED_COPY, e.stackTraceToString()) return PackageManagerResult.Error(PackageManagerError.PATCH_FAILED_COPY, e.stackTraceToString())
} }
val chmod = Shell.su("chmod", "644", newPatchPath).exec() val chmod = Shell.su("chmod", "644", newPatchPath).exec()
if (!chmod.isSuccess) if (!chmod.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.PATCH_FAILED_CHMOD, chmod.errString) return PackageManagerResult.Error(PackageManagerError.PATCH_FAILED_CHMOD, chmod.errString)
val chown = Shell.su("chown", "system:system", newPatchPath).exec() val chown = Shell.su("chown", "system:system", newPatchPath).exec()
if (!chmod.isSuccess) if (!chmod.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.PATCH_FAILED_CHOWN, chown.errString) return PackageManagerResult.Error(PackageManagerError.PATCH_FAILED_CHOWN, chown.errString)
return PackageManagerResult.Success(null) return PackageManagerResult.Success(null)
} }
@ -72,7 +72,7 @@ object Patcher {
fun chconPatch(app: String): PackageManagerResult<Nothing> { fun chconPatch(app: String): PackageManagerResult<Nothing> {
val chcon = Shell.su("chcon u:object_r:apk_data_file:s0 ${getAppPatchPath(app)}").exec() val chcon = Shell.su("chcon u:object_r:apk_data_file:s0 ${getAppPatchPath(app)}").exec()
if (!chcon.isSuccess) if (!chcon.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.PATCH_FAILED_CHCON, chcon.errString) return PackageManagerResult.Error(PackageManagerError.PATCH_FAILED_CHCON, chcon.errString)
return PackageManagerResult.Success(null) return PackageManagerResult.Success(null)
} }
@ -82,13 +82,13 @@ object Patcher {
Shell.su("""for i in ${'$'}(ls /data/app/ | grep $stockPackage | tr " "); do umount -l "/data/app/${"$"}i/base.apk"; done """) Shell.su("""for i in ${'$'}(ls /data/app/ | grep $stockPackage | tr " "); do umount -l "/data/app/${"$"}i/base.apk"; done """)
.exec() .exec()
if (!umount.isSuccess) if (!umount.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.LINK_FAILED_UNMOUNT, umount.errString) return PackageManagerResult.Error(PackageManagerError.LINK_FAILED_UNMOUNT, umount.errString)
val mount = val mount =
Shell.su("su", "-mm", "-c", """"mount -o bind ${getAppPatchPath(app)} $stockPath"""") Shell.su("su", "-mm", "-c", """"mount -o bind ${getAppPatchPath(app)} $stockPath"""")
.exec() .exec()
if (!mount.isSuccess) if (!mount.isSuccess)
return PackageManagerResult.Error(PackageManagerStatus.LINK_FAILED_MOUNT, mount.errString) return PackageManagerResult.Error(PackageManagerError.LINK_FAILED_MOUNT, mount.errString)
return PackageManagerResult.Success(null) return PackageManagerResult.Success(null)
} }
@ -136,9 +136,9 @@ private fun cleanPatchFiles(
patchPath: String, patchPath: String,
): PackageManagerResult<Nothing> { ): PackageManagerResult<Nothing> {
val files = mapOf( val files = mapOf(
postFsPath to PackageManagerStatus.SCRIPT_FAILED_DESTROY_POST_FS, postFsPath to PackageManagerError.SCRIPT_FAILED_DESTROY_POST_FS,
serviceDPath to PackageManagerStatus.SCRIPT_FAILED_DESTROY_SERVICE_D, serviceDPath to PackageManagerError.SCRIPT_FAILED_DESTROY_SERVICE_D,
patchPath to PackageManagerStatus.PATCH_FAILED_DESTROY, patchPath to PackageManagerError.PATCH_FAILED_DESTROY,
) )
for ((filePath, errorStatusType) in files) { for ((filePath, errorStatusType) in files) {

View file

@ -12,8 +12,7 @@ import com.topjohnwu.superuser.io.SuFileInputStream
import com.topjohnwu.superuser.io.SuFileOutputStream import com.topjohnwu.superuser.io.SuFileOutputStream
import com.vanced.manager.installer.service.AppInstallService import com.vanced.manager.installer.service.AppInstallService
import com.vanced.manager.installer.service.AppUninstallService import com.vanced.manager.installer.service.AppUninstallService
import com.vanced.manager.util.SuException import com.vanced.manager.util.*
import com.vanced.manager.util.awaitOutputOrThrow
import java.io.File import java.io.File
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.IOException import java.io.IOException
@ -53,10 +52,11 @@ class NonrootPackageManager(
} else { } else {
packageInfo.versionCode packageInfo.versionCode
} }
PackageManagerResult.Success(versionCode) PackageManagerResult.Success(versionCode)
} catch (e: android.content.pm.PackageManager.NameNotFoundException) { } catch (e: android.content.pm.PackageManager.NameNotFoundException) {
PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.GET_FAILED_PACKAGE_VERSION_CODE, error = PackageManagerError.GET_FAILED_PACKAGE_VERSION_CODE,
message = e.stackTraceToString() message = e.stackTraceToString()
) )
} }
@ -68,10 +68,11 @@ class NonrootPackageManager(
val versionName = context.packageManager val versionName = context.packageManager
.getPackageInfo(packageName, FLAG_NOTHING) .getPackageInfo(packageName, FLAG_NOTHING)
.versionName .versionName
PackageManagerResult.Success(versionName) PackageManagerResult.Success(versionName)
} catch (e: android.content.pm.PackageManager.NameNotFoundException) { } catch (e: android.content.pm.PackageManager.NameNotFoundException) {
PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.GET_FAILED_PACKAGE_VERSION_NAME, error = PackageManagerError.GET_FAILED_PACKAGE_VERSION_NAME,
message = e.stackTraceToString() message = e.stackTraceToString()
) )
} }
@ -84,10 +85,11 @@ class NonrootPackageManager(
.getPackageInfo(packageName, FLAG_NOTHING) .getPackageInfo(packageName, FLAG_NOTHING)
.applicationInfo .applicationInfo
.sourceDir .sourceDir
PackageManagerResult.Success(installationDir) PackageManagerResult.Success(installationDir)
} catch (e: android.content.pm.PackageManager.NameNotFoundException) { } catch (e: android.content.pm.PackageManager.NameNotFoundException) {
PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.GET_FAILED_PACKAGE_DIR, error = PackageManagerError.GET_FAILED_PACKAGE_DIR,
message = e.stackTraceToString() message = e.stackTraceToString()
) )
} }
@ -98,14 +100,14 @@ class NonrootPackageManager(
installerPackage: String installerPackage: String
): PackageManagerResult<Nothing> { ): PackageManagerResult<Nothing> {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.SET_FAILED_INSTALLER, error = PackageManagerError.SET_FAILED_INSTALLER,
message = "Unsupported" message = "Unsupported"
) )
} }
override suspend fun forceStop(packageName: String): PackageManagerResult<Nothing> { override suspend fun forceStop(packageName: String): PackageManagerResult<Nothing> {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.APP_FAILED_FORCE_STOP, error = PackageManagerError.APP_FAILED_FORCE_STOP,
message = "Unsupported" message = "Unsupported"
) )
} }
@ -154,30 +156,27 @@ class NonrootPackageManager(
intentFlags intentFlags
).intentSender ).intentSender
val sessionId: Int val sessionId = tripleUnionTryCatch<IOException, SecurityException, IllegalArgumentException, Int>(
try { onCatch = {
sessionId = packageInstaller.createSession(sessionParams)
} catch (e: IOException) {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_FAILED_CREATE, error = PackageManagerError.SESSION_FAILED_CREATE,
message = e.stackTraceToString() message = it.stackTraceToString()
) )
} }
) {
packageInstaller.createSession(sessionParams)
}
val session: PackageInstaller.Session val session = doubleUnionTryCatch<IOException, SecurityException, PackageInstaller.Session>(
try { onCatch = {
session = packageInstaller.openSession(sessionId)
} catch (e: IOException) {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_FAILED_OPEN, error = PackageManagerError.SESSION_FAILED_CREATE,
message = e.stackTraceToString() message = it.stackTraceToString()
)
} catch (e: SecurityException) {
return PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_FAILED_OPEN,
message = e.stackTraceToString()
) )
} }
) {
packageInstaller.openSession(sessionId)
}
try { try {
session.use { session.use {
@ -186,12 +185,12 @@ class NonrootPackageManager(
} }
} catch (e: IOException) { } catch (e: IOException) {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_FAILED_WRITE, error = PackageManagerError.SESSION_FAILED_WRITE,
message = e.stackTraceToString() message = e.stackTraceToString()
) )
} catch (e: SecurityException) { } catch (e: SecurityException) {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_FAILED_COMMIT, error = PackageManagerError.SESSION_FAILED_COMMIT,
message = e.stackTraceToString() message = e.stackTraceToString()
) )
} }
@ -236,12 +235,12 @@ class RootPackageManager : PackageManager {
PackageManagerResult.Success(versionCode) PackageManagerResult.Success(versionCode)
} catch (e: SuException) { } catch (e: SuException) {
PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.GET_FAILED_PACKAGE_VERSION_CODE, error = PackageManagerError.GET_FAILED_PACKAGE_VERSION_CODE,
message = e.stderrOut message = e.stderrOut
) )
} catch (e: java.lang.NumberFormatException) { } catch (e: java.lang.NumberFormatException) {
PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.GET_FAILED_PACKAGE_VERSION_CODE, error = PackageManagerError.GET_FAILED_PACKAGE_VERSION_CODE,
message = e.stackTraceToString() message = e.stackTraceToString()
) )
} }
@ -256,7 +255,7 @@ class RootPackageManager : PackageManager {
PackageManagerResult.Success(versionName) PackageManagerResult.Success(versionName)
} catch (e: SuException) { } catch (e: SuException) {
PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.GET_FAILED_PACKAGE_VERSION_NAME, error = PackageManagerError.GET_FAILED_PACKAGE_VERSION_NAME,
message = e.stderrOut message = e.stderrOut
) )
} }
@ -271,7 +270,7 @@ class RootPackageManager : PackageManager {
PackageManagerResult.Success(installationDir) PackageManagerResult.Success(installationDir)
} catch (e: SuException) { } catch (e: SuException) {
PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.GET_FAILED_PACKAGE_DIR, error = PackageManagerError.GET_FAILED_PACKAGE_DIR,
message = e.stderrOut message = e.stderrOut
) )
} }
@ -281,25 +280,26 @@ class RootPackageManager : PackageManager {
targetPackage: String, targetPackage: String,
installerPackage: String installerPackage: String
): PackageManagerResult<Nothing> { ): PackageManagerResult<Nothing> {
try { return try {
Shell.su("pm", "set-installer", targetPackage, installerPackage).awaitOutputOrThrow() Shell.su("pm", "set-installer", targetPackage, installerPackage).awaitOutputOrThrow()
PackageManagerResult.Success(null)
} catch (e: SuException) { } catch (e: SuException) {
return PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.SET_FAILED_INSTALLER, error = PackageManagerError.SET_FAILED_INSTALLER,
message = e.stderrOut message = e.stderrOut
) )
} }
return PackageManagerResult.Success(null)
} }
override suspend fun forceStop(packageName: String): PackageManagerResult<Nothing> { override suspend fun forceStop(packageName: String): PackageManagerResult<Nothing> {
return try { return try {
Shell.su("am", "force-stop", packageName).awaitOutputOrThrow() Shell.su("am", "force-stop", packageName).awaitOutputOrThrow()
PackageManagerResult.Success(null) PackageManagerResult.Success(null)
} catch (e: SuException) { } catch (e: SuException) {
PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.APP_FAILED_FORCE_STOP, error = PackageManagerError.APP_FAILED_FORCE_STOP,
message = e.stderrOut message = e.stderrOut
) )
} }
@ -307,38 +307,39 @@ class RootPackageManager : PackageManager {
override suspend fun installApp(apk: File): PackageManagerResult<Nothing> { override suspend fun installApp(apk: File): PackageManagerResult<Nothing> {
var tempApk: File? = null var tempApk: File? = null
try { return try {
tempApk = copyApkToTemp(apk) tempApk = copyApkToTemp(apk)
Shell.su("pm", "install", "-r", tempApk.absolutePath).awaitOutputOrThrow() Shell.su("pm", "install", "-r", tempApk.absolutePath).awaitOutputOrThrow()
PackageManagerResult.Success(null)
} catch (e: IOException) { } catch (e: IOException) {
return PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_FAILED_COPY, error = PackageManagerError.SESSION_FAILED_COPY,
message = e.stackTraceToString() message = e.stackTraceToString()
) )
} catch (e: SuException) { } catch (e: SuException) {
return PackageManagerResult.Error( PackageManagerResult.Error(
status = getEnumForInstallFailed(e.stderrOut), error = getEnumForInstallFailed(e.stderrOut),
message = e.stderrOut message = e.stderrOut
) )
} finally { } finally {
tempApk?.delete() tempApk?.delete()
} }
return PackageManagerResult.Success(null)
} }
override suspend fun installSplitApp(apks: Array<File>): PackageManagerResult<Nothing> { override suspend fun installSplitApp(apks: Array<File>): PackageManagerResult<Nothing> {
val sessionId: Int val sessionId = try {
try {
val installCreate = Shell.su("pm", "install-create", "-r").awaitOutputOrThrow() val installCreate = Shell.su("pm", "install-create", "-r").awaitOutputOrThrow()
sessionId = installCreate.toInt()
installCreate.toInt()
} catch (e: SuException) { } catch (e: SuException) {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_FAILED_CREATE, error = PackageManagerError.SESSION_FAILED_CREATE,
message = e.stderrOut message = e.stderrOut
) )
} catch (e: NumberFormatException) { } catch (e: NumberFormatException) {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_INVALID_ID, error = PackageManagerError.SESSION_INVALID_ID,
message = e.stackTraceToString() message = e.stackTraceToString()
) )
} }
@ -350,12 +351,12 @@ class RootPackageManager : PackageManager {
Shell.su("pm", "install-write", sessionId.toString(), tempApk.name, tempApk.absolutePath).awaitOutputOrThrow() Shell.su("pm", "install-write", sessionId.toString(), tempApk.name, tempApk.absolutePath).awaitOutputOrThrow()
} catch (e: SuException) { } catch (e: SuException) {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_FAILED_WRITE, error = PackageManagerError.SESSION_FAILED_WRITE,
message = e.stderrOut message = e.stderrOut
) )
} catch (e: IOException) { } catch (e: IOException) {
return PackageManagerResult.Error( return PackageManagerResult.Error(
status = PackageManagerStatus.SESSION_FAILED_COPY, error = PackageManagerError.SESSION_FAILED_COPY,
message = e.stackTraceToString() message = e.stackTraceToString()
) )
} finally { } finally {
@ -363,24 +364,26 @@ class RootPackageManager : PackageManager {
} }
} }
try { return try {
Shell.su("pm", "install-commit", sessionId.toString()).awaitOutputOrThrow() Shell.su("pm", "install-commit", sessionId.toString()).awaitOutputOrThrow()
PackageManagerResult.Success(null)
} catch (e: SuException) { } catch (e: SuException) {
return PackageManagerResult.Error( PackageManagerResult.Error(
status = getEnumForInstallFailed(e.stderrOut), error = getEnumForInstallFailed(e.stderrOut),
message = e.stderrOut message = e.stderrOut
) )
} }
return PackageManagerResult.Success(null)
} }
override suspend fun uninstallApp(packageName: String): PackageManagerResult<Nothing> { override suspend fun uninstallApp(packageName: String): PackageManagerResult<Nothing> {
return try { return try {
Shell.su("pm", "uninstall", packageName).awaitOutputOrThrow() Shell.su("pm", "uninstall", packageName).awaitOutputOrThrow()
PackageManagerResult.Success(null) PackageManagerResult.Success(null)
} catch (e: SuException) { } catch (e: SuException) {
PackageManagerResult.Error( PackageManagerResult.Error(
status = PackageManagerStatus.UNINSTALL_FAILED, error = PackageManagerError.UNINSTALL_FAILED,
message = e.stderrOut message = e.stderrOut
) )
} }
@ -409,7 +412,7 @@ class RootPackageManager : PackageManager {
} }
enum class PackageManagerStatus { enum class PackageManagerError {
SET_FAILED_INSTALLER, SET_FAILED_INSTALLER,
GET_FAILED_PACKAGE_DIR, GET_FAILED_PACKAGE_DIR,
GET_FAILED_PACKAGE_VERSION_NAME, GET_FAILED_PACKAGE_VERSION_NAME,
@ -450,22 +453,22 @@ enum class PackageManagerStatus {
SCRIPT_FAILED_DESTROY_SERVICE_D, SCRIPT_FAILED_DESTROY_SERVICE_D,
} }
fun getEnumForInstallFailed(outString: String): PackageManagerStatus { fun getEnumForInstallFailed(outString: String): PackageManagerError {
return when { return when {
outString.contains("INSTALL_FAILED_ABORTED") -> PackageManagerStatus.INSTALL_FAILED_ABORTED outString.contains("INSTALL_FAILED_ABORTED") -> PackageManagerError.INSTALL_FAILED_ABORTED
outString.contains("INSTALL_FAILED_ALREADY_EXISTS") -> PackageManagerStatus.INSTALL_FAILED_ALREADY_EXISTS outString.contains("INSTALL_FAILED_ALREADY_EXISTS") -> PackageManagerError.INSTALL_FAILED_ALREADY_EXISTS
outString.contains("INSTALL_FAILED_CPU_ABI_INCOMPATIBLE") -> PackageManagerStatus.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE outString.contains("INSTALL_FAILED_CPU_ABI_INCOMPATIBLE") -> PackageManagerError.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE
outString.contains("INSTALL_FAILED_INSUFFICIENT_STORAGE") -> PackageManagerStatus.INSTALL_FAILED_INSUFFICIENT_STORAGE outString.contains("INSTALL_FAILED_INSUFFICIENT_STORAGE") -> PackageManagerError.INSTALL_FAILED_INSUFFICIENT_STORAGE
outString.contains("INSTALL_FAILED_INVALID_APK") -> PackageManagerStatus.INSTALL_FAILED_INVALID_APK outString.contains("INSTALL_FAILED_INVALID_APK") -> PackageManagerError.INSTALL_FAILED_INVALID_APK
outString.contains("INSTALL_FAILED_VERSION_DOWNGRADE") -> PackageManagerStatus.INSTALL_FAILED_VERSION_DOWNGRADE outString.contains("INSTALL_FAILED_VERSION_DOWNGRADE") -> PackageManagerError.INSTALL_FAILED_VERSION_DOWNGRADE
outString.contains("INSTALL_PARSE_FAILED_NO_CERTIFICATES") -> PackageManagerStatus.INSTALL_FAILED_PARSE_NO_CERTIFICATES outString.contains("INSTALL_PARSE_FAILED_NO_CERTIFICATES") -> PackageManagerError.INSTALL_FAILED_PARSE_NO_CERTIFICATES
else -> PackageManagerStatus.INSTALL_FAILED_UNKNOWN else -> PackageManagerError.INSTALL_FAILED_UNKNOWN
} }
} }
sealed class PackageManagerResult<out V> { sealed class PackageManagerResult<out V> {
data class Success<out V>(val value: V?) : PackageManagerResult<V>() data class Success<out V>(val value: V?) : PackageManagerResult<V>()
data class Error(val status: PackageManagerStatus, val message: String) : PackageManagerResult<Nothing>() data class Error(val error: PackageManagerError, val message: String) : PackageManagerResult<Nothing>()
fun getValueOrNull(): V? = getOrElse { null } fun getValueOrNull(): V? = getOrElse { null }

View file

@ -0,0 +1,32 @@
package com.vanced.manager.util
//Dear reader, welcome to HELL.
//We don't kink-shame here.
inline fun <reified E1 : Exception, reified E2 : Exception, R> doubleUnionTryCatch(
onCatch: (Exception) -> R,
onTry: () -> R
): R {
return try {
onTry()
} catch (e: Exception) {
when (e) {
is E1, is E2 -> onCatch(e)
else -> throw e
}
}
}
inline fun <reified E1 : Exception, reified E2 : Exception, reified E3 : Exception, R> tripleUnionTryCatch(
onCatch: (Exception) -> R,
onTry: () -> R
): R {
return try {
onTry()
} catch (e: Exception) {
when (e) {
is E1, is E2, is E3 -> onCatch(e)
else -> throw e
}
}
}