Fix: Silent install is user-profile aware (Closes #43)

Add: Root uninstall
This commit is contained in:
LooKeR 2021-10-23 10:51:27 +05:30
parent 081a959e09
commit e96fea6b8d
2 changed files with 37 additions and 28 deletions

View File

@ -30,6 +30,7 @@ import com.looker.droidify.utility.RxUtils
import com.looker.droidify.utility.Utils import com.looker.droidify.utility.Utils
import com.looker.droidify.utility.Utils.startPackageInstaller import com.looker.droidify.utility.Utils.startPackageInstaller
import com.looker.droidify.utility.Utils.startUpdate import com.looker.droidify.utility.Utils.startUpdate
import com.looker.droidify.utility.Utils.uninstallPackage
import com.looker.droidify.utility.extension.android.* import com.looker.droidify.utility.extension.android.*
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.core.Observable
@ -41,7 +42,6 @@ import kotlinx.coroutines.launch
class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks { class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
companion object { companion object {
private const val EXTRA_PACKAGE_NAME = "packageName" private const val EXTRA_PACKAGE_NAME = "packageName"
private const val STATE_LAYOUT_MANAGER = "layoutManager" private const val STATE_LAYOUT_MANAGER = "layoutManager"
private const val STATE_ADAPTER = "adapter" private const val STATE_ADAPTER = "adapter"
} }
@ -433,13 +433,12 @@ class ProductFragment() : ScreenFragment(), ProductAdapter.Callbacks {
) )
} }
ProductAdapter.Action.UNINSTALL -> { ProductAdapter.Action.UNINSTALL -> {
// TODO Handle deprecation lifecycleScope.launch(Dispatchers.IO) {
@Suppress("DEPRECATION") this@ProductFragment.context?.uninstallPackage(
startActivity( packageName
Intent(Intent.ACTION_UNINSTALL_PACKAGE)
.setData(Uri.parse("package:$packageName"))
) )
} }
}
ProductAdapter.Action.CANCEL -> { ProductAdapter.Action.CANCEL -> {
val binder = downloadConnection.binder val binder = downloadConnection.binder
if (downloading && binder != null) { if (downloading && binder != null) {

View File

@ -1,14 +1,11 @@
package com.looker.droidify.utility package com.looker.droidify.utility
import android.animation.ValueAnimator
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
import android.content.pm.Signature import android.content.pm.Signature
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.provider.Settings
import android.util.Log import android.util.Log
import com.looker.droidify.R import com.looker.droidify.R
import com.looker.droidify.content.Cache import com.looker.droidify.content.Cache
@ -93,25 +90,14 @@ object Utils {
} }
} }
fun areAnimationsEnabled(context: Context): Boolean { suspend fun Context.startPackageInstaller(cacheFileName: String) {
return if (Android.sdk(26)) {
ValueAnimator.areAnimatorsEnabled()
} else {
Settings.Global.getFloat(
context.contentResolver,
Settings.Global.ANIMATOR_DURATION_SCALE,
1f
) != 0f
}
}
suspend fun Activity.startPackageInstaller(cacheFileName: String) {
val file = Cache.getReleaseFile(this, cacheFileName) val file = Cache.getReleaseFile(this, cacheFileName)
if (Preferences[Preferences.Key.RootPermission]) { if (Preferences[Preferences.Key.RootPermission]) {
val commandBuilder = StringBuilder() val commandBuilder = StringBuilder()
val verifyState = getVerifyState() val verifyState = getVerifyState
val userId = getCurrentUserState()
if (verifyState == "1") commandBuilder.append("settings put global verifier_verify_adb_installs 0 ; ") if (verifyState == "1") commandBuilder.append("settings put global verifier_verify_adb_installs 0 ; ")
commandBuilder.append(getPackageInstallCommand(file)) commandBuilder.append(getPackageInstallCommand(file, userId))
commandBuilder.append(" ; settings put global verifier_verify_adb_installs $verifyState") commandBuilder.append(" ; settings put global verifier_verify_adb_installs $verifyState")
withContext(Dispatchers.IO) { withContext(Dispatchers.IO) {
launch { launch {
@ -141,6 +127,22 @@ object Utils {
} }
} }
suspend fun Context.uninstallPackage(packageName: String) {
if (Preferences[Preferences.Key.RootPermission]) {
val commandBuilder = StringBuilder()
val userId = getCurrentUserState()
commandBuilder.append(getPackageUninstallCommand(packageName, userId))
withContext(Dispatchers.IO) { launch { Shell.su(commandBuilder.toString()).exec() } }
} else {
// TODO Handle deprecation
@Suppress("DEPRECATION")
startActivity(
Intent(Intent.ACTION_UNINSTALL_PACKAGE)
.setData(Uri.parse("package:$packageName"))
)
}
}
fun startUpdate( fun startUpdate(
packageName: String, packageName: String,
installedItem: InstalledItem?, installedItem: InstalledItem?,
@ -170,10 +172,18 @@ object Utils {
} else Unit } else Unit
} }
private fun getPackageInstallCommand(cacheFile: File): String = private fun getPackageInstallCommand(cacheFile: File, userId: String = "0"): String =
"cat \"${cacheFile.absolutePath}\" | pm install -t -r -S ${cacheFile.length()}" "cat \"${cacheFile.absolutePath}\" | pm install --user $userId -t -r -S ${cacheFile.length()}"
private fun getVerifyState(): String = private fun getPackageUninstallCommand(packageName: String, userId: String = "0"): String =
"cat \"$packageName\" | pm uninstall --user $userId $packageName"
private fun getCurrentUserState(): String =
if (Android.sdk(25)) Shell.su("am get-current-user").exec().out[0]
else Shell.su("dumpsys activity | grep mCurrentUser").exec().out[0].trim()
.removePrefix("mCurrentUser=")
private val getVerifyState: String =
Shell.sh("settings get global verifier_verify_adb_installs").exec().out[0] Shell.sh("settings get global verifier_verify_adb_installs").exec().out[0]
private fun quote(string: String) = private fun quote(string: String) =