diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a648d4eac..8934c6193 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -135,7 +135,7 @@ diff --git a/app/src/main/java/com/aurora/store/data/installer/SessionInstallerBase.kt b/app/src/main/java/com/aurora/store/data/installer/SessionInstallerBase.kt index 9c06dc7a8..d35e4ba95 100644 --- a/app/src/main/java/com/aurora/store/data/installer/SessionInstallerBase.kt +++ b/app/src/main/java/com/aurora/store/data/installer/SessionInstallerBase.kt @@ -28,7 +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.data.receiver.InstallerStatusReceiver import com.aurora.store.util.Log import java.io.File @@ -62,8 +62,8 @@ abstract class SessionInstallerBase(context: Context) : InstallerBase(context) { } } - val callBackIntent = Intent(context, InstallReceiver::class.java).apply { - action = InstallReceiver.ACTION_INSTALL_STATUS + val callBackIntent = Intent(context, InstallerStatusReceiver::class.java).apply { + action = InstallerStatusReceiver.ACTION_INSTALL_STATUS setPackage(context.packageName) putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, packageName) addFlags(Intent.FLAG_RECEIVER_FOREGROUND) diff --git a/app/src/main/java/com/aurora/store/data/receiver/InstallReceiver.kt b/app/src/main/java/com/aurora/store/data/receiver/InstallerStatusReceiver.kt similarity index 54% rename from app/src/main/java/com/aurora/store/data/receiver/InstallReceiver.kt rename to app/src/main/java/com/aurora/store/data/receiver/InstallerStatusReceiver.kt index 7670bdaef..009472c93 100644 --- a/app/src/main/java/com/aurora/store/data/receiver/InstallReceiver.kt +++ b/app/src/main/java/com/aurora/store/data/receiver/InstallerStatusReceiver.kt @@ -25,91 +25,56 @@ 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.CommonUtil.inForeground import com.aurora.store.util.NotificationUtil -import com.aurora.store.util.PathUtil import dagger.hilt.android.AndroidEntryPoint -import java.io.File import org.greenrobot.eventbus.EventBus @AndroidEntryPoint -class InstallReceiver : BroadcastReceiver() { +class InstallerStatusReceiver : 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 + private val TAG = InstallerStatusReceiver::class.java.simpleName override fun onReceive(context: Context, intent: Intent) { - 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).path) - AppInstaller.getInstance(context).getPreferredInstaller() - .install( - packageName, - downloadDir.listFiles()!!.filter { it.path.endsWith(".apk") } - ) - } catch (exception: Exception) { - Log.e(TAG, "Failed to install $packageName") - } - } - } + if (intent.action == 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) - 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) + // Exit early if package was successfully installed, nothing to do + if (status == PackageInstaller.STATUS_SUCCESS) return - if (inForeground() && status == PackageInstaller.STATUS_PENDING_USER_ACTION) { - promptUser(intent, context) - } else { - postStatus(status, packageName, extra, context) - notifyInstallation(context, packageName!!, status) - } + if (inForeground() && status == PackageInstaller.STATUS_PENDING_USER_ACTION) { + promptUser(intent, context) + } else { + postStatus(status, packageName, extra, context) + notifyUser(context, packageName!!, status) } } } - private fun notifyInstallation(context: Context, packageName: String, status: Int) { + private fun notifyUser(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( + val notification = NotificationUtil.getInstallerStatusNotification( context, - App(packageName).apply { - if (status == PackageInstaller.STATUS_SUCCESS) { - val appInfo = context.packageManager.getApplicationInfo(packageName, 0) - displayName = context.packageManager.getApplicationLabel(appInfo).toString() - } - }, - content + App(packageName), + AppInstaller.getErrorString(context, status) ) 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 { + IntentCompat.getParcelableExtra(intent, Intent.EXTRA_INTENT, Intent::class.java)?.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) @@ -153,8 +118,4 @@ class InstallReceiver : BroadcastReceiver() { } } } - - private fun inForeground(): Boolean { - return ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED) - } } diff --git a/app/src/main/java/com/aurora/store/data/work/DownloadWorker.kt b/app/src/main/java/com/aurora/store/data/work/DownloadWorker.kt index 3081417a3..39e48f576 100644 --- a/app/src/main/java/com/aurora/store/data/work/DownloadWorker.kt +++ b/app/src/main/java/com/aurora/store/data/work/DownloadWorker.kt @@ -3,24 +3,22 @@ package com.aurora.store.data.work import android.app.NotificationManager import android.app.Service import android.content.Context -import android.content.Intent import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC import android.util.Log import androidx.hilt.work.HiltWorker import androidx.work.CoroutineWorker import androidx.work.ForegroundInfo import androidx.work.WorkerParameters -import com.aurora.Constants import com.aurora.extensions.copyTo import com.aurora.extensions.isQAndAbove import com.aurora.extensions.requiresObbDir import com.aurora.gplayapi.helpers.PurchaseHelper +import com.aurora.store.data.installer.AppInstaller import com.aurora.store.data.model.DownloadInfo import com.aurora.store.data.model.DownloadStatus import com.aurora.store.data.model.Request import com.aurora.store.data.network.HttpClient import com.aurora.store.data.providers.AuthProvider -import com.aurora.store.data.receiver.InstallReceiver import com.aurora.store.data.room.download.Download import com.aurora.store.data.room.download.DownloadDao import com.aurora.store.util.DownloadWorkerUtil @@ -143,17 +141,30 @@ class DownloadWorker @AssistedInject constructor( // Mark download as completed notifyStatus(DownloadStatus.COMPLETED) Log.i(TAG, "Finished downloading ${download.packageName}") - - // Notify for installation - Intent(appContext, InstallReceiver::class.java).also { - it.action = InstallReceiver.ACTION_INSTALL_APP - it.putExtra(Constants.STRING_APP, download.packageName) - it.putExtra(Constants.STRING_VERSION, download.versionCode) - appContext.sendBroadcast(it) - } + onSuccess() return Result.success() } + private suspend fun onSuccess() { + withContext(NonCancellable) { + try { + val downloadDir = PathUtil.getAppDownloadDir( + appContext, + download.packageName, + download.versionCode + ) + AppInstaller.getInstance(appContext) + .getPreferredInstaller() + .install( + download.packageName, + downloadDir.listFiles()!!.filter { it.path.endsWith(".apk") } + ) + } catch (exception: Exception) { + Log.e(TAG, "Failed to install ${download.packageName}", exception) + } + } + } + private suspend fun onFailure() { withContext(NonCancellable) { Log.i(TAG, "Cleaning up!") diff --git a/app/src/main/java/com/aurora/store/util/NotificationUtil.kt b/app/src/main/java/com/aurora/store/util/NotificationUtil.kt index c7c528428..1c6a6afcf 100644 --- a/app/src/main/java/com/aurora/store/util/NotificationUtil.kt +++ b/app/src/main/java/com/aurora/store/util/NotificationUtil.kt @@ -163,7 +163,7 @@ object NotificationUtil { return builder.build() } - fun getInstallNotification(context: Context, app: App, content: String?): Notification { + fun getInstallerStatusNotification(context: Context, app: App, content: String?): Notification { val builder = NotificationCompat.Builder(context, Constants.NOTIFICATION_CHANNEL_ALERT).apply { color = context.getStyledAttributeColor(R.color.colorAccent)