Eliminate "backup enabled but not provisioned" failure modes

Previously, the setup app was responsible for telling the backup
manager through a side band that the user had passed through the
backup/restore-related portion of the setup flow.  Now that the
flow has been streamlined and certain mandatory portions of it
are no longer relevant, we can ditch the whole idea of the backup
manager's internal "provisioned" state.  This makes setup and the
setup "wizard" applications less fragile as well as eliminating
the possibility of unrecoverable "backup was never provisioned"
failure modes.

Now, the only check the backup manager has to do is against the
full "device is provisioned" flag, just like all of the other
components on the phone that only become usable after the setup
process has exited [such as phone calls].

Bug 6493520

Change-Id: I13ec8dd8baa1e74ed8569b0326219a98a7f632a9
This commit is contained in:
Christopher Tate
2012-05-17 14:59:41 -07:00
parent 9cb376e792
commit 97ea122c65

View File

@@ -48,6 +48,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.pm.PackageManager.NameNotFoundException;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -252,6 +253,34 @@ class BackupManagerService extends IBackupManager.Stub {
IBackupTransport mLocalTransport, mGoogleTransport;
ActiveRestoreSession mActiveRestoreSession;
// Watch the device provisioning operation during setup
ContentObserver mProvisionedObserver;
class ProvisionedObserver extends ContentObserver {
public ProvisionedObserver(Handler handler) {
super(handler);
}
public void onChange(boolean selfChange) {
final boolean wasProvisioned = mProvisioned;
final boolean isProvisioned = deviceIsProvisioned();
// latch: never unprovision
mProvisioned = wasProvisioned || isProvisioned;
if (MORE_DEBUG) {
Slog.d(TAG, "Provisioning change: was=" + wasProvisioned
+ " is=" + isProvisioned + " now=" + mProvisioned);
}
synchronized (mQueueLock) {
if (mProvisioned && !wasProvisioned && mEnabled) {
// we're now good to go, so start the backup alarms
if (MORE_DEBUG) Slog.d(TAG, "Now provisioned, so starting backups");
startBackupAlarmsLocked(FIRST_BACKUP_INTERVAL);
}
}
}
}
class RestoreGetSetsParams {
public IBackupTransport transport;
public ActiveRestoreSession session;
@@ -695,12 +724,19 @@ class BackupManagerService extends IBackupManager.Stub {
mBackupHandler = new BackupHandler(mHandlerThread.getLooper());
// Set up our bookkeeping
boolean areEnabled = Settings.Secure.getInt(context.getContentResolver(),
final ContentResolver resolver = context.getContentResolver();
boolean areEnabled = Settings.Secure.getInt(resolver,
Settings.Secure.BACKUP_ENABLED, 0) != 0;
mProvisioned = Settings.Secure.getInt(context.getContentResolver(),
Settings.Secure.BACKUP_PROVISIONED, 0) != 0;
mAutoRestore = Settings.Secure.getInt(context.getContentResolver(),
mProvisioned = Settings.Secure.getInt(resolver,
Settings.Secure.DEVICE_PROVISIONED, 0) != 0;
mAutoRestore = Settings.Secure.getInt(resolver,
Settings.Secure.BACKUP_AUTO_RESTORE, 1) != 0;
mProvisionedObserver = new ProvisionedObserver(mBackupHandler);
resolver.registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.DEVICE_PROVISIONED),
false, mProvisionedObserver);
// If Encrypted file systems is enabled or disabled, this call will return the
// correct directory.
mBaseStateDir = new File(Environment.getSecureDataDirectory(), "backup");
@@ -5172,24 +5208,9 @@ class BackupManagerService extends IBackupManager.Stub {
public void setBackupProvisioned(boolean available) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
"setBackupProvisioned");
boolean wasProvisioned = mProvisioned;
synchronized (this) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.BACKUP_PROVISIONED, available ? 1 : 0);
mProvisioned = available;
}
synchronized (mQueueLock) {
if (available && !wasProvisioned && mEnabled) {
// we're now good to go, so start the backup alarms
startBackupAlarmsLocked(FIRST_BACKUP_INTERVAL);
} else if (!available) {
// No longer enabled, so stop running backups
Slog.w(TAG, "Backup service no longer provisioned");
mAlarmManager.cancel(mRunBackupIntent);
}
}
/*
* This is now a no-op; provisioning is simply the device's own setup state.
*/
}
private void startBackupAlarmsLocked(long delayBeforeFirstBackup) {