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
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 18e7e4f..f1e226e 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -198,22 +198,26 @@
         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 @@
                 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 @@
         private PackageInfo mTargetPackage;
         private File mStateDir;
         private int mPmToken;
+        private boolean mNeedFullBackup;
 
         class RestoreRequest {
             public PackageInfo app;
@@ -1571,12 +1577,14 @@
         }
 
         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 @@
                 // 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 @@
 
                     // 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 @@
         }
 
         // 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 @@
                 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 @@
             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 @@
                         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 @@
             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;