Refactor InstallResult to be more extensible
This commit is contained in:
parent
f45411d81b
commit
747384fb59
3 changed files with 51 additions and 15 deletions
|
@ -15,7 +15,6 @@ import androidx.recyclerview.widget.LinearLayoutManager.VERTICAL
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.stevesoltys.seedvault.R
|
||||
import com.stevesoltys.seedvault.restore.RestoreViewModel
|
||||
import com.stevesoltys.seedvault.restore.install.ApkInstallState.QUEUED
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
||||
class InstallProgressFragment : Fragment() {
|
||||
|
@ -75,12 +74,11 @@ class InstallProgressFragment : Fragment() {
|
|||
// skip this screen, if there are no apps to install
|
||||
if (installResult.isEmpty()) viewModel.onNextClicked()
|
||||
|
||||
val result = installResult.filterValues { it.state != QUEUED }
|
||||
val position = layoutManager.findFirstVisibleItemPosition()
|
||||
adapter.update(result.values)
|
||||
adapter.update(installResult.getNotQueued())
|
||||
if (position == 0) layoutManager.scrollToPosition(0)
|
||||
|
||||
result.getInProgress()?.let {
|
||||
installResult.getInProgress()?.let {
|
||||
progressBar.progress = it.progress
|
||||
progressBar.max = it.total
|
||||
}
|
||||
|
|
|
@ -1,28 +1,66 @@
|
|||
package com.stevesoltys.seedvault.restore.install
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import com.stevesoltys.seedvault.restore.install.ApkInstallState.IN_PROGRESS
|
||||
import com.stevesoltys.seedvault.restore.install.ApkInstallState.QUEUED
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
internal typealias InstallResult = Map<String, ApkInstallResult>
|
||||
internal interface InstallResult {
|
||||
/**
|
||||
* Returns true, if there is no packages to install and false otherwise.
|
||||
*/
|
||||
fun isEmpty(): Boolean
|
||||
|
||||
internal fun InstallResult.getInProgress(): ApkInstallResult? {
|
||||
val filtered = filterValues { result -> result.state == ApkInstallState.IN_PROGRESS }
|
||||
/**
|
||||
* Returns the [ApkInstallResult] of the package currently [IN_PROGRESS]
|
||||
* or null if there is no such package.
|
||||
*/
|
||||
fun getInProgress(): ApkInstallResult?
|
||||
|
||||
/**
|
||||
* Get all [ApkInstallResult]s that are not in state [QUEUED].
|
||||
*/
|
||||
fun getNotQueued(): Collection<ApkInstallResult>
|
||||
|
||||
/**
|
||||
* Get the [ApkInstallResult] for the given package name or null if none exists.
|
||||
*/
|
||||
operator fun get(packageName: String): ApkInstallResult?
|
||||
}
|
||||
|
||||
internal class MutableInstallResult(initialCapacity: Int) : InstallResult {
|
||||
|
||||
private val installResults = ConcurrentHashMap<String, ApkInstallResult>(initialCapacity)
|
||||
|
||||
override fun isEmpty() = installResults.isEmpty()
|
||||
|
||||
override fun getInProgress(): ApkInstallResult? {
|
||||
val filtered = installResults.filterValues { result -> result.state == IN_PROGRESS }
|
||||
if (filtered.isEmpty()) return null
|
||||
check(filtered.size == 1) { "More than one package in progress: ${filtered.keys}" }
|
||||
return filtered.values.first()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getNotQueued(): Collection<ApkInstallResult> {
|
||||
return installResults.filterValues { result -> result.state != QUEUED }.values
|
||||
}
|
||||
|
||||
override fun get(packageName: String) = installResults[packageName]
|
||||
|
||||
operator fun set(packageName: String, installResult: ApkInstallResult) {
|
||||
installResults[packageName] = installResult
|
||||
}
|
||||
|
||||
internal class MutableInstallResult(initialCapacity: Int) :
|
||||
ConcurrentHashMap<String, ApkInstallResult>(initialCapacity) {
|
||||
fun update(
|
||||
packageName: String,
|
||||
updateFun: (ApkInstallResult) -> ApkInstallResult
|
||||
): MutableInstallResult {
|
||||
val result = get(packageName)
|
||||
check(result != null) { "ApkRestoreResult for $packageName does not exist." }
|
||||
set(packageName, updateFun(result))
|
||||
installResults[packageName] = updateFun(result)
|
||||
return this
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal data class ApkInstallResult(
|
||||
|
|
|
@ -167,7 +167,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
@Test
|
||||
fun `test successful run`(@TempDir tmpDir: Path) = runBlocking {
|
||||
val installResult = MutableInstallResult(1).apply {
|
||||
put(
|
||||
set(
|
||||
packageName, ApkInstallResult(
|
||||
packageName,
|
||||
progress = 1,
|
||||
|
@ -244,7 +244,7 @@ internal class ApkRestoreTest : TransportTest() {
|
|||
every { installedPackageInfo.longVersionCode } returns packageMetadata.version!! - 1
|
||||
if (!willFail) {
|
||||
val installResult = MutableInstallResult(1).apply {
|
||||
put(
|
||||
set(
|
||||
packageName,
|
||||
ApkInstallResult(packageName, progress = 1, total = 1, state = SUCCEEDED)
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue