Show apps that we could not restore data for
This commit is contained in:
parent
690017c050
commit
7b27242625
6 changed files with 258 additions and 21 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
5
app/src/main/res/drawable/ic_launcher_default.xml
Normal file
5
app/src/main/res/drawable/ic_launcher_default.xml
Normal 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>
|
170
app/src/main/res/drawable/ic_launcher_default_background.xml
Normal file
170
app/src/main/res/drawable/ic_launcher_default_background.xml
Normal 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>
|
34
app/src/main/res/drawable/ic_launcher_default_foreground.xml
Normal file
34
app/src/main/res/drawable/ic_launcher_default_foreground.xml
Normal 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>
|
Loading…
Reference in a new issue