diff options
| -rw-r--r-- | api/current.xml | 13 | ||||
| -rw-r--r-- | core/java/android/content/pm/ApplicationInfo.java | 13 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageParser.java | 9 | ||||
| -rw-r--r-- | core/res/res/values/attrs_manifest.xml | 20 | ||||
| -rw-r--r-- | core/res/res/values/public.xml | 1 | ||||
| -rw-r--r-- | services/java/com/android/server/BackupManagerService.java | 27 |
6 files changed, 70 insertions, 13 deletions
diff --git a/api/current.xml b/api/current.xml index 3af1426..031506b 100644 --- a/api/current.xml +++ b/api/current.xml @@ -6785,6 +6785,17 @@ visibility="public" > </field> +<field name="restoreAnyVersion" + type="int" + transient="false" + volatile="false" + value="16843451" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="restoreNeedsApplication" type="int" transient="false" @@ -14630,7 +14641,7 @@ </parameter> <parameter name="features" type="java.lang.String[]"> </parameter> -<parameter name="activityForPrompting" type="android.app.Activity"> +<parameter name="activity" type="android.app.Activity"> </parameter> <parameter name="addAccountOptions" type="android.os.Bundle"> </parameter> diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 2e405c1..8773f59 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -248,6 +248,19 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public static final int FLAG_NATIVE_DEBUGGABLE = 1<<21; /** + * Value for {@link #flags}: Set to true if the application's backup + * agent claims to be able to handle restore data even "from the future," + * i.e. from versions of the application with a versionCode greater than + * the one currently installed on the device. + * + * <p>If android:allowBackup is set to false or no android:backupAgent + * is specified, this flag will be ignored. + * + * {@hide} + */ + public static final int FLAG_RESTORE_ANY_VERSION = 1<<22; + + /** * Flags associated with the application. Any combination of * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE}, * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 5823560..98aacaa 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1369,8 +1369,8 @@ public class PackageParser { if (allowBackup) { ai.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; - // backupAgent, killAfterRestore, and restoreNeedsApplication are only relevant - // if backup is possible for the given application. + // backupAgent, killAfterRestore, restoreNeedsApplication, and restoreAnyVersion + // are only relevant if backup is possible for the given application. String backupAgent = sa.getNonResourceString( com.android.internal.R.styleable.AndroidManifestApplication_backupAgent); if (backupAgent != null) { @@ -1390,6 +1390,11 @@ public class PackageParser { false)) { ai.flags |= ApplicationInfo.FLAG_RESTORE_NEEDS_APPLICATION; } + if (sa.getBoolean( + com.android.internal.R.styleable.AndroidManifestApplication_restoreAnyVersion, + false)) { + ai.flags |= ApplicationInfo.FLAG_RESTORE_ANY_VERSION; + } } } diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index b3adf49..d66f513 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -593,12 +593,15 @@ <attr name="backupAgent" format="string" /> <!-- Whether to allow the application to participate in backup - infrastructure. - STOPSHIP: more explanation --> + infrastructure. If this attribute is set to <code>false</code>, no backup + of the application will ever be performed, even by a full-system backup that + would otherwise cause all application data to be saved via adb. The + default value of this attribute is <code>true</code>. --> <attr name="allowBackup" format="boolean" /> <!-- Whether the application in question should be terminated after its - settings have been restored. The default is to do so. --> + settings have been restored. The default is <code>true</code>, + which means to do so. --> <attr name="killAfterRestore" format="boolean" /> <!-- Whether the application needs to have its own Application subclass @@ -606,6 +609,16 @@ Application class to avoid interference with application logic. --> <attr name="restoreNeedsApplication" format="boolean" /> + <!-- Indicate that the application is prepared to attempt a restore of any + backed-up dataset, even if the backup is apparently from a newer version + of the application than is currently installed on the device. Setting + this attribute to <code>true</code> will permit the Backup Manager to + attempt restore even when a version mismatch suggests that the data are + incompatible. <em>Use with caution!</em> + + <p>The default value of this attribute is <code>false</code>. --> + <attr name="restoreAnyVersion" format="boolean" /> + <!-- The default install location defined by an application. --> <attr name="installLocation"> <!-- Let the system decide ideal install location --> @@ -700,6 +713,7 @@ <attr name="allowBackup" /> <attr name="killAfterRestore" /> <attr name="restoreNeedsApplication" /> + <attr name="restoreAnyVersion" /> <attr name="neverEncrypt" /> </declare-styleable> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index b334337..5da8e85 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -1231,6 +1231,7 @@ <public type="attr" name="safeMode" id="0x010102b8" /> <public type="attr" name="webTextViewStyle" id="0x010102b9" /> <public type="attr" name="overscrollMode" id="0x010102ba" /> + <public type="attr" name="restoreAnyVersion" id="0x010102bb" /> <public type="anim" name="cycle_interpolator" id="0x010a000c" /> diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java index f79a02a..d4b28e2 100644 --- a/services/java/com/android/server/BackupManagerService.java +++ b/services/java/com/android/server/BackupManagerService.java @@ -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); |
