mirror of
https://github.com/YTVanced/VancedManager
synced 2024-11-22 11:15:10 +00:00
packagemanager code cleanup
This commit is contained in:
parent
a1662bab5a
commit
9b21751957
4 changed files with 128 additions and 93 deletions
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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,29 +156,26 @@ class NonrootPackageManager(
|
||||||
intentFlags
|
intentFlags
|
||||||
).intentSender
|
).intentSender
|
||||||
|
|
||||||
val sessionId: Int
|
val sessionId = tripleUnionTryCatch<IOException, SecurityException, IllegalArgumentException, Int>(
|
||||||
try {
|
onCatch = {
|
||||||
sessionId = packageInstaller.createSession(sessionParams)
|
return PackageManagerResult.Error(
|
||||||
} catch (e: IOException) {
|
error = PackageManagerError.SESSION_FAILED_CREATE,
|
||||||
return PackageManagerResult.Error(
|
message = it.stackTraceToString()
|
||||||
status = PackageManagerStatus.SESSION_FAILED_CREATE,
|
)
|
||||||
message = e.stackTraceToString()
|
}
|
||||||
)
|
) {
|
||||||
|
packageInstaller.createSession(sessionParams)
|
||||||
}
|
}
|
||||||
|
|
||||||
val session: PackageInstaller.Session
|
val session = doubleUnionTryCatch<IOException, SecurityException, PackageInstaller.Session>(
|
||||||
try {
|
onCatch = {
|
||||||
session = packageInstaller.openSession(sessionId)
|
return PackageManagerResult.Error(
|
||||||
} catch (e: IOException) {
|
error = PackageManagerError.SESSION_FAILED_CREATE,
|
||||||
return PackageManagerResult.Error(
|
message = it.stackTraceToString()
|
||||||
status = PackageManagerStatus.SESSION_FAILED_OPEN,
|
)
|
||||||
message = e.stackTraceToString()
|
}
|
||||||
)
|
) {
|
||||||
} catch (e: SecurityException) {
|
packageInstaller.openSession(sessionId)
|
||||||
return PackageManagerResult.Error(
|
|
||||||
status = PackageManagerStatus.SESSION_FAILED_OPEN,
|
|
||||||
message = e.stackTraceToString()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -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 }
|
||||||
|
|
||||||
|
|
32
app/src/main/java/com/vanced/manager/util/Safety.kt
Normal file
32
app/src/main/java/com/vanced/manager/util/Safety.kt
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue