AppInstaller: Always use intent based uninstallation of apps
This requests user's confirmation before uninstallation every time which is what we want to happen as well. Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -40,13 +40,3 @@ inline fun <reified T : Context> Context.newIntent(flags: Int, extras: Bundle):
|
|||||||
intent.putExtras(extras)
|
intent.putExtras(extras)
|
||||||
return intent
|
return intent
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Intent.applyUninstallActionCompat() {
|
|
||||||
if (isPAndAbove()) {
|
|
||||||
action = Intent.ACTION_DELETE
|
|
||||||
} else {
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
action = Intent.ACTION_UNINSTALL_PACKAGE
|
|
||||||
putExtra(Intent.EXTRA_RETURN_RESULT, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -21,9 +21,12 @@
|
|||||||
package com.aurora.store.data.installer
|
package com.aurora.store.data.installer
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.content.pm.PackageInstaller
|
import android.content.pm.PackageInstaller
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.net.Uri
|
||||||
import com.aurora.extensions.isOAndAbove
|
import com.aurora.extensions.isOAndAbove
|
||||||
|
import com.aurora.extensions.isPAndAbove
|
||||||
import com.aurora.store.BuildConfig
|
import com.aurora.store.BuildConfig
|
||||||
import com.aurora.store.R
|
import com.aurora.store.R
|
||||||
import com.aurora.store.util.PackageUtil
|
import com.aurora.store.util.PackageUtil
|
||||||
@@ -91,6 +94,20 @@ open class AppInstaller private constructor(var context: Context) {
|
|||||||
return Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED
|
return Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun uninstall(context: Context, packageName: String) {
|
||||||
|
val intent = Intent().apply {
|
||||||
|
data = Uri.fromParts("package", packageName, null)
|
||||||
|
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
if (isPAndAbove()) {
|
||||||
|
action = Intent.ACTION_DELETE
|
||||||
|
} else {
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
action = Intent.ACTION_UNINSTALL_PACKAGE
|
||||||
|
putExtra(Intent.EXTRA_RETURN_RESULT, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val choiceAndInstaller = HashMap<Int, IInstaller>()
|
val choiceAndInstaller = HashMap<Int, IInstaller>()
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ package com.aurora.store.data.installer
|
|||||||
|
|
||||||
interface IInstaller {
|
interface IInstaller {
|
||||||
fun install(packageName: String, files: List<Any>)
|
fun install(packageName: String, files: List<Any>)
|
||||||
fun uninstall(packageName: String)
|
|
||||||
|
|
||||||
fun clearQueue()
|
fun clearQueue()
|
||||||
fun isAlreadyQueued(packageName: String): Boolean
|
fun isAlreadyQueued(packageName: String): Boolean
|
||||||
fun removeFromInstallQueue(packageName: String)
|
fun removeFromInstallQueue(packageName: String)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,8 @@
|
|||||||
package com.aurora.store.data.installer
|
package com.aurora.store.data.installer
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import com.aurora.extensions.applyUninstallActionCompat
|
|
||||||
import com.aurora.store.AuroraApplication
|
import com.aurora.store.AuroraApplication
|
||||||
import com.aurora.store.BuildConfig
|
import com.aurora.store.BuildConfig
|
||||||
import com.aurora.store.data.event.InstallerEvent
|
import com.aurora.store.data.event.InstallerEvent
|
||||||
@@ -45,17 +43,6 @@ abstract class InstallerBase(protected var context: Context) : IInstaller {
|
|||||||
AuroraApplication.enqueuedInstalls.remove(packageName)
|
AuroraApplication.enqueuedInstalls.remove(packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun uninstall(packageName: String) {
|
|
||||||
val uri = Uri.fromParts("package", packageName, null)
|
|
||||||
val intent = Intent().apply {
|
|
||||||
data = uri
|
|
||||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
applyUninstallActionCompat()
|
|
||||||
}
|
|
||||||
|
|
||||||
context.startActivity(intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun postError(packageName: String, error: String?, extra: String?) {
|
open fun postError(packageName: String, error: String?, extra: String?) {
|
||||||
Log.e("Service Error :$error")
|
Log.e("Service Error :$error")
|
||||||
|
|
||||||
@@ -75,4 +62,4 @@ abstract class InstallerBase(protected var context: Context) : IInstaller {
|
|||||||
file
|
file
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,30 +57,6 @@ class RootInstaller(context: Context) : InstallerBase(context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun uninstall(packageName: String) {
|
|
||||||
if (Shell.getShell().isRoot) {
|
|
||||||
val result: Shell.Result =
|
|
||||||
Shell.cmd("pm uninstall --user 0 $packageName")
|
|
||||||
.exec()
|
|
||||||
val response = result.out
|
|
||||||
|
|
||||||
if (response[0] != "Success") {
|
|
||||||
postError(
|
|
||||||
packageName,
|
|
||||||
context.getString(R.string.installer_status_failure),
|
|
||||||
parseError(result)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
postError(
|
|
||||||
packageName,
|
|
||||||
context.getString(R.string.installer_status_failure),
|
|
||||||
context.getString(R.string.installer_root_unavailable)
|
|
||||||
)
|
|
||||||
Log.e(" >>>>>>>>>>>>>>>>>>>>>>>>>> NO ROOT ACCESS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun xInstall(packageName: String, files: List<File>) {
|
private fun xInstall(packageName: String, files: List<File>) {
|
||||||
var totalSize = 0
|
var totalSize = 0
|
||||||
|
|
||||||
|
|||||||
@@ -98,85 +98,6 @@ class ServiceInstaller(context: Context) : InstallerBase(context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun uninstall(packageName: String) {
|
|
||||||
executor.execute {
|
|
||||||
val readyWithAction = AtomicBoolean(false)
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
|
||||||
val serviceConnection = object : ServiceConnection {
|
|
||||||
override fun onServiceConnected(name: ComponentName, binder: IBinder) {
|
|
||||||
if (isAlreadyQueued(packageName)) {
|
|
||||||
if (::serviceConnection.isInitialized) {
|
|
||||||
context.unbindService(serviceConnection)
|
|
||||||
}
|
|
||||||
readyWithAction.set(true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
AuroraApplication.enqueuedInstalls.add(packageName)
|
|
||||||
val service = IPrivilegedService.Stub.asInterface(binder)
|
|
||||||
|
|
||||||
if (service.hasPrivilegedPermissions()) {
|
|
||||||
Log.i(context.getString(R.string.installer_service_available))
|
|
||||||
|
|
||||||
val callback = object : IPrivilegedCallback.Stub() {
|
|
||||||
|
|
||||||
override fun handleResult(packageName: String, returnCode: Int) {}
|
|
||||||
|
|
||||||
override fun handleResultX(
|
|
||||||
packageName: String,
|
|
||||||
returnCode: Int,
|
|
||||||
extra: String?
|
|
||||||
) {
|
|
||||||
removeFromInstallQueue(packageName)
|
|
||||||
handleCallbackUninstall(packageName, returnCode, extra)
|
|
||||||
readyWithAction.set(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
service.deletePackageX(
|
|
||||||
packageName,
|
|
||||||
2,
|
|
||||||
BuildConfig.APPLICATION_ID,
|
|
||||||
callback
|
|
||||||
)
|
|
||||||
} catch (e: RemoteException) {
|
|
||||||
Log.e("Failed to connect Aurora Services")
|
|
||||||
removeFromInstallQueue(packageName)
|
|
||||||
readyWithAction.set(true)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
removeFromInstallQueue(packageName)
|
|
||||||
postError(
|
|
||||||
packageName,
|
|
||||||
context.getString(R.string.installer_status_failure),
|
|
||||||
context.getString(R.string.installer_service_misconfigured)
|
|
||||||
)
|
|
||||||
readyWithAction.set(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceDisconnected(name: ComponentName) {
|
|
||||||
removeFromInstallQueue(packageName)
|
|
||||||
Log.e("Disconnected from Aurora Services")
|
|
||||||
readyWithAction.set(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val intent = Intent(PRIVILEGED_EXTENSION_SERVICE_INTENT)
|
|
||||||
intent.setPackage(PRIVILEGED_EXTENSION_PACKAGE_NAME)
|
|
||||||
|
|
||||||
context.bindService(
|
|
||||||
intent,
|
|
||||||
serviceConnection,
|
|
||||||
Context.BIND_AUTO_CREATE
|
|
||||||
)
|
|
||||||
}
|
|
||||||
while (!readyWithAction.get()) {
|
|
||||||
Thread.sleep(1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun xInstall(packageName: String, uriList: List<Uri>, fileList: List<String>) {
|
private fun xInstall(packageName: String, uriList: List<Uri>, fileList: List<String>) {
|
||||||
executor.execute {
|
executor.execute {
|
||||||
val readyWithAction = AtomicBoolean(false)
|
val readyWithAction = AtomicBoolean(false)
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ import com.aurora.store.data.ViewState
|
|||||||
import com.aurora.store.data.event.BusEvent
|
import com.aurora.store.data.event.BusEvent
|
||||||
import com.aurora.store.data.event.InstallerEvent
|
import com.aurora.store.data.event.InstallerEvent
|
||||||
import com.aurora.store.data.installer.AppInstaller
|
import com.aurora.store.data.installer.AppInstaller
|
||||||
import com.aurora.store.data.installer.RootInstaller
|
|
||||||
import com.aurora.store.data.model.DownloadStatus
|
import com.aurora.store.data.model.DownloadStatus
|
||||||
import com.aurora.store.data.providers.AuthProvider
|
import com.aurora.store.data.providers.AuthProvider
|
||||||
import com.aurora.store.databinding.FragmentDetailsBinding
|
import com.aurora.store.databinding.FragmentDetailsBinding
|
||||||
@@ -89,7 +88,6 @@ import com.aurora.store.viewmodel.details.AppDetailsViewModel
|
|||||||
import com.aurora.store.viewmodel.details.DetailsClusterViewModel
|
import com.aurora.store.viewmodel.details.DetailsClusterViewModel
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||||
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
|
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
@@ -375,7 +373,7 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_uninstall -> {
|
R.id.action_uninstall -> {
|
||||||
uninstallApp()
|
AppInstaller.uninstall(requireContext(), app.packageName)
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_download_manual -> {
|
R.id.menu_download_manual -> {
|
||||||
@@ -440,27 +438,6 @@ class AppDetailsFragment : BaseFragment(R.layout.fragment_details) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
private fun uninstallApp() {
|
|
||||||
val installer = AppInstaller.getInstance(requireContext()).getPreferredInstaller()
|
|
||||||
|
|
||||||
if (installer is RootInstaller) {
|
|
||||||
MaterialAlertDialogBuilder(requireContext())
|
|
||||||
.setTitle(app.displayName)
|
|
||||||
.setMessage(requireContext().getString(R.string.action_uninstall_confirmation))
|
|
||||||
.setPositiveButton(requireContext().getString(android.R.string.ok)) { _, _ ->
|
|
||||||
installer.uninstall(app.packageName)
|
|
||||||
}
|
|
||||||
.setNegativeButton(requireContext().getString(android.R.string.cancel)) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
.show()
|
|
||||||
} else {
|
|
||||||
installer.uninstall(app.packageName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun inflatePartialApp() {
|
private fun inflatePartialApp() {
|
||||||
if (::app.isInitialized) {
|
if (::app.isInitialized) {
|
||||||
attachHeader()
|
attachHeader()
|
||||||
|
|||||||
@@ -115,8 +115,7 @@ class AppMenuSheet : BaseBottomSheet() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_uninstall -> {
|
R.id.action_uninstall -> {
|
||||||
AppInstaller.getInstance(requireContext())
|
AppInstaller.uninstall(requireContext(), args.app.packageName)
|
||||||
.getPreferredInstaller().uninstall(args.app.packageName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_info -> {
|
R.id.action_info -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user