PackageManagerReceiver: Rework package install actions

Notify on package installation and delete the downloaded directory

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2023-12-27 20:51:38 +05:30
parent e0cda7eadf
commit 87dc309d35
3 changed files with 84 additions and 22 deletions

View File

@@ -0,0 +1,26 @@
package com.aurora.extensions
import android.content.BroadcastReceiver
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
@OptIn(DelicateCoroutinesApi::class)
fun BroadcastReceiver.goAsync(
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.() -> Unit
) {
val pendingResult = goAsync()
GlobalScope.launch(context) {
try {
block()
} finally {
pendingResult.finish()
cancel()
}
}
}

View File

@@ -19,29 +19,53 @@
package com.aurora.store.data.receiver
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.aurora.store.BuildConfig
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.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
import java.io.File
@AndroidEntryPoint
open class PackageManagerReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
private val TAG = PackageManagerReceiver::class.java.simpleName
@Inject
lateinit var downloadWorkerUtil: DownloadWorkerUtil
override fun onReceive(context: Context, intent: Intent) = goAsync {
if (intent.action != null && intent.data != null) {
val packageName = intent.data!!.encodedSchemeSpecificPart
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.status == DownloadStatus.COMPLETED }
?.let {
notifyInstallation(context, it)
if (Preferences.getBoolean(context, PREFERENCE_AUTO_DELETE)) {
clearDownloads(context, it)
}
}
}
Intent.ACTION_PACKAGE_REMOVED -> {
@@ -53,29 +77,22 @@ open class PackageManagerReceiver : BroadcastReceiver() {
AppInstaller.getInstance(context)
.getPreferredInstaller()
.removeFromInstallQueue(packageName)
val isAutoDeleteAPKEnabled = Preferences.getBoolean(
context,
Preferences.PREFERENCE_AUTO_DELETE
)
if (isAutoDeleteAPKEnabled)
clearDownloads(context, packageName)
//Clear self update apk
if (packageName == BuildConfig.APPLICATION_ID)
clearDownloads(context, packageName)
}
}
private fun clearDownloads(context: Context, packageName: String) {
private fun clearDownloads(context: Context, download: Download) {
try {
val rootDirPath = PathUtil.getPackageDirectory(context, packageName)
val rootDir = File(rootDirPath)
if (rootDir.exists())
rootDir.deleteRecursively()
} catch (e: Exception) {
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)
}
}

View File

@@ -163,6 +163,25 @@ object NotificationUtil {
return builder.build()
}
fun getInstallNotification(context: Context, download: AuroraDownload): Notification {
val builder = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ALERT)
// Set big icon for download
try {
val bitmap = BitmapFactory.decodeStream(URL(download.iconURL).openStream())
builder.setLargeIcon(bitmap)
} catch (exception: Exception) {
Log.i(TAG, "Failed to set big icon", exception)
}
return builder.setSmallIcon(R.drawable.ic_install)
.setColor(context.getStyledAttributeColor(R.color.colorAccent))
.setContentTitle(download.displayName)
.setContentText(context.getString(R.string.installer_status_success))
.setContentIntent(getContentIntentForDetails(context, download.packageName))
.build()
}
fun getInstallerStatusNotification(context: Context, app: App, content: String?): Notification {
val builder =
NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ALERT).apply {