Add 'restoreAnyVersion' attr for apps that want to restore "future" data
If a backup-participating app sets android:restoreAnyVersion="true" in its manifest <application> tag, then its agent will be invoked for restore even if the available dataset was created by a later version of the app than is currently installed on the device. This will not typically be a problem for third party applications, since for them the installation and initial data restore are tightly coupled, but it can cause serious problems for applications which are both preinstalled on the system partition and overridden by later updates. The primary difficulty that this new attribute addresses is this: 1. User buys a Nexus One, Market self-updates, and the user installs some apps. At this point the backup data on the server may indicate that the version of Market which originated its bookkeeping is newer than the stock N1 Market app. 2. User loses their phone, and buys a replacement N1. At setup time, Market has not yet had a chance to self-update, so when the restore comes in, it's tagged as being from "the future" and so the restore is refused. No apps get reinstalled. Bug: 2442127 Change-Id: I076a9553dc613e5c3189350e778315718ed1ed2b
This commit is contained in:
@ -1647,11 +1647,22 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
}
|
||||
|
||||
if (metaInfo.versionCode > packageInfo.versionCode) {
|
||||
String message = "Version " + metaInfo.versionCode
|
||||
+ " > installed version " + packageInfo.versionCode;
|
||||
Log.w(TAG, "Package " + packageName + ": " + message);
|
||||
EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE, packageName, message);
|
||||
continue;
|
||||
// Data is from a "newer" version of the app than we have currently
|
||||
// installed. If the app has not declared that it is prepared to
|
||||
// handle this case, we do not attempt the restore.
|
||||
if ((packageInfo.applicationInfo.flags
|
||||
& ApplicationInfo.FLAG_RESTORE_ANY_VERSION) == 0) {
|
||||
String message = "Version " + metaInfo.versionCode
|
||||
+ " > installed version " + packageInfo.versionCode;
|
||||
Log.w(TAG, "Package " + packageName + ": " + message);
|
||||
EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
|
||||
packageName, message);
|
||||
continue;
|
||||
} else {
|
||||
if (DEBUG) Log.v(TAG, "Version " + metaInfo.versionCode
|
||||
+ " > installed " + packageInfo.versionCode
|
||||
+ " but restoreAnyVersion");
|
||||
}
|
||||
}
|
||||
|
||||
if (!signaturesMatch(metaInfo.signatures, packageInfo)) {
|
||||
@ -1695,8 +1706,10 @@ class BackupManagerService extends IBackupManager.Stub {
|
||||
// The agent was probably running with a stub Application object,
|
||||
// which isn't a valid run mode for the main app logic. Shut
|
||||
// down the app so that next time it's launched, it gets the
|
||||
// usual full initialization.
|
||||
if ((packageInfo.applicationInfo.flags
|
||||
// usual full initialization. Note that this is only done for
|
||||
// full-system restores: when a single app has requested a restore,
|
||||
// it is explicitly not killed following that operation.
|
||||
if (mTargetPackage == null && (packageInfo.applicationInfo.flags
|
||||
& ApplicationInfo.FLAG_KILL_AFTER_RESTORE) != 0) {
|
||||
if (DEBUG) Log.d(TAG, "Restore complete, killing host process of "
|
||||
+ packageInfo.applicationInfo.processName);
|
||||
|
Reference in New Issue
Block a user