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 androidx.recyclerview.widget.RecyclerView
|
||||||
import com.stevesoltys.seedvault.R
|
import com.stevesoltys.seedvault.R
|
||||||
import com.stevesoltys.seedvault.restore.RestoreViewModel
|
import com.stevesoltys.seedvault.restore.RestoreViewModel
|
||||||
import com.stevesoltys.seedvault.restore.install.ApkInstallState.QUEUED
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||||
|
|
||||||
class InstallProgressFragment : Fragment() {
|
class InstallProgressFragment : Fragment() {
|
||||||
|
@ -75,12 +74,11 @@ class InstallProgressFragment : Fragment() {
|
||||||
// skip this screen, if there are no apps to install
|
// skip this screen, if there are no apps to install
|
||||||
if (installResult.isEmpty()) viewModel.onNextClicked()
|
if (installResult.isEmpty()) viewModel.onNextClicked()
|
||||||
|
|
||||||
val result = installResult.filterValues { it.state != QUEUED }
|
|
||||||
val position = layoutManager.findFirstVisibleItemPosition()
|
val position = layoutManager.findFirstVisibleItemPosition()
|
||||||
adapter.update(result.values)
|
adapter.update(installResult.getNotQueued())
|
||||||
if (position == 0) layoutManager.scrollToPosition(0)
|
if (position == 0) layoutManager.scrollToPosition(0)
|
||||||
|
|
||||||
result.getInProgress()?.let {
|
installResult.getInProgress()?.let {
|
||||||
progressBar.progress = it.progress
|
progressBar.progress = it.progress
|
||||||
progressBar.max = it.total
|
progressBar.max = it.total
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,66 @@
|
||||||
package com.stevesoltys.seedvault.restore.install
|
package com.stevesoltys.seedvault.restore.install
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
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
|
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]
|
||||||
if (filtered.isEmpty()) return null
|
* or null if there is no such package.
|
||||||
check(filtered.size == 1) { "More than one package in progress: ${filtered.keys}" }
|
*/
|
||||||
return filtered.values.first()
|
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) :
|
internal class MutableInstallResult(initialCapacity: Int) : InstallResult {
|
||||||
ConcurrentHashMap<String, ApkInstallResult>(initialCapacity) {
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
fun update(
|
fun update(
|
||||||
packageName: String,
|
packageName: String,
|
||||||
updateFun: (ApkInstallResult) -> ApkInstallResult
|
updateFun: (ApkInstallResult) -> ApkInstallResult
|
||||||
): MutableInstallResult {
|
): MutableInstallResult {
|
||||||
val result = get(packageName)
|
val result = get(packageName)
|
||||||
check(result != null) { "ApkRestoreResult for $packageName does not exist." }
|
check(result != null) { "ApkRestoreResult for $packageName does not exist." }
|
||||||
set(packageName, updateFun(result))
|
installResults[packageName] = updateFun(result)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal data class ApkInstallResult(
|
internal data class ApkInstallResult(
|
||||||
|
|
|
@ -167,7 +167,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
@Test
|
@Test
|
||||||
fun `test successful run`(@TempDir tmpDir: Path) = runBlocking {
|
fun `test successful run`(@TempDir tmpDir: Path) = runBlocking {
|
||||||
val installResult = MutableInstallResult(1).apply {
|
val installResult = MutableInstallResult(1).apply {
|
||||||
put(
|
set(
|
||||||
packageName, ApkInstallResult(
|
packageName, ApkInstallResult(
|
||||||
packageName,
|
packageName,
|
||||||
progress = 1,
|
progress = 1,
|
||||||
|
@ -244,7 +244,7 @@ internal class ApkRestoreTest : TransportTest() {
|
||||||
every { installedPackageInfo.longVersionCode } returns packageMetadata.version!! - 1
|
every { installedPackageInfo.longVersionCode } returns packageMetadata.version!! - 1
|
||||||
if (!willFail) {
|
if (!willFail) {
|
||||||
val installResult = MutableInstallResult(1).apply {
|
val installResult = MutableInstallResult(1).apply {
|
||||||
put(
|
set(
|
||||||
packageName,
|
packageName,
|
||||||
ApkInstallResult(packageName, progress = 1, total = 1, state = SUCCEEDED)
|
ApkInstallResult(packageName, progress = 1, total = 1, state = SUCCEEDED)
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue