Initialize backup, when enabling it
For ApkBackup, we need to be initialized. If the system starts with app backup off, we would not initialize which would lead to issues when backing up the APKs.
This commit is contained in:
parent
2da989971b
commit
ee581ee652
6 changed files with 60 additions and 14 deletions
|
@ -2,6 +2,7 @@ package com.stevesoltys.seedvault.e2e
|
|||
|
||||
import android.content.pm.PackageInfo
|
||||
import android.os.ParcelFileDescriptor
|
||||
import androidx.test.uiautomator.Until
|
||||
import com.stevesoltys.seedvault.e2e.io.BackupDataInputIntercept
|
||||
import com.stevesoltys.seedvault.e2e.io.InputStreamIntercept
|
||||
import com.stevesoltys.seedvault.e2e.screen.impl.BackupScreen
|
||||
|
@ -44,6 +45,11 @@ internal interface LargeBackupTestBase : LargeTestBase {
|
|||
if (!backupManager.isBackupEnabled) {
|
||||
backupSwitch.click()
|
||||
waitUntilIdle()
|
||||
|
||||
BackupScreen {
|
||||
device.wait(Until.hasObject(initializingText), 10000)
|
||||
device.wait(Until.gone(initializingText), 120000)
|
||||
}
|
||||
}
|
||||
|
||||
backupMenu.clickAndWaitForNewWindow()
|
||||
|
|
|
@ -57,7 +57,7 @@ open class App : Application() {
|
|||
factory<IBackupManager> { IBackupManager.Stub.asInterface(getService(BACKUP_SERVICE)) }
|
||||
factory { AppListRetriever(this@App, get(), get(), get()) }
|
||||
|
||||
viewModel { SettingsViewModel(this@App, get(), get(), get(), get(), get(), get()) }
|
||||
viewModel { SettingsViewModel(this@App, get(), get(), get(), get(), get(), get(), get()) }
|
||||
viewModel { RecoveryCodeViewModel(this@App, get(), get(), get(), get(), get(), get()) }
|
||||
viewModel { BackupStorageViewModel(this@App, get(), get(), get(), get()) }
|
||||
viewModel { RestoreStorageViewModel(this@App, get(), get()) }
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.stevesoltys.seedvault.ui.RequireProvisioningActivity
|
|||
import com.stevesoltys.seedvault.ui.RequireProvisioningViewModel
|
||||
import com.stevesoltys.seedvault.ui.notification.BackupNotificationManager
|
||||
import com.stevesoltys.seedvault.ui.recoverycode.ARG_FOR_NEW_CODE
|
||||
import com.stevesoltys.seedvault.ui.storage.StorageCheckFragment
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
|
@ -36,6 +37,19 @@ class SettingsActivity : RequireProvisioningActivity(), OnPreferenceStartFragmen
|
|||
if (intent?.action == ACTION_APP_STATUS_LIST) {
|
||||
showFragment(AppStatusFragment(), true)
|
||||
}
|
||||
|
||||
// observe initialization and show/remove init fragment
|
||||
// this can happen when enabling backup and storage wasn't initialized
|
||||
viewModel.initEvent.observeEvent(this) { show ->
|
||||
val tag = "INIT"
|
||||
if (show) {
|
||||
val title = getString(R.string.storage_check_fragment_backup_title)
|
||||
showFragment(StorageCheckFragment.newInstance(title), true, tag)
|
||||
} else {
|
||||
val f = supportFragmentManager.findFragmentByTag(tag)
|
||||
if (f != null && f.isVisible) supportFragmentManager.popBackStack()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
|
|
|
@ -19,7 +19,6 @@ import androidx.preference.Preference
|
|||
import androidx.preference.Preference.OnPreferenceChangeListener
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import androidx.preference.TwoStatePreference
|
||||
import androidx.work.ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE
|
||||
import androidx.work.WorkInfo
|
||||
import com.stevesoltys.seedvault.R
|
||||
import com.stevesoltys.seedvault.permitDiskReads
|
||||
|
@ -213,16 +212,10 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
// TODO this should really get moved out off the UI layer
|
||||
private fun trySetBackupEnabled(enabled: Boolean): Boolean {
|
||||
return try {
|
||||
backupManager.isBackupEnabled = enabled
|
||||
if (enabled) {
|
||||
viewModel.scheduleAppBackup(CANCEL_AND_REENQUEUE)
|
||||
viewModel.enableCallLogBackup()
|
||||
} else {
|
||||
viewModel.cancelAppBackup()
|
||||
}
|
||||
viewModel.onBackupEnabled(enabled)
|
||||
backup.isChecked = enabled
|
||||
true
|
||||
} catch (e: RemoteException) {
|
||||
|
|
|
@ -37,6 +37,9 @@ import com.stevesoltys.seedvault.permitDiskReads
|
|||
import com.stevesoltys.seedvault.storage.StorageBackupJobService
|
||||
import com.stevesoltys.seedvault.storage.StorageBackupService
|
||||
import com.stevesoltys.seedvault.storage.StorageBackupService.Companion.EXTRA_START_APP_BACKUP
|
||||
import com.stevesoltys.seedvault.transport.backup.BackupInitializer
|
||||
import com.stevesoltys.seedvault.ui.LiveEvent
|
||||
import com.stevesoltys.seedvault.ui.MutableLiveEvent
|
||||
import com.stevesoltys.seedvault.ui.RequireProvisioningViewModel
|
||||
import com.stevesoltys.seedvault.worker.AppBackupWorker
|
||||
import com.stevesoltys.seedvault.worker.AppBackupWorker.Companion.UNIQUE_WORK_NAME
|
||||
|
@ -60,6 +63,7 @@ internal class SettingsViewModel(
|
|||
private val appListRetriever: AppListRetriever,
|
||||
private val storageBackup: StorageBackup,
|
||||
private val backupManager: IBackupManager,
|
||||
private val backupInitializer: BackupInitializer,
|
||||
) : RequireProvisioningViewModel(app, settingsManager, keyManager) {
|
||||
|
||||
private val contentResolver = app.contentResolver
|
||||
|
@ -90,6 +94,9 @@ internal class SettingsViewModel(
|
|||
private val _filesSummary = MutableLiveData<String>()
|
||||
internal val filesSummary: LiveData<String> = _filesSummary
|
||||
|
||||
private val _initEvent = MutableLiveEvent<Boolean>()
|
||||
val initEvent: LiveEvent<Boolean> = _initEvent
|
||||
|
||||
private val storageObserver = object : ContentObserver(null) {
|
||||
override fun onChange(selfChange: Boolean, uris: MutableCollection<Uri>, flags: Int) {
|
||||
onStoragePropertiesChanged()
|
||||
|
@ -230,6 +237,30 @@ internal class SettingsViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun onBackupEnabled(enabled: Boolean) {
|
||||
if (enabled) {
|
||||
if (metadataManager.requiresInit) {
|
||||
val onError: () -> Unit = {
|
||||
viewModelScope.launch(Dispatchers.Main) {
|
||||
val res = R.string.storage_check_fragment_backup_error
|
||||
Toast.makeText(app, res, LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
backupInitializer.initialize(onError) {
|
||||
_initEvent.postEvent(false)
|
||||
scheduleAppBackup(CANCEL_AND_REENQUEUE)
|
||||
}
|
||||
_initEvent.postEvent(true)
|
||||
}
|
||||
}
|
||||
// enable call log backups for existing installs (added end of 2020)
|
||||
enableCallLogBackup()
|
||||
} else {
|
||||
cancelAppBackup()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the call log will be included in backups.
|
||||
*
|
||||
|
|
|
@ -17,11 +17,13 @@ abstract class BackupActivity : AppCompatActivity() {
|
|||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
protected fun showFragment(f: Fragment, addToBackStack: Boolean = false) {
|
||||
val fragmentTransaction = supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment, f)
|
||||
if (addToBackStack) fragmentTransaction.addToBackStack(null)
|
||||
fragmentTransaction.commit()
|
||||
protected fun showFragment(f: Fragment, addToBackStack: Boolean = false, tag: String? = null) {
|
||||
supportFragmentManager.beginTransaction().apply {
|
||||
if (tag == null) replace(R.id.fragment, f)
|
||||
else replace(R.id.fragment, f, tag)
|
||||
if (addToBackStack) addToBackStack(null)
|
||||
commit()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue