From 8f4995221a5e3d6e8ab8af2979c8b99e9bb2ac7d Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Sat, 4 May 2024 14:05:56 +0530 Subject: [PATCH] Move post-installation steps to AppInstaller class Signed-off-by: Aayush Gupta --- .../aurora/extensions/BroadcastReceiver.kt | 24 --------- .../store/data/installer/AppInstaller.kt | 12 +++++ .../store/data/installer/InstallerBase.kt | 20 ++++++++ .../store/data/installer/RootInstaller.kt | 4 +- .../store/data/installer/SessionInstaller.kt | 4 ++ .../store/data/installer/ShizukuInstaller.kt | 4 ++ .../data/receiver/InstallerStatusReceiver.kt | 19 ++++++- .../data/receiver/PackageManagerReceiver.kt | 49 +------------------ 8 files changed, 61 insertions(+), 75 deletions(-) delete mode 100644 app/src/main/java/com/aurora/extensions/BroadcastReceiver.kt diff --git a/app/src/main/java/com/aurora/extensions/BroadcastReceiver.kt b/app/src/main/java/com/aurora/extensions/BroadcastReceiver.kt deleted file mode 100644 index 04e0df3fd..000000000 --- a/app/src/main/java/com/aurora/extensions/BroadcastReceiver.kt +++ /dev/null @@ -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() - } - } -} diff --git a/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt index 93ff25873..f89552134 100644 --- a/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/AppInstaller.kt @@ -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) diff --git a/app/src/main/java/com/aurora/store/data/installer/InstallerBase.kt b/app/src/main/java/com/aurora/store/data/installer/InstallerBase.kt index 0b6968cc3..a775fb4d1 100644 --- a/app/src/main/java/com/aurora/store/data/installer/InstallerBase.kt +++ b/app/src/main/java/com/aurora/store/data/installer/InstallerBase.kt @@ -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") diff --git a/app/src/main/java/com/aurora/store/data/installer/RootInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/RootInstaller.kt index 81bbd25ec..6601910fd 100644 --- a/app/src/main/java/com/aurora/store/data/installer/RootInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/RootInstaller.kt @@ -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, diff --git a/app/src/main/java/com/aurora/store/data/installer/SessionInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/SessionInstaller.kt index 373b096e9..d356f49f6 100644 --- a/app/src/main/java/com/aurora/store/data/installer/SessionInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/SessionInstaller.kt @@ -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()) { diff --git a/app/src/main/java/com/aurora/store/data/installer/ShizukuInstaller.kt b/app/src/main/java/com/aurora/store/data/installer/ShizukuInstaller.kt index 4f3b6db9e..134886539 100644 --- a/app/src/main/java/com/aurora/store/data/installer/ShizukuInstaller.kt +++ b/app/src/main/java/com/aurora/store/data/installer/ShizukuInstaller.kt @@ -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 diff --git a/app/src/main/java/com/aurora/store/data/receiver/InstallerStatusReceiver.kt b/app/src/main/java/com/aurora/store/data/receiver/InstallerStatusReceiver.kt index ae86be05b..967940fa2 100644 --- a/app/src/main/java/com/aurora/store/data/receiver/InstallerStatusReceiver.kt +++ b/app/src/main/java/com/aurora/store/data/receiver/InstallerStatusReceiver.kt @@ -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) diff --git a/app/src/main/java/com/aurora/store/data/receiver/PackageManagerReceiver.kt b/app/src/main/java/com/aurora/store/data/receiver/PackageManagerReceiver.kt index ab30587be..eb188bed7 100644 --- a/app/src/main/java/com/aurora/store/data/receiver/PackageManagerReceiver.kt +++ b/app/src/main/java/com/aurora/store/data/receiver/PackageManagerReceiver.kt @@ -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) - } }