Move post-installation steps to AppInstaller class
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
@@ -1,24 +0,0 @@
|
||||
package com.aurora.extensions
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import com.aurora.store.AuroraApp
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.coroutines.EmptyCoroutineContext
|
||||
|
||||
fun BroadcastReceiver.goAsync(
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
) {
|
||||
val pendingResult = goAsync()
|
||||
AuroraApp.scope.launch(context) {
|
||||
try {
|
||||
block()
|
||||
} finally {
|
||||
pendingResult.finish()
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
package com.aurora.store.data.installer
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
@@ -31,6 +32,8 @@ import com.aurora.extensions.isOAndAbove
|
||||
import com.aurora.extensions.isPAndAbove
|
||||
import com.aurora.store.BuildConfig
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.room.download.Download
|
||||
import com.aurora.store.util.NotificationUtil
|
||||
import com.aurora.store.util.PackageUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_INSTALLER_ID
|
||||
@@ -43,6 +46,15 @@ import javax.inject.Inject
|
||||
class AppInstaller @Inject constructor(@ApplicationContext private val context: Context) {
|
||||
|
||||
companion object {
|
||||
const val EXTRA_DOWNLOAD = "com.aurora.store.data.installer.AppInstaller.EXTRA_DOWNLOAD"
|
||||
|
||||
fun notifyInstallation(context: Context, download: Download) {
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
val notification = NotificationUtil.getInstallNotification(context, download)
|
||||
notificationManager.notify(download.packageName.hashCode(), notification)
|
||||
}
|
||||
|
||||
fun getErrorString(context: Context, status: Int): String {
|
||||
return when (status) {
|
||||
PackageInstaller.STATUS_FAILURE_ABORTED -> context.getString(R.string.installer_status_user_action)
|
||||
|
||||
@@ -25,13 +25,23 @@ import androidx.core.content.FileProvider
|
||||
import com.aurora.store.AuroraApp
|
||||
import com.aurora.store.BuildConfig
|
||||
import com.aurora.store.data.event.InstallerEvent
|
||||
import com.aurora.store.data.room.download.Download
|
||||
import com.aurora.store.util.Log
|
||||
import com.aurora.store.util.PathUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_AUTO_DELETE
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.io.File
|
||||
|
||||
abstract class InstallerBase(protected var context: Context) : IInstaller {
|
||||
|
||||
var download: Download? = null
|
||||
private set
|
||||
|
||||
override fun install(download: Download) {
|
||||
this.download = download
|
||||
}
|
||||
|
||||
override fun clearQueue() {
|
||||
AuroraApp.enqueuedInstalls.clear()
|
||||
}
|
||||
@@ -44,6 +54,16 @@ abstract class InstallerBase(protected var context: Context) : IInstaller {
|
||||
AuroraApp.enqueuedInstalls.remove(packageName)
|
||||
}
|
||||
|
||||
open fun onInstallationSuccess() {
|
||||
download?.let {
|
||||
AppInstaller.notifyInstallation(context, it)
|
||||
if (Preferences.getBoolean(context, PREFERENCE_AUTO_DELETE)) {
|
||||
PathUtil.getAppDownloadDir(context, it.packageName, it.versionCode)
|
||||
.deleteRecursively()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open fun postError(packageName: String, error: String?, extra: String?) {
|
||||
Log.e("Service Error :$error")
|
||||
|
||||
|
||||
@@ -93,7 +93,9 @@ class RootInstaller(context: Context) : InstallerBase(context) {
|
||||
|
||||
val shellResult = Shell.cmd("pm install-commit $sessionId").exec()
|
||||
|
||||
if (!shellResult.isSuccess) {
|
||||
if (shellResult.isSuccess) {
|
||||
onInstallationSuccess()
|
||||
} else {
|
||||
removeFromInstallQueue(packageName)
|
||||
val event = InstallerEvent.Failed(
|
||||
packageName,
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.aurora.extensions.isTAndAbove
|
||||
import com.aurora.extensions.isUAndAbove
|
||||
import com.aurora.extensions.runOnUiThread
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.installer.AppInstaller.Companion.EXTRA_DOWNLOAD
|
||||
import com.aurora.store.data.model.Installer
|
||||
import com.aurora.store.data.receiver.InstallerStatusReceiver
|
||||
import com.aurora.store.data.room.download.Download
|
||||
@@ -63,6 +64,8 @@ class SessionInstaller(context: Context) : InstallerBase(context) {
|
||||
}
|
||||
|
||||
override fun install(download: Download) {
|
||||
super.install(download)
|
||||
|
||||
if (isAlreadyQueued(download.packageName)) {
|
||||
Log.i("${download.packageName} already queued")
|
||||
} else {
|
||||
@@ -168,6 +171,7 @@ class SessionInstaller(context: Context) : InstallerBase(context) {
|
||||
action = InstallerStatusReceiver.ACTION_INSTALL_STATUS
|
||||
setPackage(context.packageName)
|
||||
putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, packageName)
|
||||
putExtra(EXTRA_DOWNLOAD, download)
|
||||
addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
||||
}
|
||||
val flags = if (isSAndAbove()) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import androidx.annotation.RequiresApi
|
||||
import com.aurora.extensions.isOAndAbove
|
||||
import com.aurora.extensions.isSAndAbove
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.installer.AppInstaller.Companion.EXTRA_DOWNLOAD
|
||||
import com.aurora.store.data.model.Installer
|
||||
import com.aurora.store.data.receiver.InstallerStatusReceiver
|
||||
import com.aurora.store.data.room.download.Download
|
||||
@@ -81,6 +82,8 @@ class ShizukuInstaller(context: Context) : InstallerBase(context) {
|
||||
}
|
||||
|
||||
override fun install(download: Download) {
|
||||
super.install(download)
|
||||
|
||||
if (isAlreadyQueued(download.packageName)) {
|
||||
Log.i("${download.packageName} already queued")
|
||||
} else {
|
||||
@@ -142,6 +145,7 @@ class ShizukuInstaller(context: Context) : InstallerBase(context) {
|
||||
setPackage(context.packageName)
|
||||
addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
||||
putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, sharedLibPkgName.ifBlank { packageName })
|
||||
putExtra(EXTRA_DOWNLOAD, download)
|
||||
}
|
||||
val flags = if (isSAndAbove()) {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
||||
|
||||
@@ -30,8 +30,13 @@ import com.aurora.gplayapi.data.models.App
|
||||
import com.aurora.store.R
|
||||
import com.aurora.store.data.event.InstallerEvent
|
||||
import com.aurora.store.data.installer.AppInstaller
|
||||
import com.aurora.store.data.installer.AppInstaller.Companion.EXTRA_DOWNLOAD
|
||||
import com.aurora.store.data.room.download.Download
|
||||
import com.aurora.store.util.CommonUtil.inForeground
|
||||
import com.aurora.store.util.NotificationUtil
|
||||
import com.aurora.store.util.PathUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_AUTO_DELETE
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
@@ -50,9 +55,19 @@ class InstallerStatusReceiver : BroadcastReceiver() {
|
||||
val packageName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)
|
||||
val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)
|
||||
val extra = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
|
||||
val download = IntentCompat.getParcelableExtra(
|
||||
intent, EXTRA_DOWNLOAD, Download::class.java
|
||||
)
|
||||
|
||||
// Exit early if package was successfully installed, nothing to do
|
||||
if (status == PackageInstaller.STATUS_SUCCESS) return
|
||||
// If package was successfully installed, exit after notifying user and doing cleanup
|
||||
if (status == PackageInstaller.STATUS_SUCCESS && download != null) {
|
||||
AppInstaller.notifyInstallation(context, download)
|
||||
if (Preferences.getBoolean(context, PREFERENCE_AUTO_DELETE)) {
|
||||
PathUtil.getAppDownloadDir(context, download.packageName, download.versionCode)
|
||||
.deleteRecursively()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (inForeground() && status == PackageInstaller.STATUS_PENDING_USER_ACTION) {
|
||||
promptUser(intent, context)
|
||||
|
||||
@@ -19,60 +19,29 @@
|
||||
|
||||
package com.aurora.store.data.receiver
|
||||
|
||||
import android.app.NotificationManager
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import com.aurora.extensions.goAsync
|
||||
import com.aurora.store.data.event.BusEvent.InstallEvent
|
||||
import com.aurora.store.data.event.BusEvent.UninstallEvent
|
||||
import com.aurora.store.data.installer.AppInstaller
|
||||
import com.aurora.store.data.model.DownloadStatus
|
||||
import com.aurora.store.data.room.download.Download
|
||||
import com.aurora.store.util.DownloadWorkerUtil
|
||||
import com.aurora.store.util.NotificationUtil
|
||||
import com.aurora.store.util.PackageUtil.isSharedLibrary
|
||||
import com.aurora.store.util.PathUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_AUTO_DELETE
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
@AndroidEntryPoint
|
||||
open class PackageManagerReceiver : BroadcastReceiver() {
|
||||
|
||||
private val TAG = PackageManagerReceiver::class.java.simpleName
|
||||
|
||||
@Inject
|
||||
lateinit var downloadWorkerUtil: DownloadWorkerUtil
|
||||
|
||||
@Inject
|
||||
lateinit var appInstaller: AppInstaller
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) = goAsync {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action != null && intent.data != null) {
|
||||
val packageName = intent.data!!.encodedSchemeSpecificPart
|
||||
|
||||
// We don't care about shared libraries, bail out
|
||||
if (isSharedLibrary(context, packageName)) return@goAsync
|
||||
|
||||
when (intent.action) {
|
||||
Intent.ACTION_PACKAGE_ADDED -> {
|
||||
Log.i(TAG, "Installed $packageName")
|
||||
EventBus.getDefault().post(InstallEvent(packageName, ""))
|
||||
|
||||
downloadWorkerUtil.downloadsList.filter { it.isNotEmpty() }.firstOrNull()
|
||||
?.find { it.packageName == packageName && it.downloadStatus == DownloadStatus.COMPLETED }
|
||||
?.let {
|
||||
notifyInstallation(context, it)
|
||||
if (Preferences.getBoolean(context, PREFERENCE_AUTO_DELETE)) {
|
||||
clearDownloads(context, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Intent.ACTION_PACKAGE_REMOVED -> {
|
||||
@@ -84,20 +53,4 @@ open class PackageManagerReceiver : BroadcastReceiver() {
|
||||
appInstaller.getPreferredInstaller().removeFromInstallQueue(packageName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearDownloads(context: Context, download: Download) {
|
||||
try {
|
||||
PathUtil.getAppDownloadDir(context, download.packageName, download.versionCode)
|
||||
.deleteRecursively()
|
||||
} catch (exception: Exception) {
|
||||
Log.e(TAG, "Failed to delete $download.packageName's downloads", exception)
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyInstallation(context: Context, download: Download) {
|
||||
val notificationManager =
|
||||
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
val notification = NotificationUtil.getInstallNotification(context, download)
|
||||
notificationManager.notify(download.packageName.hashCode(), notification)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user