Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbff7ed4 authored by Chris Tate's avatar Chris Tate
Browse files

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
parent 6ec91731
Loading
Loading
Loading
Loading
+29 −10
Original line number Diff line number Diff line
@@ -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;