Show restore data progress bar and improve readability of log messages
This commit is contained in:
parent
1924db7779
commit
3f73119b52
10 changed files with 49 additions and 105 deletions
|
@ -28,9 +28,6 @@ class NotificationBackupObserver(context: Context, private val userInitiated: Bo
|
||||||
override fun onUpdate(currentBackupPackage: String, backupProgress: BackupProgress) {
|
override fun onUpdate(currentBackupPackage: String, backupProgress: BackupProgress) {
|
||||||
val transferred = backupProgress.bytesTransferred.toInt()
|
val transferred = backupProgress.bytesTransferred.toInt()
|
||||||
val expected = backupProgress.bytesExpected.toInt()
|
val expected = backupProgress.bytesExpected.toInt()
|
||||||
if (isLoggable(TAG, INFO)) {
|
|
||||||
Log.i(TAG, "Update. Target: $currentBackupPackage, $transferred/$expected")
|
|
||||||
}
|
|
||||||
val app = getAppName(currentBackupPackage)
|
val app = getAppName(currentBackupPackage)
|
||||||
nm.onBackupUpdate(app, transferred, expected, userInitiated)
|
nm.onBackupUpdate(app, transferred, expected, userInitiated)
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,7 @@ import com.stevesoltys.seedvault.R
|
||||||
import com.stevesoltys.seedvault.transport.restore.ApkRestoreStatus.QUEUED
|
import com.stevesoltys.seedvault.transport.restore.ApkRestoreStatus.QUEUED
|
||||||
import com.stevesoltys.seedvault.transport.restore.InstallResult
|
import com.stevesoltys.seedvault.transport.restore.InstallResult
|
||||||
import com.stevesoltys.seedvault.transport.restore.getInProgress
|
import com.stevesoltys.seedvault.transport.restore.getInProgress
|
||||||
import kotlinx.android.synthetic.main.fragment_install_progress.*
|
import kotlinx.android.synthetic.main.fragment_restore_progress.*
|
||||||
import kotlinx.android.synthetic.main.fragment_restore_progress.backupNameView
|
|
||||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||||
|
|
||||||
class InstallProgressFragment : Fragment() {
|
class InstallProgressFragment : Fragment() {
|
||||||
|
@ -26,16 +25,19 @@ class InstallProgressFragment : Fragment() {
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?): View? {
|
savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.fragment_install_progress, container, false)
|
return inflater.inflate(R.layout.fragment_restore_progress, container, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
titleView.setText(R.string.restore_installing_packages)
|
||||||
|
|
||||||
appList.apply {
|
appList.apply {
|
||||||
layoutManager = this@InstallProgressFragment.layoutManager
|
layoutManager = this@InstallProgressFragment.layoutManager
|
||||||
adapter = this@InstallProgressFragment.adapter
|
adapter = this@InstallProgressFragment.adapter
|
||||||
addItemDecoration(DividerItemDecoration(context, VERTICAL))
|
addItemDecoration(DividerItemDecoration(context, VERTICAL))
|
||||||
}
|
}
|
||||||
nextButton.setOnClickListener { viewModel.onNextClicked() }
|
button.setText(R.string.restore_next)
|
||||||
|
button.setOnClickListener { viewModel.onNextClicked() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
|
@ -50,7 +52,7 @@ class InstallProgressFragment : Fragment() {
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.nextButtonEnabled.observe(this, Observer { enabled ->
|
viewModel.nextButtonEnabled.observe(this, Observer { enabled ->
|
||||||
nextButton.isEnabled = enabled
|
button.isEnabled = enabled
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,15 @@ class RestoreProgressFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
titleView.setText(R.string.restore_restoring)
|
||||||
|
|
||||||
appList.apply {
|
appList.apply {
|
||||||
layoutManager = this@RestoreProgressFragment.layoutManager
|
layoutManager = this@RestoreProgressFragment.layoutManager
|
||||||
adapter = this@RestoreProgressFragment.adapter
|
adapter = this@RestoreProgressFragment.adapter
|
||||||
addItemDecoration(DividerItemDecoration(context, VERTICAL))
|
addItemDecoration(DividerItemDecoration(context, VERTICAL))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.setText(R.string.restore_finished_button)
|
||||||
button.setOnClickListener {
|
button.setOnClickListener {
|
||||||
requireActivity().setResult(RESULT_OK)
|
requireActivity().setResult(RESULT_OK)
|
||||||
requireActivity().finishAfterTransition()
|
requireActivity().finishAfterTransition()
|
||||||
|
@ -49,10 +52,12 @@ class RestoreProgressFragment : Fragment() {
|
||||||
|
|
||||||
viewModel.chosenRestorableBackup.observe(this, Observer { restorableBackup ->
|
viewModel.chosenRestorableBackup.observe(this, Observer { restorableBackup ->
|
||||||
backupNameView.text = restorableBackup.name
|
backupNameView.text = restorableBackup.name
|
||||||
|
progressBar.max = restorableBackup.packageMetadataMap.size
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.restoreProgress.observe(this, Observer { list ->
|
viewModel.restoreProgress.observe(this, Observer { list ->
|
||||||
stayScrolledAtTop { adapter.update(list) }
|
stayScrolledAtTop { adapter.update(list) }
|
||||||
|
progressBar.progress = list.size
|
||||||
})
|
})
|
||||||
|
|
||||||
viewModel.restoreBackupResult.observe(this, Observer { finished ->
|
viewModel.restoreBackupResult.observe(this, Observer { finished ->
|
||||||
|
|
|
@ -205,7 +205,7 @@ internal class RestoreViewModel(
|
||||||
val expectedPackages = restorableBackup.packageMetadataMap.keys
|
val expectedPackages = restorableBackup.packageMetadataMap.keys
|
||||||
expectedPackages.removeAll(seenPackages)
|
expectedPackages.removeAll(seenPackages)
|
||||||
for (packageName: String in expectedPackages) {
|
for (packageName: String in expectedPackages) {
|
||||||
list.add(AppRestoreResult(packageName, FAILED))
|
list.addFirst(AppRestoreResult(packageName, FAILED))
|
||||||
}
|
}
|
||||||
mRestoreProgress.postValue(list)
|
mRestoreProgress.postValue(list)
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,15 @@ import android.os.RemoteException
|
||||||
import android.os.ServiceManager.getService
|
import android.os.ServiceManager.getService
|
||||||
import android.os.UserHandle
|
import android.os.UserHandle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.util.Log.INFO
|
||||||
import com.google.android.collect.Sets.newArraySet
|
import com.google.android.collect.Sets.newArraySet
|
||||||
import com.stevesoltys.seedvault.MAGIC_PACKAGE_MANAGER
|
import com.stevesoltys.seedvault.MAGIC_PACKAGE_MANAGER
|
||||||
import org.koin.core.KoinComponent
|
import org.koin.core.KoinComponent
|
||||||
import org.koin.core.inject
|
import org.koin.core.inject
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
private val TAG = PackageService::class.java.simpleName
|
private val TAG = PackageService::class.java.simpleName
|
||||||
|
|
||||||
|
private const val LOG_MAX_PACKAGES = 100
|
||||||
private val IGNORED_PACKAGES = newArraySet(
|
private val IGNORED_PACKAGES = newArraySet(
|
||||||
"com.android.externalstorage",
|
"com.android.externalstorage",
|
||||||
"com.android.providers.downloads.ui",
|
"com.android.providers.downloads.ui",
|
||||||
|
@ -43,12 +44,24 @@ internal object PackageService : KoinComponent {
|
||||||
.filter { packageName -> !IGNORED_PACKAGES.contains(packageName) }
|
.filter { packageName -> !IGNORED_PACKAGES.contains(packageName) }
|
||||||
.sorted()
|
.sorted()
|
||||||
|
|
||||||
Log.d(TAG, "Got ${packageList.size} packages: $packageList")
|
// log packages
|
||||||
|
if (Log.isLoggable(TAG, INFO)) {
|
||||||
|
Log.i(TAG, "Got ${packageList.size} packages:")
|
||||||
|
packageList.chunked(LOG_MAX_PACKAGES).forEach {
|
||||||
|
Log.i(TAG, it.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO why is this filtering out so much?
|
// TODO why is this filtering out so much?
|
||||||
val eligibleApps = backupManager.filterAppsEligibleForBackupForUser(UserHandle.myUserId(), packageList.toTypedArray())
|
val eligibleApps = backupManager.filterAppsEligibleForBackupForUser(UserHandle.myUserId(), packageList.toTypedArray())
|
||||||
|
|
||||||
Log.d(TAG, "Filtering left ${eligibleApps.size} eligible packages: ${Arrays.toString(eligibleApps)}")
|
// log eligible packages
|
||||||
|
if (Log.isLoggable(TAG, INFO)) {
|
||||||
|
Log.i(TAG, "Filtering left ${eligibleApps.size} eligible packages:")
|
||||||
|
eligibleApps.toList().chunked(LOG_MAX_PACKAGES).forEach {
|
||||||
|
Log.i(TAG, it.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add magic @pm@ package (PACKAGE_MANAGER_SENTINEL) which holds package manager data
|
// add magic @pm@ package (PACKAGE_MANAGER_SENTINEL) which holds package manager data
|
||||||
val packageArray = eligibleApps.toMutableList()
|
val packageArray = eligibleApps.toMutableList()
|
||||||
|
|
|
@ -127,8 +127,6 @@ internal class FullBackup(
|
||||||
return TRANSPORT_QUOTA_EXCEEDED
|
return TRANSPORT_QUOTA_EXCEEDED
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.i(TAG, "Send full backup data of $numBytes bytes.")
|
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
// get output stream or initialize it, if it does not yet exist
|
// get output stream or initialize it, if it does not yet exist
|
||||||
check((state.outputStream != null) xor (state.outputStreamInit != null)) { "No OutputStream xor no StreamGetter" }
|
check((state.outputStream != null) xor (state.outputStreamInit != null)) { "No OutputStream xor no StreamGetter" }
|
||||||
|
|
|
@ -76,7 +76,6 @@ internal class FullRestore(
|
||||||
* that aborts all further restore operations on the current dataset.
|
* that aborts all further restore operations on the current dataset.
|
||||||
*/
|
*/
|
||||||
fun getNextFullRestoreDataChunk(socket: ParcelFileDescriptor): Int {
|
fun getNextFullRestoreDataChunk(socket: ParcelFileDescriptor): Int {
|
||||||
Log.i(TAG, "Get next full restore data chunk.")
|
|
||||||
val state = this.state ?: throw IllegalStateException("no state")
|
val state = this.state ?: throw IllegalStateException("no state")
|
||||||
val packageName = state.packageInfo.packageName
|
val packageName = state.packageInfo.packageName
|
||||||
|
|
||||||
|
|
|
@ -1,83 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progressBar"
|
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="4dp"
|
|
||||||
android:indeterminate="false"
|
|
||||||
android:padding="0dp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
tools:max="23"
|
|
||||||
tools:progress="5" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/imageView"
|
|
||||||
android:layout_width="32dp"
|
|
||||||
android:layout_height="32dp"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:tint="?android:colorAccent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/progressBar"
|
|
||||||
app:srcCompat="@drawable/ic_cloud_download"
|
|
||||||
tools:ignore="ContentDescription" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/titleView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:text="@string/restore_installing_packages"
|
|
||||||
android:textColor="?android:textColorSecondary"
|
|
||||||
android:textSize="24sp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/imageView" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/backupNameView"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
android:textColor="?android:textColorTertiary"
|
|
||||||
android:textSize="18sp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/titleView"
|
|
||||||
tools:text="Pixel 2 XL" />
|
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
|
||||||
android:id="@+id/appList"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_margin="16dp"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/nextButton"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/backupNameView"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
tools:listitem="@layout/list_item_app_status" />
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/nextButton"
|
|
||||||
style="@style/Widget.AppCompat.Button.Colored"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginBottom="16dp"
|
|
||||||
android:enabled="false"
|
|
||||||
android:text="@string/restore_next"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="1.0"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
|
@ -5,6 +5,19 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progressBar"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="4dp"
|
||||||
|
android:indeterminate="false"
|
||||||
|
android:padding="0dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:max="23"
|
||||||
|
tools:progress="5" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imageView"
|
android:id="@+id/imageView"
|
||||||
android:layout_width="32dp"
|
android:layout_width="32dp"
|
||||||
|
@ -13,7 +26,7 @@
|
||||||
android:tint="?android:colorAccent"
|
android:tint="?android:colorAccent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toBottomOf="@+id/progressBar"
|
||||||
app:srcCompat="@drawable/ic_cloud_download"
|
app:srcCompat="@drawable/ic_cloud_download"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
@ -22,7 +35,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="16dp"
|
android:layout_margin="16dp"
|
||||||
android:text="@string/restore_restoring"
|
android:text="@string/restore_installing_packages"
|
||||||
android:textColor="?android:textColorSecondary"
|
android:textColor="?android:textColorSecondary"
|
||||||
android:textSize="24sp"
|
android:textSize="24sp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -57,13 +70,14 @@
|
||||||
style="@style/Widget.AppCompat.Button.Colored"
|
style="@style/Widget.AppCompat.Button.Colored"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:text="@string/restore_finished_button"
|
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:text="@string/restore_next"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/appList"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintVertical_bias="1.0" />
|
app:layout_constraintHorizontal_bias="1.0"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -91,7 +91,6 @@
|
||||||
<string name="restore_installing_packages">Re-installing Apps</string>
|
<string name="restore_installing_packages">Re-installing Apps</string>
|
||||||
<string name="restore_next">Next</string>
|
<string name="restore_next">Next</string>
|
||||||
<string name="restore_restoring">Restoring Backup</string>
|
<string name="restore_restoring">Restoring Backup</string>
|
||||||
<string name="restore_current_package">Restoring %s…</string>
|
|
||||||
<string name="restore_magic_package">System Package Manager</string>
|
<string name="restore_magic_package">System Package Manager</string>
|
||||||
<string name="restore_finished_success">Restore complete</string>
|
<string name="restore_finished_success">Restore complete</string>
|
||||||
<string name="restore_finished_error">An error occurred while restoring the backup.</string>
|
<string name="restore_finished_error">An error occurred while restoring the backup.</string>
|
||||||
|
|
Loading…
Add table
Reference in a new issue