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.app.backup.IBackupObserver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.Log.INFO
|
import android.util.Log.INFO
|
||||||
import android.util.Log.isLoggable
|
import android.util.Log.isLoggable
|
||||||
|
@ -71,6 +72,10 @@ class NotificationBackupObserver(context: Context, private val userInitiated: Bo
|
||||||
|
|
||||||
fun getAppName(pm: PackageManager, packageId: String): CharSequence {
|
fun getAppName(pm: PackageManager, packageId: String): CharSequence {
|
||||||
if (packageId == MAGIC_PACKAGE_MANAGER) return packageId
|
if (packageId == MAGIC_PACKAGE_MANAGER) return packageId
|
||||||
|
return try {
|
||||||
val appInfo = pm.getApplicationInfo(packageId, 0)
|
val appInfo = pm.getApplicationInfo(packageId, 0)
|
||||||
return pm.getApplicationLabel(appInfo) ?: packageId
|
pm.getApplicationLabel(appInfo) ?: packageId
|
||||||
|
} catch (e: NameNotFoundException) {
|
||||||
|
packageId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.stevesoltys.seedvault.restore
|
package com.stevesoltys.seedvault.restore
|
||||||
|
|
||||||
|
import android.content.pm.PackageManager.NameNotFoundException
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.INVISIBLE
|
import android.view.View.INVISIBLE
|
||||||
|
@ -18,7 +19,9 @@ import java.util.*
|
||||||
|
|
||||||
internal class RestoreProgressAdapter : Adapter<PackageViewHolder>() {
|
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
|
private var isComplete = false
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PackageViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PackageViewHolder {
|
||||||
|
@ -32,15 +35,16 @@ internal class RestoreProgressAdapter : Adapter<PackageViewHolder>() {
|
||||||
holder.bind(items[position], position == 0)
|
holder.bind(items[position], position == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun add(packageName: String) {
|
fun add(item: AppRestoreResult) {
|
||||||
items.addFirst(packageName)
|
items.addFirst(item)
|
||||||
notifyItemInserted(0)
|
notifyItemInserted(0)
|
||||||
notifyItemRangeChanged(1, items.size - 1)
|
notifyItemRangeChanged(1, items.size - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setComplete() {
|
fun setComplete(): LinkedList<AppRestoreResult> {
|
||||||
isComplete = true
|
isComplete = true
|
||||||
notifyItemChanged(0)
|
notifyItemChanged(0)
|
||||||
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class PackageViewHolder(v: View) : ViewHolder(v) {
|
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 appStatus: ImageView = v.findViewById(R.id.appStatus)
|
||||||
private val progressBar: ProgressBar = v.findViewById(R.id.progressBar)
|
private val progressBar: ProgressBar = v.findViewById(R.id.progressBar)
|
||||||
|
|
||||||
init {
|
fun bind(item: AppRestoreResult, isLatest: Boolean) {
|
||||||
appStatus.setImageResource(R.drawable.ic_check_green)
|
if (item.packageName == MAGIC_PACKAGE_MANAGER) {
|
||||||
}
|
appIcon.setImageResource(R.drawable.ic_launcher_default)
|
||||||
|
|
||||||
fun bind(item: String, isLast: Boolean) {
|
|
||||||
if (item == MAGIC_PACKAGE_MANAGER) {
|
|
||||||
appIcon.setImageDrawable(pm.getApplicationIcon("android"))
|
|
||||||
appName.text = context.getString(R.string.restore_magic_package)
|
appName.text = context.getString(R.string.restore_magic_package)
|
||||||
} else {
|
} else {
|
||||||
appIcon.setImageDrawable(pm.getApplicationIcon(item))
|
try {
|
||||||
appName.text = getAppName(pm, item)
|
appIcon.setImageDrawable(pm.getApplicationIcon(item.packageName))
|
||||||
|
} catch (e: NameNotFoundException) {
|
||||||
|
appIcon.setImageResource(R.drawable.ic_launcher_default)
|
||||||
}
|
}
|
||||||
if (isLast && !isComplete) {
|
appName.text = getAppName(pm, item.packageName)
|
||||||
|
}
|
||||||
|
if (isLatest && !isComplete) {
|
||||||
appStatus.visibility = INVISIBLE
|
appStatus.visibility = INVISIBLE
|
||||||
progressBar.visibility = VISIBLE
|
progressBar.visibility = VISIBLE
|
||||||
} else {
|
} else {
|
||||||
|
appStatus.setImageResource(if (item.success) R.drawable.ic_check_green else R.drawable.ic_cancel_red)
|
||||||
appStatus.visibility = VISIBLE
|
appStatus.visibility = VISIBLE
|
||||||
progressBar.visibility = INVISIBLE
|
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 ->
|
viewModel.restoreProgress.observe(this, Observer { currentPackage ->
|
||||||
// TODO maybe check against metadata and add packages that weren't called as failed in the end
|
stayScrolledAtTop {
|
||||||
val position = layoutManager.findFirstVisibleItemPosition()
|
adapter.add(AppRestoreResult(currentPackage, true))
|
||||||
adapter.add(currentPackage)
|
}
|
||||||
if (position == 0) layoutManager.scrollToPosition(0)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.restoreBackupResult.observe(this, Observer { finished ->
|
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
|
button.isEnabled = true
|
||||||
if (finished.hasError()) {
|
if (finished.hasError()) {
|
||||||
backupNameView.text = finished.errorMsg
|
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