InstallReceiver: Notify package installation status as well

Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
This commit is contained in:
Aayush Gupta
2023-11-02 20:31:14 +05:30
parent 26c4749047
commit 5b60758347
5 changed files with 145 additions and 22 deletions

View File

@@ -28,6 +28,7 @@ import android.net.Uri
import androidx.core.content.FileProvider
import com.aurora.extensions.isSAndAbove
import com.aurora.store.BuildConfig
import com.aurora.store.data.receiver.InstallReceiver
import com.aurora.store.util.Log
import java.io.File
@@ -61,12 +62,17 @@ abstract class SessionInstallerBase(context: Context) : InstallerBase(context) {
}
}
val callBackIntent = Intent(context, InstallerService::class.java)
val callBackIntent = Intent(context, InstallReceiver::class.java).apply {
action = InstallReceiver.ACTION_INSTALL_STATUS
setPackage(context.packageName)
putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, packageName)
addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
}
val flags = if (isSAndAbove())
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE else
PendingIntent.FLAG_UPDATE_CURRENT
val pendingIntent = PendingIntent.getService(
val pendingIntent = PendingIntent.getBroadcast(
context,
sessionId,
callBackIntent,

View File

@@ -18,35 +18,148 @@
*/
package com.aurora.store.data.receiver
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInstaller
import android.util.Log
import androidx.core.content.IntentCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ProcessLifecycleOwner
import com.aurora.Constants
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.util.NotificationUtil
import com.aurora.store.util.PathUtil
import java.io.File
import org.greenrobot.eventbus.EventBus
import kotlin.io.path.pathString
class InstallReceiver : BroadcastReceiver() {
companion object {
const val ACTION_INSTALL_APP = "com.aurora.store.data.receiver.InstallReceiver.INSTALL_APP"
const val ACTION_INSTALL_STATUS =
"com.aurora.store.data.receiver.InstallReceiver.INSTALL_STATUS"
}
private val TAG = InstallReceiver::class.java.simpleName
override fun onReceive(context: Context, intent: Intent) {
val packageName = intent.extras?.getString(Constants.STRING_APP) ?: String()
val version = intent.extras?.getInt(Constants.STRING_VERSION)
if (packageName.isNotBlank() && version != null) {
try {
val downloadDir =
File(PathUtil.getAppDownloadDir(context, packageName, version).pathString)
AppInstaller.getInstance(context).getPreferredInstaller()
.install(
packageName,
downloadDir.listFiles()!!.filter { it.path.endsWith(".apk") }
)
} catch (exception: Exception) {
Log.e(TAG, "Failed to install $packageName")
when (intent.action) {
ACTION_INSTALL_APP -> {
val packageName = intent.extras?.getString(Constants.STRING_APP) ?: String()
val version = intent.extras?.getInt(Constants.STRING_VERSION)
if (packageName.isNotBlank() && version != null) {
try {
val downloadDir =
File(
PathUtil.getAppDownloadDir(
context,
packageName,
version
).pathString
)
AppInstaller.getInstance(context).getPreferredInstaller()
.install(
packageName,
downloadDir.listFiles()!!.filter { it.path.endsWith(".apk") }
)
} catch (exception: Exception) {
Log.e(TAG, "Failed to install $packageName")
}
}
}
ACTION_INSTALL_STATUS -> {
val packageName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)
val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)
val extra = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
if (inForeground() && status == PackageInstaller.STATUS_PENDING_USER_ACTION) {
promptUser(intent, context)
} else {
postStatus(status, packageName, extra, context)
notifyInstallation(context, packageName!!, status)
}
}
}
}
private fun notifyInstallation(context: Context, packageName: String, status: Int) {
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val content = if (status == PackageInstaller.STATUS_SUCCESS) {
context.getString(R.string.installer_status_success)
} else {
AppInstaller.getErrorString(context, status)
}
val notification = NotificationUtil.getInstallNotification(
context,
App(packageName).apply {
if (status == PackageInstaller.STATUS_SUCCESS) {
val appInfo = context.packageManager.getApplicationInfo(packageName, 0)
displayName = context.packageManager.getApplicationLabel(appInfo).toString()
}
},
content
)
notificationManager.notify(packageName.hashCode(), notification)
}
private fun promptUser(intent: Intent, context: Context) {
val confirmationIntent =
IntentCompat.getParcelableExtra(intent, Intent.EXTRA_INTENT, Intent::class.java)
confirmationIntent?.let {
it.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
it.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, "com.android.vending")
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
try {
context.startActivity(it)
} catch (exception: Exception) {
Log.e(TAG, "Failed to trigger installation!", exception)
}
}
}
private fun postStatus(status: Int, packageName: String?, extra: String?, context: Context) {
when (status) {
PackageInstaller.STATUS_SUCCESS -> {
EventBus.getDefault().post(
InstallerEvent.Success(
packageName,
context.getString(R.string.installer_status_success)
)
)
}
PackageInstaller.STATUS_FAILURE_ABORTED -> {
EventBus.getDefault().post(
InstallerEvent.Cancelled(
packageName,
AppInstaller.getErrorString(context, status)
)
)
}
else -> {
EventBus.getDefault().post(
InstallerEvent.Failed(
packageName,
AppInstaller.getErrorString(context, status),
extra
)
)
}
}
}
private fun inForeground(): Boolean {
return ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)
}
}

View File

@@ -135,10 +135,10 @@ class DownloadWorker(private val appContext: Context, workerParams: WorkerParame
// Notify for installation
Intent(appContext, InstallReceiver::class.java).also {
it.action = InstallReceiver.ACTION_INSTALL_APP
it.putExtra(Constants.STRING_APP, app.packageName)
it.putExtra(Constants.STRING_VERSION, app.versionCode)
appContext.sendBroadcast(it)
}
// Remove the app from the list

View File

@@ -268,12 +268,15 @@ object NotificationUtil {
}
fun getInstallNotification(context: Context, app: App, content: String?): Notification {
val builder = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ALERT)
builder.color = context.getStyledAttributeColor(R.color.colorAccent)
builder.setSmallIcon(R.drawable.ic_install)
builder.setContentTitle(app.displayName)
builder.setContentText(content)
builder.setSubText(app.packageName)
val builder =
NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ALERT).apply {
color = context.getStyledAttributeColor(R.color.colorAccent)
setSmallIcon(R.drawable.ic_install)
setContentTitle(app.displayName)
setContentText(content)
setContentIntent(getContentIntentForDetails(context, app))
setSubText(app.packageName)
}
return builder.build()
}