Show apps that we could not restore data for

This commit is contained in:
Torsten Grote 2020-01-09 09:50:09 -03:00
parent 690017c050
commit 7b27242625
No known key found for this signature in database
GPG key ID: 3E5F77D92CF891FF
6 changed files with 258 additions and 21 deletions

View file

@ -4,6 +4,7 @@ import android.app.backup.BackupProgress
import android.app.backup.IBackupObserver
import android.content.Context
import android.content.pm.PackageManager
import android.content.pm.PackageManager.NameNotFoundException
import android.util.Log
import android.util.Log.INFO
import android.util.Log.isLoggable
@ -71,6 +72,10 @@ class NotificationBackupObserver(context: Context, private val userInitiated: Bo
fun getAppName(pm: PackageManager, packageId: String): CharSequence {
if (packageId == MAGIC_PACKAGE_MANAGER) return packageId
val appInfo = pm.getApplicationInfo(packageId, 0)
return pm.getApplicationLabel(appInfo) ?: packageId
return try {
val appInfo = pm.getApplicationInfo(packageId, 0)
pm.getApplicationLabel(appInfo) ?: packageId
} catch (e: NameNotFoundException) {
packageId
}
}

View file

@ -1,5 +1,6 @@
package com.stevesoltys.seedvault.restore
import android.content.pm.PackageManager.NameNotFoundException
import android.view.LayoutInflater
import android.view.View
import android.view.View.INVISIBLE
@ -18,7 +19,9 @@ import java.util.*
internal class RestoreProgressAdapter : Adapter<PackageViewHolder>() {
private val items = LinkedList<String>().apply { add(MAGIC_PACKAGE_MANAGER) }
private val items = LinkedList<AppRestoreResult>().apply {
add(AppRestoreResult(MAGIC_PACKAGE_MANAGER, true))
}
private var isComplete = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PackageViewHolder {
@ -32,15 +35,16 @@ internal class RestoreProgressAdapter : Adapter<PackageViewHolder>() {
holder.bind(items[position], position == 0)
}
fun add(packageName: String) {
items.addFirst(packageName)
fun add(item: AppRestoreResult) {
items.addFirst(item)
notifyItemInserted(0)
notifyItemRangeChanged(1, items.size - 1)
}
fun setComplete() {
fun setComplete(): LinkedList<AppRestoreResult> {
isComplete = true
notifyItemChanged(0)
return items
}
inner class PackageViewHolder(v: View) : ViewHolder(v) {
@ -52,22 +56,23 @@ internal class RestoreProgressAdapter : Adapter<PackageViewHolder>() {
private val appStatus: ImageView = v.findViewById(R.id.appStatus)
private val progressBar: ProgressBar = v.findViewById(R.id.progressBar)
init {
appStatus.setImageResource(R.drawable.ic_check_green)
}
fun bind(item: String, isLast: Boolean) {
if (item == MAGIC_PACKAGE_MANAGER) {
appIcon.setImageDrawable(pm.getApplicationIcon("android"))
fun bind(item: AppRestoreResult, isLatest: Boolean) {
if (item.packageName == MAGIC_PACKAGE_MANAGER) {
appIcon.setImageResource(R.drawable.ic_launcher_default)
appName.text = context.getString(R.string.restore_magic_package)
} else {
appIcon.setImageDrawable(pm.getApplicationIcon(item))
appName.text = getAppName(pm, item)
try {
appIcon.setImageDrawable(pm.getApplicationIcon(item.packageName))
} catch (e: NameNotFoundException) {
appIcon.setImageResource(R.drawable.ic_launcher_default)
}
appName.text = getAppName(pm, item.packageName)
}
if (isLast && !isComplete) {
if (isLatest && !isComplete) {
appStatus.visibility = INVISIBLE
progressBar.visibility = VISIBLE
} else {
appStatus.setImageResource(if (item.success) R.drawable.ic_check_green else R.drawable.ic_cancel_red)
appStatus.visibility = VISIBLE
progressBar.visibility = INVISIBLE
}
@ -76,3 +81,5 @@ internal class RestoreProgressAdapter : Adapter<PackageViewHolder>() {
}
}
data class AppRestoreResult(val packageName: String, val success: Boolean)

View file

@ -52,14 +52,24 @@ class RestoreProgressFragment : Fragment() {
})
viewModel.restoreProgress.observe(this, Observer { currentPackage ->
// TODO maybe check against metadata and add packages that weren't called as failed in the end
val position = layoutManager.findFirstVisibleItemPosition()
adapter.add(currentPackage)
if (position == 0) layoutManager.scrollToPosition(0)
stayScrolledAtTop {
adapter.add(AppRestoreResult(currentPackage, true))
}
})
viewModel.restoreBackupResult.observe(this, Observer { finished ->
adapter.setComplete()
val list = adapter.setComplete()
stayScrolledAtTop {
// add missing packages as failed
val restorableBackup = viewModel.chosenRestorableBackup.value!!
val expectedPackages = restorableBackup.packageMetadataMap.keys
for (packageName: String in expectedPackages) {
if (AppRestoreResult(packageName, true) !in list) {
adapter.add(AppRestoreResult(packageName, false))
}
}
}
button.isEnabled = true
if (finished.hasError()) {
backupNameView.text = finished.errorMsg
@ -71,4 +81,10 @@ class RestoreProgressFragment : Fragment() {
})
}
private fun stayScrolledAtTop(add: () -> Unit) {
val position = layoutManager.findFirstVisibleItemPosition()
add.invoke()
if (position == 0) layoutManager.scrollToPosition(0)
}
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_default_background" />
<foreground android:drawable="@drawable/ic_launcher_default_foreground" />
</adaptive-icon>

View file

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View file

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeWidth="1"
android:strokeColor="#00000000">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>