From 8031a3df2fd0c38d85eeae39c1ea2c83e813f4ff Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Mon, 6 Jul 2009 16:36:05 -0700 Subject: [PATCH] Make enable/provisioning of the backup service a two-step process This CL adds the concept of 'provisioned' to the backup manager. No backups will be scheduled until the user has indicated that backups are to be enabled *and* has clicked all the way through the setup wizard. When the user first turns on the backup system, the delay before the initial backup pass is different from the periodic backup interval. Currently that initial delay is 12 hours. The intent here is to guess at a less-active time for performing that first backup pass. NOTE: currently the backup service defaults to 'provisioned'. Once the real code goes live in Setup Wizard, this will be changed to default to not-provisioned until the user has confirmed all the relevant UI. --- core/java/android/backup/IBackupManager.aidl | 7 +++ core/java/android/provider/Settings.java | 9 +++- .../android/server/BackupManagerService.java | 49 ++++++++++++++++--- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/core/java/android/backup/IBackupManager.aidl b/core/java/android/backup/IBackupManager.aidl index d4933acda1aac..9d181bec49df7 100644 --- a/core/java/android/backup/IBackupManager.aidl +++ b/core/java/android/backup/IBackupManager.aidl @@ -72,6 +72,13 @@ interface IBackupManager { */ void setBackupEnabled(boolean isEnabled); + /** + * Indicate that any necessary one-time provisioning has occurred. + * + *

Callers must hold the android.permission.BACKUP permission to use this method. + */ + void setBackupProvisioned(boolean isProvisioned); + /** * Report whether the backup mechanism is currently enabled. * diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 70173336af263..7f63bff67da55 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -2269,12 +2269,19 @@ public final class Settings { public static final String USE_LOCATION_FOR_SERVICES = "use_location"; /** - * Controls whether data backup is enabled. + * Controls whether settings backup is enabled. * Type: int ( 0 = disabled, 1 = enabled ) * @hide */ public static final String BACKUP_ENABLED = "backup_enabled"; + /** + * Indicates whether settings backup has been fully provisioned. + * Type: int ( 0 = unprovisioned, 1 = fully provisioned ) + * @hide + */ + public static final String BACKUP_PROVISIONED = "backup_provisioned"; + /** * Component of the transport to use for backup/restore. * @hide diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index 4b5c3df4b51fd..2ae9fc506c723 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -81,6 +81,10 @@ class BackupManagerService extends IBackupManager.Stub { // trigger an immediate pass. private static final long BACKUP_INTERVAL = AlarmManager.INTERVAL_HOUR; + // The amount of time between the initial provisioning of the device and + // the first backup pass. + private static final long FIRST_BACKUP_INTERVAL = 12 * AlarmManager.INTERVAL_HOUR; + private static final String RUN_BACKUP_ACTION = "_backup_run_"; private static final int MSG_RUN_BACKUP = 1; private static final int MSG_RUN_FULL_BACKUP = 2; @@ -97,6 +101,7 @@ class BackupManagerService extends IBackupManager.Stub { private AlarmManager mAlarmManager; private boolean mEnabled; // access to this is synchronized on 'this' + private boolean mProvisioned; private PowerManager.WakeLock mWakelock; private final BackupHandler mBackupHandler = new BackupHandler(); private PendingIntent mRunBackupIntent; @@ -188,6 +193,9 @@ class BackupManagerService extends IBackupManager.Stub { // Set up our bookkeeping boolean areEnabled = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.BACKUP_ENABLED, 0) != 0; + // !!! TODO: mProvisioned needs to default to 0, not 1. + mProvisioned = Settings.Secure.getInt(context.getContentResolver(), + Settings.Secure.BACKUP_PROVISIONED, 1) != 0; mBaseStateDir = new File(Environment.getDataDirectory(), "backup"); mDataDir = Environment.getDownloadCacheDirectory(); @@ -1301,7 +1309,7 @@ class BackupManagerService extends IBackupManager.Stub { } } - // Enable/disable the backup transport + // Enable/disable the backup service public void setBackupEnabled(boolean enable) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "setBackupEnabled"); @@ -1314,11 +1322,9 @@ class BackupManagerService extends IBackupManager.Stub { } synchronized (mQueueLock) { - if (enable && !wasEnabled) { + if (enable && !wasEnabled && mProvisioned) { // if we've just been enabled, start scheduling backup passes - long when = System.currentTimeMillis() + BACKUP_INTERVAL; - mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, when, - BACKUP_INTERVAL, mRunBackupIntent); + startBackupAlarmsLocked(BACKUP_INTERVAL); } else if (!enable) { // No longer enabled, so stop running backups mAlarmManager.cancel(mRunBackupIntent); @@ -1326,6 +1332,36 @@ class BackupManagerService extends IBackupManager.Stub { } } + // Mark the backup service as having been provisioned + 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 + Log.w(TAG, "Backup service no longer provisioned"); + mAlarmManager.cancel(mRunBackupIntent); + } + } + } + + private void startBackupAlarmsLocked(long delayBeforeFirstBackup) { + long when = System.currentTimeMillis() + delayBeforeFirstBackup; + mAlarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, when, + BACKUP_INTERVAL, mRunBackupIntent); + } + // Report whether the backup mechanism is currently enabled public boolean isBackupEnabled() { mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "isBackupEnabled"); @@ -1506,7 +1542,8 @@ class BackupManagerService extends IBackupManager.Stub { synchronized (mQueueLock) { long oldId = Binder.clearCallingIdentity(); - pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled")); + pw.println("Backup Manager is " + (mEnabled ? "enabled" : "disabled") + + " / " + (!mProvisioned ? "not " : "") + "provisioned"); pw.println("Available transports:"); for (String t : listAllTransports()) { String pad = (t.equals(mCurrentTransport)) ? " * " : " ";