DO NOT MERGE : Ensure that the first post-restore backup pass is correct
Some restore passes bring an ancestral dataset to the application, but others instead act to bring an app back into sync with its own most- recently-saved data. In the latter case the state file written by the app after the restore is a correct basis for generating future backup deltas, but in the former case it is not. The app should not be required to distinguish between these cases; the framework has all the information necessary to handle the saved state correctly following any flavor of restore operation. This patch makes the Backup Manager properly cause a full backup pass following an ancestral-dataset restore. After a current-set restore the saved state file is an accurate description for purposes of continued backup operations, so is preserved. (Cherrypick from master to gingerbread) Change-Id: I4bc4e8782a168ecc0795107a340bdbb35060730e
This commit is contained in:
@ -198,22 +198,26 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
public long token;
|
||||
public PackageInfo pkgInfo;
|
||||
public int pmToken; // in post-install restore, the PM's token for this transaction
|
||||
public boolean needFullBackup;
|
||||
|
||||
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs,
|
||||
long _token, PackageInfo _pkg, int _pmToken) {
|
||||
long _token, PackageInfo _pkg, int _pmToken, boolean _needFullBackup) {
|
||||
transport = _transport;
|
||||
observer = _obs;
|
||||
token = _token;
|
||||
pkgInfo = _pkg;
|
||||
pmToken = _pmToken;
|
||||
needFullBackup = _needFullBackup;
|
||||
}
|
||||
|
||||
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token) {
|
||||
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token,
|
||||
boolean _needFullBackup) {
|
||||
transport = _transport;
|
||||
observer = _obs;
|
||||
token = _token;
|
||||
pkgInfo = null;
|
||||
pmToken = 0;
|
||||
needFullBackup = _needFullBackup;
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,7 +327,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
RestoreParams params = (RestoreParams)msg.obj;
|
||||
Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
|
||||
(new PerformRestoreTask(params.transport, params.observer,
|
||||
params.token, params.pkgInfo, params.pmToken)).run();
|
||||
params.token, params.pkgInfo, params.pmToken,
|
||||
params.needFullBackup)).run();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1559,6 +1564,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
private PackageInfo mTargetPackage;
|
||||
private File mStateDir;
|
||||
private int mPmToken;
|
||||
private boolean mNeedFullBackup;
|
||||
|
||||
class RestoreRequest {
|
||||
public PackageInfo app;
|
||||
@ -1571,12 +1577,14 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
}
|
||||
|
||||
PerformRestoreTask(IBackupTransport transport, IRestoreObserver observer,
|
||||
long restoreSetToken, PackageInfo targetPackage, int pmToken) {
|
||||
long restoreSetToken, PackageInfo targetPackage, int pmToken,
|
||||
boolean needFullBackup) {
|
||||
mTransport = transport;
|
||||
mObserver = observer;
|
||||
mToken = restoreSetToken;
|
||||
mTargetPackage = targetPackage;
|
||||
mPmToken = pmToken;
|
||||
mNeedFullBackup = needFullBackup;
|
||||
|
||||
try {
|
||||
mStateDir = new File(mBaseStateDir, transport.transportDirName());
|
||||
@ -1654,7 +1662,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
// Pull the Package Manager metadata from the restore set first
|
||||
pmAgent = new PackageManagerBackupAgent(
|
||||
mPackageManager, agentPackages);
|
||||
processOneRestore(omPackage, 0, IBackupAgent.Stub.asInterface(pmAgent.onBind()));
|
||||
processOneRestore(omPackage, 0, IBackupAgent.Stub.asInterface(pmAgent.onBind()),
|
||||
mNeedFullBackup);
|
||||
|
||||
// Verify that the backup set includes metadata. If not, we can't do
|
||||
// signature/version verification etc, so we simply do not proceed with
|
||||
@ -1751,7 +1760,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
|
||||
// And then finally run the restore on this agent
|
||||
try {
|
||||
processOneRestore(packageInfo, metaInfo.versionCode, agent);
|
||||
processOneRestore(packageInfo, metaInfo.versionCode, agent,
|
||||
mNeedFullBackup);
|
||||
++count;
|
||||
} finally {
|
||||
// unbind and tidy up even on timeout or failure, just in case
|
||||
@ -1821,7 +1831,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
}
|
||||
|
||||
// Do the guts of a restore of one application, using mTransport.getRestoreData().
|
||||
void processOneRestore(PackageInfo app, int appVersionCode, IBackupAgent agent) {
|
||||
void processOneRestore(PackageInfo app, int appVersionCode, IBackupAgent agent,
|
||||
boolean needFullBackup) {
|
||||
// !!! TODO: actually run the restore through mTransport
|
||||
final String packageName = app.packageName;
|
||||
|
||||
@ -1900,6 +1911,14 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
try { if (newState != null) newState.close(); } catch (IOException e) {}
|
||||
backupData = newState = null;
|
||||
mCurrentOperations.delete(token);
|
||||
|
||||
// If we know a priori that we'll need to perform a full post-restore backup
|
||||
// pass, clear the new state file data. This means we're discarding work that
|
||||
// was just done by the app's agent, but this way the agent doesn't need to
|
||||
// take any special action based on global device state.
|
||||
if (needFullBackup) {
|
||||
newStateName.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2385,7 +2404,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
mWakelock.acquire();
|
||||
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
|
||||
msg.obj = new RestoreParams(getTransport(mCurrentTransport), null,
|
||||
restoreSet, pkg, token);
|
||||
restoreSet, pkg, token, true);
|
||||
mBackupHandler.sendMessage(msg);
|
||||
} else {
|
||||
// Auto-restore disabled or no way to attempt a restore; just tell the Package
|
||||
@ -2516,7 +2535,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
long oldId = Binder.clearCallingIdentity();
|
||||
mWakelock.acquire();
|
||||
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
|
||||
msg.obj = new RestoreParams(mRestoreTransport, observer, token);
|
||||
msg.obj = new RestoreParams(mRestoreTransport, observer, token, true);
|
||||
mBackupHandler.sendMessage(msg);
|
||||
Binder.restoreCallingIdentity(oldId);
|
||||
return 0;
|
||||
@ -2581,7 +2600,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
long oldId = Binder.clearCallingIdentity();
|
||||
mWakelock.acquire();
|
||||
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
|
||||
msg.obj = new RestoreParams(mRestoreTransport, observer, token, app, 0);
|
||||
msg.obj = new RestoreParams(mRestoreTransport, observer, token, app, 0, false);
|
||||
mBackupHandler.sendMessage(msg);
|
||||
Binder.restoreCallingIdentity(oldId);
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user