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 long token;
|
||||||
public PackageInfo pkgInfo;
|
public PackageInfo pkgInfo;
|
||||||
public int pmToken; // in post-install restore, the PM's token for this transaction
|
public int pmToken; // in post-install restore, the PM's token for this transaction
|
||||||
|
public boolean needFullBackup;
|
||||||
|
|
||||||
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs,
|
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs,
|
||||||
long _token, PackageInfo _pkg, int _pmToken) {
|
long _token, PackageInfo _pkg, int _pmToken, boolean _needFullBackup) {
|
||||||
transport = _transport;
|
transport = _transport;
|
||||||
observer = _obs;
|
observer = _obs;
|
||||||
token = _token;
|
token = _token;
|
||||||
pkgInfo = _pkg;
|
pkgInfo = _pkg;
|
||||||
pmToken = _pmToken;
|
pmToken = _pmToken;
|
||||||
|
needFullBackup = _needFullBackup;
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token) {
|
RestoreParams(IBackupTransport _transport, IRestoreObserver _obs, long _token,
|
||||||
|
boolean _needFullBackup) {
|
||||||
transport = _transport;
|
transport = _transport;
|
||||||
observer = _obs;
|
observer = _obs;
|
||||||
token = _token;
|
token = _token;
|
||||||
pkgInfo = null;
|
pkgInfo = null;
|
||||||
pmToken = 0;
|
pmToken = 0;
|
||||||
|
needFullBackup = _needFullBackup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +327,8 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
RestoreParams params = (RestoreParams)msg.obj;
|
RestoreParams params = (RestoreParams)msg.obj;
|
||||||
Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
|
Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
|
||||||
(new PerformRestoreTask(params.transport, 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1559,6 +1564,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
private PackageInfo mTargetPackage;
|
private PackageInfo mTargetPackage;
|
||||||
private File mStateDir;
|
private File mStateDir;
|
||||||
private int mPmToken;
|
private int mPmToken;
|
||||||
|
private boolean mNeedFullBackup;
|
||||||
|
|
||||||
class RestoreRequest {
|
class RestoreRequest {
|
||||||
public PackageInfo app;
|
public PackageInfo app;
|
||||||
@ -1571,12 +1577,14 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PerformRestoreTask(IBackupTransport transport, IRestoreObserver observer,
|
PerformRestoreTask(IBackupTransport transport, IRestoreObserver observer,
|
||||||
long restoreSetToken, PackageInfo targetPackage, int pmToken) {
|
long restoreSetToken, PackageInfo targetPackage, int pmToken,
|
||||||
|
boolean needFullBackup) {
|
||||||
mTransport = transport;
|
mTransport = transport;
|
||||||
mObserver = observer;
|
mObserver = observer;
|
||||||
mToken = restoreSetToken;
|
mToken = restoreSetToken;
|
||||||
mTargetPackage = targetPackage;
|
mTargetPackage = targetPackage;
|
||||||
mPmToken = pmToken;
|
mPmToken = pmToken;
|
||||||
|
mNeedFullBackup = needFullBackup;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mStateDir = new File(mBaseStateDir, transport.transportDirName());
|
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
|
// Pull the Package Manager metadata from the restore set first
|
||||||
pmAgent = new PackageManagerBackupAgent(
|
pmAgent = new PackageManagerBackupAgent(
|
||||||
mPackageManager, agentPackages);
|
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
|
// Verify that the backup set includes metadata. If not, we can't do
|
||||||
// signature/version verification etc, so we simply do not proceed with
|
// 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
|
// And then finally run the restore on this agent
|
||||||
try {
|
try {
|
||||||
processOneRestore(packageInfo, metaInfo.versionCode, agent);
|
processOneRestore(packageInfo, metaInfo.versionCode, agent,
|
||||||
|
mNeedFullBackup);
|
||||||
++count;
|
++count;
|
||||||
} finally {
|
} finally {
|
||||||
// unbind and tidy up even on timeout or failure, just in case
|
// 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().
|
// 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
|
// !!! TODO: actually run the restore through mTransport
|
||||||
final String packageName = app.packageName;
|
final String packageName = app.packageName;
|
||||||
|
|
||||||
@ -1900,6 +1911,14 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
try { if (newState != null) newState.close(); } catch (IOException e) {}
|
try { if (newState != null) newState.close(); } catch (IOException e) {}
|
||||||
backupData = newState = null;
|
backupData = newState = null;
|
||||||
mCurrentOperations.delete(token);
|
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();
|
mWakelock.acquire();
|
||||||
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
|
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
|
||||||
msg.obj = new RestoreParams(getTransport(mCurrentTransport), null,
|
msg.obj = new RestoreParams(getTransport(mCurrentTransport), null,
|
||||||
restoreSet, pkg, token);
|
restoreSet, pkg, token, true);
|
||||||
mBackupHandler.sendMessage(msg);
|
mBackupHandler.sendMessage(msg);
|
||||||
} else {
|
} else {
|
||||||
// Auto-restore disabled or no way to attempt a restore; just tell the Package
|
// 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();
|
long oldId = Binder.clearCallingIdentity();
|
||||||
mWakelock.acquire();
|
mWakelock.acquire();
|
||||||
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
|
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);
|
mBackupHandler.sendMessage(msg);
|
||||||
Binder.restoreCallingIdentity(oldId);
|
Binder.restoreCallingIdentity(oldId);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2581,7 +2600,7 @@ class BackupManagerService extends IBackupManager.Stub {
|
|||||||
long oldId = Binder.clearCallingIdentity();
|
long oldId = Binder.clearCallingIdentity();
|
||||||
mWakelock.acquire();
|
mWakelock.acquire();
|
||||||
Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
|
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);
|
mBackupHandler.sendMessage(msg);
|
||||||
Binder.restoreCallingIdentity(oldId);
|
Binder.restoreCallingIdentity(oldId);
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user