Merge change 26974 into eclair

* changes:
  Disallow concurrent backups; consult transport requestBackupTime()
This commit is contained in:
Android (Google) Code Review
2009-09-24 23:22:29 -04:00

View File

@@ -162,6 +162,7 @@ class BackupManagerService extends IBackupManager.Stub {
final Object mAgentConnectLock = new Object(); final Object mAgentConnectLock = new Object();
IBackupAgent mConnectedAgent; IBackupAgent mConnectedAgent;
volatile boolean mConnecting; volatile boolean mConnecting;
volatile boolean mBackupOrRestoreInProgress = false;
// A similar synchronicity mechanism around clearing apps' data for restore // A similar synchronicity mechanism around clearing apps' data for restore
final Object mClearDataLock = new Object(); final Object mClearDataLock = new Object();
@@ -211,7 +212,7 @@ class BackupManagerService extends IBackupManager.Stub {
// Persistently track the need to do a full init // Persistently track the need to do a full init
static final String INIT_SENTINEL_FILE_NAME = "_need_init_"; static final String INIT_SENTINEL_FILE_NAME = "_need_init_";
HashSet<String> mPendingInits = new HashSet<String>(); // transport names HashSet<String> mPendingInits = new HashSet<String>(); // transport names
boolean mInitInProgress = false; volatile boolean mInitInProgress = false;
public BackupManagerService(Context context) { public BackupManagerService(Context context) {
mContext = context; mContext = context;
@@ -316,9 +317,12 @@ class BackupManagerService extends IBackupManager.Stub {
} }
} else { } else {
// Don't run backups now if we're disabled, not yet // Don't run backups now if we're disabled, not yet
// fully set up, or racing with an initialize pass. // fully set up, in the middle of a backup already,
if (mEnabled && mProvisioned && !mInitInProgress) { // or racing with an initialize pass.
if (mEnabled && mProvisioned
&& !mBackupOrRestoreInProgress && !mInitInProgress) {
if (DEBUG) Log.v(TAG, "Running a backup pass"); if (DEBUG) Log.v(TAG, "Running a backup pass");
mBackupOrRestoreInProgress = true;
// Acquire the wakelock and pass it to the backup thread. it will // Acquire the wakelock and pass it to the backup thread. it will
// be released once backup concludes. // be released once backup concludes.
@@ -328,7 +332,7 @@ class BackupManagerService extends IBackupManager.Stub {
mBackupHandler.sendMessage(msg); mBackupHandler.sendMessage(msg);
} else { } else {
Log.w(TAG, "Backup pass but e=" + mEnabled + " p=" + mProvisioned Log.w(TAG, "Backup pass but e=" + mEnabled + " p=" + mProvisioned
+ " i=" + mInitInProgress); + " b=" + mBackupOrRestoreInProgress + " i=" + mInitInProgress);
} }
} }
} }
@@ -1106,6 +1110,12 @@ class BackupManagerService extends IBackupManager.Stub {
// can't happen; it's a local call // can't happen; it's a local call
} }
} }
// We also want to reset the backup schedule based on whatever
// the transport suggests by way of retry/backoff time.
try {
startBackupAlarmsLocked(mTransport.requestBackupTime());
} catch (RemoteException e) { /* cannot happen */ }
} }
// Either backup was successful, in which case we of course do not need // Either backup was successful, in which case we of course do not need
@@ -1116,7 +1126,11 @@ class BackupManagerService extends IBackupManager.Stub {
Log.e(TAG, "Unable to remove backup journal file " + mJournal); Log.e(TAG, "Unable to remove backup journal file " + mJournal);
} }
// Only once we're entirely finished do we release the wakelock // Only once we're entirely finished do we indicate our completion
// and release the wakelock
synchronized (mQueueLock) {
mBackupOrRestoreInProgress = false;
}
mWakelock.release(); mWakelock.release();
} }
} }
@@ -1553,6 +1567,9 @@ class BackupManagerService extends IBackupManager.Stub {
} }
// done; we can finally release the wakelock // done; we can finally release the wakelock
synchronized (mQueueLock) {
mBackupOrRestoreInProgress = false;
}
mWakelock.release(); mWakelock.release();
} }
} }
@@ -1876,6 +1893,10 @@ class BackupManagerService extends IBackupManager.Stub {
if (DEBUG) Log.v(TAG, "Scheduling immediate backup pass"); if (DEBUG) Log.v(TAG, "Scheduling immediate backup pass");
synchronized (mQueueLock) { synchronized (mQueueLock) {
// Because the alarms we are using can jitter, and we want an *immediate*
// backup pass to happen, we restart the timer beginning with "next time,"
// then manually fire the backup trigger intent ourselves.
startBackupAlarmsLocked(BACKUP_INTERVAL);
try { try {
mRunBackupIntent.send(); mRunBackupIntent.send();
} catch (PendingIntent.CanceledException e) { } catch (PendingIntent.CanceledException e) {
@@ -2108,15 +2129,24 @@ class BackupManagerService extends IBackupManager.Stub {
return -1; return -1;
} }
for (int i = 0; i < mRestoreSets.length; i++) { synchronized (mQueueLock) {
if (token == mRestoreSets[i].token) { if (mBackupOrRestoreInProgress) {
long oldId = Binder.clearCallingIdentity(); Log.e(TAG, "Backup pass in progress, restore aborted");
mWakelock.acquire(); return -1;
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE); }
msg.obj = new RestoreParams(mRestoreTransport, observer, token);
mBackupHandler.sendMessage(msg); for (int i = 0; i < mRestoreSets.length; i++) {
Binder.restoreCallingIdentity(oldId); if (token == mRestoreSets[i].token) {
return 0; long oldId = Binder.clearCallingIdentity();
// Suppress backups until the restore operation is finished
mBackupOrRestoreInProgress = true;
mWakelock.acquire();
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
msg.obj = new RestoreParams(mRestoreTransport, observer, token);
mBackupHandler.sendMessage(msg);
Binder.restoreCallingIdentity(oldId);
return 0;
}
} }
} }