Skip to content

Commit

Permalink
Download Progress
Browse files Browse the repository at this point in the history
* Disentangle MainViewModel.
* Add Download Progress for Play Source and GitHub source.
* Improve play token refresh.
* TV UI is now default.
* ApkMirror is disabled by default.
* Random delay on Alarm is reduced to -5 +5 if ApkMirror is disabled.
  • Loading branch information
rumboalla committed Mar 27, 2024
1 parent b10fb75 commit 72ef107
Show file tree
Hide file tree
Showing 26 changed files with 343 additions and 189 deletions.
3 changes: 0 additions & 3 deletions app/src/main/kotlin/com/apkupdater/data/snack/ISnack.kt

This file was deleted.

9 changes: 0 additions & 9 deletions app/src/main/kotlin/com/apkupdater/data/snack/InstallSnack.kt

This file was deleted.

12 changes: 12 additions & 0 deletions app/src/main/kotlin/com/apkupdater/data/snack/TextSnack.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.apkupdater.data.snack

import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarVisuals


class TextSnack(
override val message: String,
override val actionLabel: String? = null,
override val duration: SnackbarDuration = SnackbarDuration.Short,
override val withDismissAction: Boolean = true
): SnackbarVisuals
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.apkupdater.data.ui

data class AppInstallProgress(val id: Int, val progress: Long = 0L, val total: Long = 0L)
11 changes: 11 additions & 0 deletions app/src/main/kotlin/com/apkupdater/data/ui/AppUpdate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ data class AppUpdate(
val link: Link = Link.Empty,
val whatsNew: String = "",
val isInstalling: Boolean = false,
val total: Long = 0L,
val progress: Long = 0L,
val id: Int = "${source.name}.$packageName.$versionCode.$version".hashCode()
)

Expand All @@ -32,3 +34,12 @@ fun MutableList<AppUpdate>.removeId(id: Int): List<AppUpdate> {
if (index != -1) this.removeAt(index)
return this
}

fun MutableList<AppUpdate>.setProgress(progress: AppInstallProgress): MutableList<AppUpdate> {
val index = this.indexOf(progress.id)
if (index != -1) {
if (progress.progress != 0L) this[index] = this[index].copy(progress = progress.progress)
if (progress.total != 0L) this[index] = this[index].copy(total = progress.total)
}
return this
}
6 changes: 4 additions & 2 deletions app/src/main/kotlin/com/apkupdater/data/ui/Link.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.apkupdater.data.ui

import com.aurora.gplayapi.data.models.File


