mirror of
https://github.com/whyorean/AuroraStore.git
synced 2026-06-13 02:11:07 -04:00
Audit DownloadHelper & UpdateHelper scopes
Action Items: - monitor changes for ~3days, do self-test to ensure it doesn't break anything - also verify changes on older devices & other android skins MIUI, OneUI, EMUI
This commit is contained in:
@@ -22,8 +22,8 @@ package com.aurora.store
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.util.Log.INFO
|
||||
import android.util.Log.DEBUG
|
||||
import android.util.Log.INFO
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.hilt.work.HiltWorkerFactory
|
||||
import androidx.work.Configuration
|
||||
@@ -43,8 +43,11 @@ import com.aurora.store.util.PackageUtil
|
||||
import com.aurora.store.util.Preferences
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.OkHttpClient
|
||||
import org.lsposed.hiddenapibypass.HiddenApiBypass
|
||||
import javax.inject.Inject
|
||||
@@ -71,8 +74,7 @@ class AuroraApp : Application(), Configuration.Provider, SingletonImageLoader.Fa
|
||||
.build()
|
||||
|
||||
companion object {
|
||||
// Alternative to GlobalScope
|
||||
var scope = MainScope()
|
||||
var scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
||||
private set
|
||||
|
||||
val enqueuedInstalls: MutableSet<String> = mutableSetOf()
|
||||
@@ -95,8 +97,10 @@ class AuroraApp : Application(), Configuration.Provider, SingletonImageLoader.Fa
|
||||
NotificationUtil.createNotificationChannel(this)
|
||||
|
||||
// Initialize Download and Update helpers to observe and trigger downloads
|
||||
downloadHelper.init()
|
||||
updateHelper.init()
|
||||
scope.launch {
|
||||
downloadHelper.init()
|
||||
updateHelper.init()
|
||||
}
|
||||
|
||||
//Register broadcast receiver for package install/uninstall
|
||||
ContextCompat.registerReceiver(
|
||||
@@ -112,7 +116,12 @@ class AuroraApp : Application(), Configuration.Provider, SingletonImageLoader.Fa
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
scope.cancel("onLowMemory() called by system")
|
||||
scope = MainScope()
|
||||
scope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
|
||||
}
|
||||
|
||||
override fun onTerminate() {
|
||||
super.onTerminate()
|
||||
scope.cancel()
|
||||
}
|
||||
|
||||
override fun newImageLoader(context: Context): ImageLoader {
|
||||
|
||||
@@ -16,12 +16,12 @@ import com.aurora.store.data.room.update.Update
|
||||
import com.aurora.store.data.work.DownloadWorker
|
||||
import com.aurora.store.util.PathUtil
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@@ -49,30 +49,26 @@ class DownloadHelper @Inject constructor(
|
||||
/**
|
||||
* Removes failed download from the queue and starts observing for newly enqueued apps.
|
||||
*/
|
||||
fun init() {
|
||||
AuroraApp.scope.launch {
|
||||
suspend fun init() {
|
||||
withContext(Dispatchers.IO) {
|
||||
cancelFailedDownloads(downloadDao.downloads().firstOrNull() ?: emptyList())
|
||||
}.invokeOnCompletion {
|
||||
observeDownloads()
|
||||
}
|
||||
|
||||
observeDownloads()
|
||||
}
|
||||
|
||||
private fun observeDownloads() {
|
||||
AuroraApp.scope.launch {
|
||||
downloadDao.downloads().collectLatest { list ->
|
||||
// Check and trigger next download in queue, if any
|
||||
if (!list.any { it.downloadStatus == DownloadStatus.DOWNLOADING }) {
|
||||
val enqueuedDownloads = list.filter { it.downloadStatus == DownloadStatus.QUEUED }
|
||||
enqueuedDownloads.firstOrNull()?.let {
|
||||
try {
|
||||
Log.i(DOWNLOAD_WORKER, "Downloading ${it.packageName}")
|
||||
trigger(it)
|
||||
} catch (exception: Exception) {
|
||||
Log.i(DOWNLOAD_WORKER, "Failed to download app", exception)
|
||||
downloadDao.updateStatus(it.packageName, DownloadStatus.FAILED)
|
||||
private suspend fun observeDownloads() {
|
||||
downloadDao.downloads().collect { list ->
|
||||
try {
|
||||
if (list.none { it.downloadStatus == DownloadStatus.DOWNLOADING }) {
|
||||
list.find { it.downloadStatus == DownloadStatus.QUEUED }
|
||||
?.let { queuedDownload ->
|
||||
Log.i(TAG, "Enqueued download worker for ${queuedDownload.packageName}")
|
||||
trigger(queuedDownload)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
Log.e(TAG, "Failed to enqueue download worker", exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,8 +174,9 @@ class DownloadHelper @Inject constructor(
|
||||
// Ensure all app downloads are unique to preserve individual records
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniqueWork(
|
||||
"$DOWNLOAD_WORKER/${download.packageName}",
|
||||
ExistingWorkPolicy.KEEP, work
|
||||
"$DOWNLOAD_WORKER/${download.packageName}/${download.versionCode}",
|
||||
ExistingWorkPolicy.KEEP,
|
||||
work
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,13 +25,14 @@ import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_IDLE
|
||||
import com.aurora.store.util.Preferences.PREFERENCES_UPDATES_RESTRICTIONS_METERED
|
||||
import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_CHECK_INTERVAL
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.concurrent.TimeUnit.HOURS
|
||||
import java.util.concurrent.TimeUnit.MINUTES
|
||||
import javax.inject.Inject
|
||||
@@ -68,12 +69,12 @@ class UpdateHelper @Inject constructor(
|
||||
/**
|
||||
* Deletes invalid updates from database and starts observing events
|
||||
*/
|
||||
fun init() {
|
||||
AuroraApp.scope.launch {
|
||||
suspend fun init() {
|
||||
withContext(Dispatchers.IO) {
|
||||
deleteInvalidUpdates()
|
||||
}.invokeOnCompletion {
|
||||
observeUpdates()
|
||||
}
|
||||
|
||||
observeUpdates()
|
||||
}
|
||||
|
||||
private fun observeUpdates() {
|
||||
@@ -137,7 +138,7 @@ class UpdateHelper @Inject constructor(
|
||||
* @see [UpdateWorker]
|
||||
*/
|
||||
fun scheduleAutomatedCheck() {
|
||||
Log.i(TAG,"Scheduling periodic app updates!")
|
||||
Log.i(TAG, "Scheduling periodic app updates!")
|
||||
WorkManager.getInstance(context)
|
||||
.enqueueUniquePeriodicWork(
|
||||
UPDATE_WORKER,
|
||||
@@ -151,7 +152,7 @@ class UpdateHelper @Inject constructor(
|
||||
* @see [UpdateWorker]
|
||||
*/
|
||||
fun updateAutomatedCheck() {
|
||||
Log.i(TAG,"Updating periodic app updates!")
|
||||
Log.i(TAG, "Updating periodic app updates!")
|
||||
WorkManager.getInstance(context).updateWork(getAutoUpdateWork())
|
||||
}
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ class DownloadWorker @AssistedInject constructor(
|
||||
throw Exceptions.DownloadCancelledException()
|
||||
}
|
||||
|
||||
downloadFile(file)
|
||||
downloadFile(download.packageName, file)
|
||||
download.downloadedFiles++
|
||||
}
|
||||
} catch (exception: Exception) {
|
||||
@@ -298,8 +298,8 @@ class DownloadWorker @AssistedInject constructor(
|
||||
* @param gFile A [GPlayFile] to download
|
||||
* @return A [Boolean] indicating whether the file was downloaded or not.
|
||||
*/
|
||||
private suspend fun downloadFile(gFile: GPlayFile): Boolean = withContext(Dispatchers.IO) {
|
||||
Log.i(TAG, "Downloading ${gFile.name}")
|
||||
private suspend fun downloadFile(packageName: String, gFile: GPlayFile): Boolean = withContext(Dispatchers.IO) {
|
||||
Log.i(TAG, "Downloading $packageName @ ${gFile.name}")
|
||||
val file = PathUtil.getLocalFile(appContext, gFile, download)
|
||||
|
||||
// If file exists and has integrity intact, no need to download again
|
||||
|
||||
Reference in New Issue
Block a user