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
|
package com.aurora.store.data.installer
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageInstaller
|
import android.content.pm.PackageInstaller
|
||||||
@@ -31,6 +32,8 @@ import com.aurora.extensions.isOAndAbove
|
|||||||
import com.aurora.extensions.isPAndAbove
|
import com.aurora.extensions.isPAndAbove
|
||||||
import com.aurora.store.BuildConfig
|
import com.aurora.store.BuildConfig
|
||||||
import com.aurora.store.R
|
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.PackageUtil
|
||||||
import com.aurora.store.util.Preferences
|
import com.aurora.store.util.Preferences
|
||||||
import com.aurora.store.util.Preferences.PREFERENCE_INSTALLER_ID
|
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) {
|
class AppInstaller @Inject constructor(@ApplicationContext private val context: Context) {
|
||||||
|
|
||||||
companion object {
|
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 {
|
fun getErrorString(context: Context, status: Int): String {
|
||||||
return when (status) {
|
return when (status) {
|
||||||
PackageInstaller.STATUS_FAILURE_ABORTED -> context.getString(R.string.installer_status_user_action)
|
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.AuroraApp
|
||||||
import com.aurora.store.BuildConfig
|
import com.aurora.store.BuildConfig
|
||||||
import com.aurora.store.data.event.InstallerEvent
|
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.Log
|
||||||
import com.aurora.store.util.PathUtil
|
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 org.greenrobot.eventbus.EventBus
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class InstallerBase(protected var context: Context) : IInstaller {
|
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() {
|
override fun clearQueue() {
|
||||||
AuroraApp.enqueuedInstalls.clear()
|
AuroraApp.enqueuedInstalls.clear()
|
||||||
}
|
}
|
||||||
@@ -44,6 +54,16 @@ abstract class InstallerBase(protected var context: Context) : IInstaller {
|
|||||||
AuroraApp.enqueuedInstalls.remove(packageName)
|
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?) {
|
open fun postError(packageName: String, error: String?, extra: String?) {
|
||||||
Log.e("Service Error :$error")
|
Log.e("Service Error :$error")
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,9 @@ class RootInstaller(context: Context) : InstallerBase(context) {
|
|||||||
|
|
||||||
val shellResult = Shell.cmd("pm install-commit $sessionId").exec()
|
val shellResult = Shell.cmd("pm install-commit $sessionId").exec()
|
||||||
|
|
||||||
if (!shellResult.isSuccess) {
|
if (shellResult.isSuccess) {
|
||||||
|
onInstallationSuccess()
|
||||||
|
} else {
|
||||||
removeFromInstallQueue(packageName)
|
removeFromInstallQueue(packageName)
|
||||||
val event = InstallerEvent.Failed(
|
val event = InstallerEvent.Failed(
|
||||||
packageName,
|
packageName,
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import com.aurora.extensions.isTAndAbove
|
|||||||
import com.aurora.extensions.isUAndAbove
|
import com.aurora.extensions.isUAndAbove
|
||||||
import com.aurora.extensions.runOnUiThread
|
import com.aurora.extensions.runOnUiThread
|
||||||
import com.aurora.store.R
|
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.model.Installer
|
||||||
import com.aurora.store.data.receiver.InstallerStatusReceiver
|
import com.aurora.store.data.receiver.InstallerStatusReceiver
|
||||||
import com.aurora.store.data.room.download.Download
|
import com.aurora.store.data.room.download.Download
|
||||||
@@ -63,6 +64,8 @@ class SessionInstaller(context: Context) : InstallerBase(context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun install(download: Download) {
|
override fun install(download: Download) {
|
||||||
|
super.install(download)
|
||||||
|
|
||||||
if (isAlreadyQueued(download.packageName)) {
|
if (isAlreadyQueued(download.packageName)) {
|
||||||
Log.i("${download.packageName} already queued")
|
Log.i("${download.packageName} already queued")
|
||||||
} else {
|
} else {
|
||||||
@@ -168,6 +171,7 @@ class SessionInstaller(context: Context) : InstallerBase(context) {
|
|||||||
action = InstallerStatusReceiver.ACTION_INSTALL_STATUS
|
action = InstallerStatusReceiver.ACTION_INSTALL_STATUS
|
||||||
setPackage(context.packageName)
|
setPackage(context.packageName)
|
||||||
putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, packageName)
|
putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, packageName)
|
||||||
|
putExtra(EXTRA_DOWNLOAD, download)
|
||||||
addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
||||||
}
|
}
|
||||||
val flags = if (isSAndAbove()) {
|
val flags = if (isSAndAbove()) {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import androidx.annotation.RequiresApi
|
|||||||
import com.aurora.extensions.isOAndAbove
|
import com.aurora.extensions.isOAndAbove
|
||||||
import com.aurora.extensions.isSAndAbove
|
import com.aurora.extensions.isSAndAbove
|
||||||
import com.aurora.store.R
|
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.model.Installer
|
||||||
import com.aurora.store.data.receiver.InstallerStatusReceiver
|
import com.aurora.store.data.receiver.InstallerStatusReceiver
|
||||||
import com.aurora.store.data.room.download.Download
|
import com.aurora.store.data.room.download.Download
|
||||||
@@ -81,6 +82,8 @@ class ShizukuInstaller(context: Context) : InstallerBase(context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun install(download: Download) {
|
override fun install(download: Download) {
|
||||||
|
super.install(download)
|
||||||
|
|
||||||
if (isAlreadyQueued(download.packageName)) {
|
if (isAlreadyQueued(download.packageName)) {
|
||||||
Log.i("${download.packageName} already queued")
|
Log.i("${download.packageName} already queued")
|
||||||
} else {
|
} else {
|
||||||
@@ -142,6 +145,7 @@ class ShizukuInstaller(context: Context) : InstallerBase(context) {
|
|||||||
setPackage(context.packageName)
|
setPackage(context.packageName)
|
||||||
addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
addFlags(Intent.FLAG_RECEIVER_FOREGROUND)
|
||||||
putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, sharedLibPkgName.ifBlank { packageName })
|
putExtra(PackageInstaller.EXTRA_PACKAGE_NAME, sharedLibPkgName.ifBlank { packageName })
|
||||||
|
putExtra(EXTRA_DOWNLOAD, download)
|
||||||
}
|
}
|
||||||
val flags = if (isSAndAbove()) {
|
val flags = if (isSAndAbove()) {
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE
|
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.R
|
||||||
import com.aurora.store.data.event.InstallerEvent
|
import com.aurora.store.data.event.InstallerEvent
|
||||||
import com.aurora.store.data.installer.AppInstaller
|
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.CommonUtil.inForeground
|
||||||
import com.aurora.store.util.NotificationUtil
|
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 dagger.hilt.android.AndroidEntryPoint
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
|
||||||
@@ -50,9 +55,19 @@ class InstallerStatusReceiver : BroadcastReceiver() {
|
|||||||
val packageName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)
|
val packageName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME)
|
||||||
val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)
|
val status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -1)
|
||||||
val extra = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE)
|
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 package was successfully installed, exit after notifying user and doing cleanup
|
||||||
if (status == PackageInstaller.STATUS_SUCCESS) return
|
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) {
|
if (inForeground() && status == PackageInstaller.STATUS_PENDING_USER_ACTION) {
|
||||||
promptUser(intent, context)
|
promptUser(intent, context)
|
||||||
|
|||||||
@@ -19,60 +19,29 @@
|
|||||||
|
|
||||||
package com.aurora.store.data.receiver
|
package com.aurora.store.data.receiver
|
||||||
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
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.InstallEvent
|
||||||
import com.aurora.store.data.event.BusEvent.UninstallEvent
|
import com.aurora.store.data.event.BusEvent.UninstallEvent
|
||||||
import com.aurora.store.data.installer.AppInstaller
|
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 dagger.hilt.android.AndroidEntryPoint
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.flow.filter
|
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
open class PackageManagerReceiver : BroadcastReceiver() {
|
open class PackageManagerReceiver : BroadcastReceiver() {
|
||||||
|
|
||||||
private val TAG = PackageManagerReceiver::class.java.simpleName
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var downloadWorkerUtil: DownloadWorkerUtil
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var appInstaller: AppInstaller
|
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) {
|
if (intent.action != null && intent.data != null) {
|
||||||
val packageName = intent.data!!.encodedSchemeSpecificPart
|
val packageName = intent.data!!.encodedSchemeSpecificPart
|
||||||
|
|
||||||
// We don't care about shared libraries, bail out
|
|
||||||
if (isSharedLibrary(context, packageName)) return@goAsync
|
|
||||||
|
|
||||||
when (intent.action) {
|
when (intent.action) {
|
||||||
Intent.ACTION_PACKAGE_ADDED -> {
|
Intent.ACTION_PACKAGE_ADDED -> {
|
||||||
Log.i(TAG, "Installed $packageName")
|
|
||||||
EventBus.getDefault().post(InstallEvent(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 -> {
|
Intent.ACTION_PACKAGE_REMOVED -> {
|
||||||
@@ -84,20 +53,4 @@ open class PackageManagerReceiver : BroadcastReceiver() {
|
|||||||
appInstaller.getPreferredInstaller().removeFromInstallQueue(packageName)
|
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