Merge branch 'dev' into 'master'
dev See merge request AuroraOSS/AuroraStore!451
This commit is contained in:
@@ -95,10 +95,8 @@ class AuroraApp : Application(), Configuration.Provider, SingletonImageLoader.Fa
|
|||||||
NotificationUtil.createNotificationChannel(this)
|
NotificationUtil.createNotificationChannel(this)
|
||||||
|
|
||||||
// Initialize Download and Update helpers to observe and trigger downloads
|
// Initialize Download and Update helpers to observe and trigger downloads
|
||||||
scope.launch {
|
downloadHelper.init()
|
||||||
downloadHelper.init()
|
updateHelper.init()
|
||||||
updateHelper.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
//Register broadcast receiver for package install/uninstall
|
//Register broadcast receiver for package install/uninstall
|
||||||
ContextCompat.registerReceiver(
|
ContextCompat.registerReceiver(
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ import com.aurora.store.data.room.update.Update
|
|||||||
import com.aurora.store.data.work.DownloadWorker
|
import com.aurora.store.data.work.DownloadWorker
|
||||||
import com.aurora.store.util.PathUtil
|
import com.aurora.store.util.PathUtil
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,16 +50,16 @@ class DownloadHelper @Inject constructor(
|
|||||||
/**
|
/**
|
||||||
* Removes failed download from the queue and starts observing for newly enqueued apps.
|
* Removes failed download from the queue and starts observing for newly enqueued apps.
|
||||||
*/
|
*/
|
||||||
suspend fun init() {
|
fun init() {
|
||||||
withContext(Dispatchers.IO) {
|
AuroraApp.scope.launch {
|
||||||
cancelFailedDownloads(downloadDao.downloads().firstOrNull() ?: emptyList())
|
cancelFailedDownloads(downloadDao.downloads().firstOrNull() ?: emptyList())
|
||||||
|
}.invokeOnCompletion {
|
||||||
|
observeDownloads()
|
||||||
}
|
}
|
||||||
|
|
||||||
observeDownloads()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun observeDownloads() {
|
private fun observeDownloads() {
|
||||||
downloadDao.downloads().collect { list ->
|
downloadDao.downloads().onEach { list ->
|
||||||
try {
|
try {
|
||||||
if (list.none { it.downloadStatus == DownloadStatus.DOWNLOADING }) {
|
if (list.none { it.downloadStatus == DownloadStatus.DOWNLOADING }) {
|
||||||
list.find { it.downloadStatus == DownloadStatus.QUEUED }
|
list.find { it.downloadStatus == DownloadStatus.QUEUED }
|
||||||
@@ -70,7 +71,7 @@ class DownloadHelper @Inject constructor(
|
|||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
Log.e(TAG, "Failed to enqueue download worker", exception)
|
Log.e(TAG, "Failed to enqueue download worker", exception)
|
||||||
}
|
}
|
||||||
}
|
}.launchIn(AuroraApp.scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,14 +25,13 @@ 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.PREFERENCES_UPDATES_RESTRICTIONS_METERED
|
||||||
import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_CHECK_INTERVAL
|
import com.aurora.store.util.Preferences.PREFERENCE_UPDATES_CHECK_INTERVAL
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.firstOrNull
|
import kotlinx.coroutines.flow.firstOrNull
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.launch
|
||||||
import java.util.concurrent.TimeUnit.HOURS
|
import java.util.concurrent.TimeUnit.HOURS
|
||||||
import java.util.concurrent.TimeUnit.MINUTES
|
import java.util.concurrent.TimeUnit.MINUTES
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -69,12 +68,12 @@ class UpdateHelper @Inject constructor(
|
|||||||
/**
|
/**
|
||||||
* Deletes invalid updates from database and starts observing events
|
* Deletes invalid updates from database and starts observing events
|
||||||
*/
|
*/
|
||||||
suspend fun init() {
|
fun init() {
|
||||||
withContext(Dispatchers.IO) {
|
AuroraApp.scope.launch {
|
||||||
deleteInvalidUpdates()
|
deleteInvalidUpdates()
|
||||||
|
}.invokeOnCompletion {
|
||||||
|
observeUpdates()
|
||||||
}
|
}
|
||||||
|
|
||||||
observeUpdates()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeUpdates() {
|
private fun observeUpdates() {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
|
import androidx.core.graphics.scale
|
||||||
import androidx.hilt.work.HiltWorker
|
import androidx.hilt.work.HiltWorker
|
||||||
import androidx.work.ForegroundInfo
|
import androidx.work.ForegroundInfo
|
||||||
import androidx.work.WorkInfo.Companion.STOP_REASON_CANCELLED_BY_APP
|
import androidx.work.WorkInfo.Companion.STOP_REASON_CANCELLED_BY_APP
|
||||||
@@ -63,9 +64,9 @@ import com.aurora.gplayapi.data.models.File as GPlayFile
|
|||||||
*/
|
*/
|
||||||
@HiltWorker
|
@HiltWorker
|
||||||
class DownloadWorker @AssistedInject constructor(
|
class DownloadWorker @AssistedInject constructor(
|
||||||
|
authProvider: AuthProvider,
|
||||||
private val downloadDao: DownloadDao,
|
private val downloadDao: DownloadDao,
|
||||||
private val appInstaller: AppInstaller,
|
private val appInstaller: AppInstaller,
|
||||||
private val authProvider: AuthProvider,
|
|
||||||
private val httpClient: IHttpClient,
|
private val httpClient: IHttpClient,
|
||||||
private val purchaseHelper: PurchaseHelper,
|
private val purchaseHelper: PurchaseHelper,
|
||||||
@Assisted private val appContext: Context,
|
@Assisted private val appContext: Context,
|
||||||
@@ -85,8 +86,6 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
private val NOTIFICATION_ID: Int = 200
|
private val NOTIFICATION_ID: Int = 200
|
||||||
|
|
||||||
object Exceptions {
|
object Exceptions {
|
||||||
class InvalidAuthDataException : Exception("AuthData is invalid")
|
|
||||||
class NoPackageNameException : Exception("No packagename provided")
|
|
||||||
class NoNetworkException : Exception("No network available")
|
class NoNetworkException : Exception("No network available")
|
||||||
class NothingToDownloadException : Exception("Failed to purchase app")
|
class NothingToDownloadException : Exception("Failed to purchase app")
|
||||||
class DownloadFailedException : Exception("Download failed")
|
class DownloadFailedException : Exception("Download failed")
|
||||||
@@ -97,23 +96,15 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
super.doWork()
|
super.doWork()
|
||||||
|
|
||||||
// Bail out immediately if authData is not valid
|
|
||||||
if (!authProvider.isSavedAuthDataValid()) return onFailure(Exceptions.InvalidAuthDataException())
|
|
||||||
|
|
||||||
// Fetch required data for download
|
// Fetch required data for download
|
||||||
try {
|
try {
|
||||||
val packageName = inputData.getString(DownloadHelper.PACKAGE_NAME)
|
download = downloadDao.getDownload(inputData.getString(DownloadHelper.PACKAGE_NAME)!!)
|
||||||
|
|
||||||
// Bail out if no package name is provided
|
|
||||||
if (packageName.isNullOrBlank()) return onFailure(Exceptions.NoPackageNameException())
|
|
||||||
|
|
||||||
download = downloadDao.getDownload(packageName)
|
|
||||||
|
|
||||||
val response = (httpClient as HttpClient).call(download.iconURL).body
|
val response = (httpClient as HttpClient).call(download.iconURL).body
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
val bitmap =
|
val bitmap =
|
||||||
BitmapFactory.decodeStream(withContext(Dispatchers.IO) { response.byteStream() })
|
BitmapFactory.decodeStream(withContext(Dispatchers.IO) { response.byteStream() })
|
||||||
icon = Bitmap.createScaledBitmap(bitmap, 96, 96, true)
|
icon = bitmap.scale(96, 96)
|
||||||
}
|
}
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
return onFailure(exception)
|
return onFailure(exception)
|
||||||
|
|||||||
Reference in New Issue
Block a user