Show when package restore failed

This commit is contained in:
Torsten Grote 2020-01-09 11:59:15 -03:00
parent 9f01d09962
commit 5632f11878
No known key found for this signature in database
GPG key ID: 3E5F77D92CF891FF
4 changed files with 36 additions and 8 deletions

View file

@ -35,16 +35,25 @@ internal class RestoreProgressAdapter : Adapter<PackageViewHolder>() {
holder.bind(items[position], position == 0) holder.bind(items[position], position == 0)
} }
fun getLatest(): AppRestoreResult {
return items[0]
}
fun setLatestFailed() {
items[0] = AppRestoreResult(items[0].packageName, false)
notifyItemChanged(0, items[0])
}
fun add(item: AppRestoreResult) { fun add(item: AppRestoreResult) {
items.addFirst(item) items.addFirst(item)
notifyItemInserted(0) notifyItemInserted(0)
notifyItemRangeChanged(1, items.size - 1) notifyItemRangeChanged(1, items.size - 1)
} }
fun setComplete(): LinkedList<AppRestoreResult> { fun setComplete(): List<String> {
isComplete = true isComplete = true
notifyItemChanged(0) notifyItemChanged(0)
return items return items.map { it.packageName }
} }
inner class PackageViewHolder(v: View) : ViewHolder(v) { inner class PackageViewHolder(v: View) : ViewHolder(v) {

View file

@ -53,20 +53,23 @@ class RestoreProgressFragment : Fragment() {
viewModel.restoreProgress.observe(this, Observer { currentPackage -> viewModel.restoreProgress.observe(this, Observer { currentPackage ->
stayScrolledAtTop { stayScrolledAtTop {
val latest = adapter.getLatest()
if (viewModel.isFailedPackage(latest.packageName)) {
adapter.setLatestFailed()
}
adapter.add(AppRestoreResult(currentPackage, true)) adapter.add(AppRestoreResult(currentPackage, true))
} }
}) })
viewModel.restoreBackupResult.observe(this, Observer { finished -> viewModel.restoreBackupResult.observe(this, Observer { finished ->
val list = adapter.setComplete() val seenPackages = adapter.setComplete()
stayScrolledAtTop { stayScrolledAtTop {
// add missing packages as failed // add missing packages as failed
val restorableBackup = viewModel.chosenRestorableBackup.value!! val restorableBackup = viewModel.chosenRestorableBackup.value!!
val expectedPackages = restorableBackup.packageMetadataMap.keys val expectedPackages = restorableBackup.packageMetadataMap.keys
expectedPackages.removeAll(seenPackages)
for (packageName: String in expectedPackages) { for (packageName: String in expectedPackages) {
if (AppRestoreResult(packageName, true) !in list) { adapter.add(AppRestoreResult(packageName, false))
adapter.add(AppRestoreResult(packageName, false))
}
} }
} }

View file

@ -164,6 +164,8 @@ internal class RestoreViewModel(
} }
} }
fun isFailedPackage(packageName: String) = restoreCoordinator.isFailedPackage(packageName)
override fun onCleared() { override fun onCleared() {
super.onCleared() super.onCleared()
closeSession() closeSession()

View file

@ -20,7 +20,8 @@ import java.io.IOException
private class RestoreCoordinatorState( private class RestoreCoordinatorState(
internal val token: Long, internal val token: Long,
internal val packages: Iterator<PackageInfo>) internal val packages: Iterator<PackageInfo>,
internal var currentPackage: String? = null)
private val TAG = RestoreCoordinator::class.java.simpleName private val TAG = RestoreCoordinator::class.java.simpleName
@ -33,6 +34,7 @@ internal class RestoreCoordinator(
private var state: RestoreCoordinatorState? = null private var state: RestoreCoordinatorState? = null
private var backupMetadata: LongSparseArray<BackupMetadata>? = null private var backupMetadata: LongSparseArray<BackupMetadata>? = null
private val failedPackages = ArrayList<String>()
/** /**
* Get the set of all backups currently available over this transport. * Get the set of all backups currently available over this transport.
@ -103,6 +105,7 @@ internal class RestoreCoordinator(
check(state == null) { "Started new restore with existing state" } check(state == null) { "Started new restore with existing state" }
Log.i(TAG, "Start restore with ${packages.map { info -> info.packageName }}") Log.i(TAG, "Start restore with ${packages.map { info -> info.packageName }}")
state = RestoreCoordinatorState(token, packages.iterator()) state = RestoreCoordinatorState(token, packages.iterator())
failedPackages.clear()
return TRANSPORT_OK return TRANSPORT_OK
} }
@ -146,11 +149,13 @@ internal class RestoreCoordinator(
kv.hasDataForPackage(state.token, packageInfo) -> { kv.hasDataForPackage(state.token, packageInfo) -> {
Log.i(TAG, "Found K/V data for $packageName.") Log.i(TAG, "Found K/V data for $packageName.")
kv.initializeState(state.token, packageInfo) kv.initializeState(state.token, packageInfo)
state.currentPackage = packageName
TYPE_KEY_VALUE TYPE_KEY_VALUE
} }
full.hasDataForPackage(state.token, packageInfo) -> { full.hasDataForPackage(state.token, packageInfo) -> {
Log.i(TAG, "Found full backup data for $packageName.") Log.i(TAG, "Found full backup data for $packageName.")
full.initializeState(state.token, packageInfo) full.initializeState(state.token, packageInfo)
state.currentPackage = packageName
TYPE_FULL_STREAM TYPE_FULL_STREAM
} }
else -> { else -> {
@ -160,6 +165,7 @@ internal class RestoreCoordinator(
} }
} catch (e: IOException) { } catch (e: IOException) {
Log.e(TAG, "Error finding restore data for $packageName.", e) Log.e(TAG, "Error finding restore data for $packageName.", e)
failedPackages.add(packageName)
return null return null
} }
return RestoreDescription(packageName, type) return RestoreDescription(packageName, type)
@ -174,7 +180,12 @@ internal class RestoreCoordinator(
* @return the same error codes as [startRestore]. * @return the same error codes as [startRestore].
*/ */
fun getRestoreData(data: ParcelFileDescriptor): Int { fun getRestoreData(data: ParcelFileDescriptor): Int {
return kv.getRestoreData(data) return kv.getRestoreData(data).apply {
if (this != TRANSPORT_OK) {
// add current package to failed ones
state?.currentPackage?.let { failedPackages.add(it) }
}
}
} }
/** /**
@ -195,6 +206,7 @@ internal class RestoreCoordinator(
* or will call [finishRestore] to shut down the restore operation. * or will call [finishRestore] to shut down the restore operation.
*/ */
fun abortFullRestore(): Int { fun abortFullRestore(): Int {
state?.currentPackage?.let { failedPackages.add(it) }
return full.abortFullRestore() return full.abortFullRestore()
} }
@ -218,4 +230,6 @@ internal class RestoreCoordinator(
return result return result
} }
fun isFailedPackage(packageName: String) = packageName in failedPackages
} }