sealed class Link {
data object Empty: Link()
data class Url(val link: String): Link()
data class Url(val link: String, val size: Long = 0L): Link()
data class Xapk(val link: String): Link()
data class Play(val getInstallFiles: () -> List<String>): Link()
data class Play(val getInstallFiles: () -> List<File>): Link()
}
27 changes: 21 additions & 6 deletions app/src/main/kotlin/com/apkupdater/di/MainModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ import com.apkupdater.service.AptoideService
import com.apkupdater.service.FdroidService
import com.apkupdater.service.GitHubService
import com.apkupdater.service.GitLabService
import com.apkupdater.util.Badger
import com.apkupdater.util.Clipboard
import com.apkupdater.util.Downloader
import com.apkupdater.util.InstallLog
import com.apkupdater.util.SessionInstaller
import com.apkupdater.util.SnackBar
import com.apkupdater.util.Stringer
import com.apkupdater.util.Themer
import com.apkupdater.util.UpdatesNotification
import com.apkupdater.util.addUserAgentInterceptor
import com.apkupdater.util.isAndroidTv
Expand Down Expand Up @@ -164,16 +169,26 @@ val mainModule = module {

single { Clipboard(androidContext()) }

single { SessionInstaller(get()) }
single { SessionInstaller(get(), get()) }

viewModel { MainViewModel(get()) }
single { SnackBar() }

viewModel { parameters -> AppsViewModel(parameters.get(), get(), get()) }
single { Badger() }

viewModel { parameters -> UpdatesViewModel(parameters.get(), get(), get(), get(), get()) }
single { Themer(get()) }

viewModel { parameters -> SettingsViewModel(parameters.get(), get(), get(), WorkManager.getInstance(get()), get(), get()) }
single { Stringer(androidContext()) }

viewModel { parameters -> SearchViewModel(parameters.get(), get(), get(), get(), get()) }
single { InstallLog() }

viewModel { MainViewModel(get(), get()) }

viewModel { AppsViewModel(get(), get(), get()) }

viewModel { UpdatesViewModel(get(), get(), get(), get(), get(), get(), get(), get()) }

viewModel { SettingsViewModel(get(), get(), WorkManager.getInstance(get()), get(), get(), get(), get()) }

viewModel { SearchViewModel(get(), get(), get(), get(), get(), get(), get(), get()) }

}
7 changes: 4 additions & 3 deletions app/src/main/kotlin/com/apkupdater/prefs/Prefs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ class Prefs(
val excludeStore = boolean("excludeStore", defValue = false, backed = true)
val portraitColumns = int("portraitColumns", 3, true)
val landscapeColumns = int("landscapeColumns", 6, true)
val playTextAnimations = boolean("playTextAnimaions", defValue = true, backed = true)
val playTextAnimations = boolean("playTextAnimations", defValue = true, backed = true)
val ignoreAlpha = boolean("ignoreAlpha", defValue = true, backed = true)
val ignoreBeta = boolean("ignoreBeta", defValue = true, backed = true)
val ignorePreRelease = boolean("ignorePreRelease", defValue = true, backed = true)
val useSafeStores = boolean("useSafeStores", defValue = true, backed = true)
val useApkMirror = boolean("useApkMirror", defValue = !isAndroidTv, backed = true)
val useApkMirror = boolean("useApkMirror", defValue = false, backed = true)
val useGitHub = boolean("useGitHub", defValue = true, backed = true)
val useGitLab = boolean("useGitLab", defValue = true, backed = true)
val useFdroid = boolean("useFdroid", defValue = true, backed = true)
Expand All @@ -34,9 +34,10 @@ class Prefs(
val enableAlarm = boolean("enableAlarm", defValue = false, backed = true)
val alarmHour = int("alarmHour", defValue = 12, backed = true)
val alarmFrequency = int("alarmFrequency", 0, backed = true)
val androidTvUi = boolean("androidTvUi", defValue = isAndroidTv, backed = true)
val androidTvUi = boolean("androidTvUi", defValue = true, backed = true)
val rootInstall = boolean("rootInstall", defValue = false, backed = true)
val theme = int("theme", defValue = 0, backed = true)
val lastTab = string("lastTab", defValue = Screen.Updates.route, backed = true)
val playAuthData = json("playAuthData", AuthData("", ""), true)
val lastPlayCheck = long("lastPlayCheck", 0L, true)
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class GitHubRepository(
versionCode = 0L,
oldVersionCode = app?.versionCode ?: 0L,
source = GitHubSource,
link = Link.Url(findApkAssetArch(releases[0].assets, extra)),
link = findApkAssetArch(releases[0].assets, extra).let { Link.Url(it.browser_download_url, it.size) },
whatsNew = releases[0].body,
iconUri = if (apps == null) Uri.parse(releases[0].author.avatar_url) else Uri.EMPTY
)))
Expand Down Expand Up @@ -154,49 +154,49 @@ class GitHubRepository(
private fun findApkAssetArch(
assets: List<GitHubReleaseAsset>,
extra: Regex?
): String {
): GitHubReleaseAsset {
val apks = assets
.filter { it.browser_download_url.endsWith(".apk", true) }
.filter { filterExtra(it, extra) }

when {
apks.isEmpty() -> return ""
apks.size == 1 -> return apks.first().browser_download_url
apks.isEmpty() -> return GitHubReleaseAsset(0L, "")
apks.size == 1 -> return apks.first()
else -> {
// Try to match exact arch
Build.SUPPORTED_ABIS.forEach { arch ->
apks.forEach { apk ->
if (apk.browser_download_url.contains(arch, true)) {
return apk.browser_download_url
return apk
}
}
}
// Try to match arm64
if (Build.SUPPORTED_ABIS.contains("arm64-v8a")) {
apks.forEach { apk ->
if (apk.browser_download_url.contains("arm64", true)) {
return apk.browser_download_url
return apk
}
}
}
// Try to match x64
if (Build.SUPPORTED_ABIS.contains("x86_64")) {
apks.forEach { apk ->
if (apk.browser_download_url.contains("x64", true)) {
return apk.browser_download_url
return apk
}
}
}
// Try to match arm
if (Build.SUPPORTED_ABIS.contains("armeabi-v7a")) {
apks.forEach { apk ->
if (apk.browser_download_url.contains("arm", true)) {
return apk.browser_download_url
return apk
}
}
}
// If no match, return biggest apk in the hope it's universal
return apks.maxByOrNull { it.size }?.browser_download_url.orEmpty()
return apks.maxByOrNull { it.size } ?: GitHubReleaseAsset(0L, "")
}
}
}
Expand Down
38 changes: 18 additions & 20 deletions app/src/main/kotlin/com/apkupdater/repository/PlayRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,10 @@ import com.aurora.gplayapi.helpers.AppDetailsHelper
import com.aurora.gplayapi.helpers.PurchaseHelper
import com.aurora.gplayapi.helpers.SearchHelper
import com.google.gson.Gson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach


@OptIn(FlowPreview::class)
class PlayRepository(
private val context: Context,
private val gson: Gson,
Expand All @@ -41,16 +33,8 @@ class PlayRepository(
const val AUTH_URL = "https://auroraoss.com/api/auth"
}

init {
// TODO: Needs testing.
PlayHttpClient.responseCode
.filter { it == 401 }
.debounce(60 * 5 * 1_000)
.onEach { runCatching { refreshAuth() }.getOrNull() }
.launchIn(CoroutineScope(Dispatchers.IO))
}

private fun refreshAuth(): AuthData {
Log.i("PlayRepository", "Refreshing token.")
val properties = NativeDeviceInfoProvider(context).getNativeDeviceProperties()
val playResponse = PlayHttpClient.postAuth(AUTH_URL, gson.toJson(properties).toByteArray())
if (playResponse.isSuccessful) {
Expand All @@ -66,6 +50,21 @@ class PlayRepository(
if (savedData.email.isEmpty()) {
return refreshAuth()
}
if (System.currentTimeMillis() - prefs.lastPlayCheck.get() > 60 * 60 * 1_000) {
// Update check time
prefs.lastPlayCheck.put(System.currentTimeMillis())
Log.i("PlayRepository", "Checking token validity.")

// 1h has passed check if token still works
val app = AppDetailsHelper(savedData)
.using(PlayHttpClient)
.getAppByPackageName("com.google.android.gm")

if (app.packageName.isEmpty()) {
return refreshAuth()
}
Log.i("PlayRepository", "Token still valid.")
}
return savedData
}

Expand All @@ -77,7 +76,7 @@ class PlayRepository(
.using(PlayHttpClient)
.searchResults(text)
.appList
.take(5)
.take(10)
.map { it.toAppUpdate(::getInstallFiles) }
emit(Result.success(updates))
} else {
Expand Down Expand Up @@ -118,12 +117,11 @@ class PlayRepository(
.using(PlayHttpClient)
.purchase(app.packageName, app.versionCode, app.offerType)
.filter { it.type == File.FileType.BASE || it.type == File.FileType.SPLIT }
.map { it.url }

}

fun App.toAppUpdate(
getInstallFiles: (App) -> List<String>,
getInstallFiles: (App) -> List<File>,
oldVersion: String = "",
oldVersionCode: Long = 0L
) = AppUpdate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import com.apkupdater.data.ui.AppInstalled
import com.apkupdater.data.ui.AppUpdate
import com.apkupdater.data.ui.Source
import com.apkupdater.util.getAppName
import com.apkupdater.util.to2f
import com.apkupdater.util.toAnnotatedString


Expand Down Expand Up @@ -79,7 +80,12 @@ fun TvInstallButton(
onClick = { onInstall(app.packageName) }
) {
if (app.isInstalling) {
CircularProgressIndicator(Modifier.size(24.dp))
if (app.total != 0L && app.progress != 0L) {
val p = (app.progress.toFloat() / app.total) * 100f
Text("${p.to2f()}%")
} else {
CircularProgressIndicator(Modifier.size(24.dp))
}
} else {
Text(stringResource(R.string.install_cd))
}
Expand Down
Loading

0 comments on commit 72ef107

Please sign in to comment.