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

Commit a88d8e04 authored by Shreyas Basarge's avatar Shreyas Basarge
Browse files

Serialize restore operations

This cl introduces logic to serialize restore
operations. An incoming restore operation will
wait for the currently running restore to
complete.

Bug: 29010684

Test: Tested manually by installing an app while a restore was in
progress.

Change-Id: Ic88fdf2a6dcfab64853fe460c649380eea644774
parent 14fd9ceb
Loading
Loading
Loading
Loading
+49 −7
Original line number Diff line number Diff line
@@ -35,15 +35,15 @@ import android.app.backup.BackupProgress;
import android.app.backup.BackupTransport;
import android.app.backup.FullBackup;
import android.app.backup.FullBackupDataOutput;
import android.app.backup.IBackupObserver;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.RestoreDescription;
import android.app.backup.RestoreSet;
import android.app.backup.IBackupManager;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
import android.app.backup.IFullBackupRestoreObserver;
import android.app.backup.IRestoreObserver;
import android.app.backup.IRestoreSession;
import android.app.backup.ISelectBackupTransportCallback;
import android.app.backup.RestoreDescription;
import android.app.backup.RestoreSet;
import android.app.backup.SelectBackupTransportCallback;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
@@ -133,6 +133,7 @@ import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -143,6 +144,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Queue;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
@@ -324,6 +326,11 @@ public class BackupManagerService {
    final Object mClearDataLock = new Object();
    volatile boolean mClearingData;

    @GuardedBy("mPendingRestores")
    private boolean mIsRestoreInProgress;
    @GuardedBy("mPendingRestores")
    private final Queue<PerformUnifiedRestoreTask> mPendingRestores = new ArrayDeque<>();

    ActiveRestoreSession mActiveRestoreSession;

    // Watch the device provisioning operation during setup
@@ -906,11 +913,28 @@ public class BackupManagerService {
            {
                RestoreParams params = (RestoreParams)msg.obj;
                Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
                BackupRestoreTask task = new PerformUnifiedRestoreTask(params.transport,

                PerformUnifiedRestoreTask task = new PerformUnifiedRestoreTask(params.transport,
                        params.observer, params.monitor, params.token, params.pkgInfo,
                        params.pmToken, params.isSystemRestore, params.filterSet);

                synchronized (mPendingRestores) {
                    if (mIsRestoreInProgress) {
                        if (DEBUG) {
                            Slog.d(TAG, "Restore in progress, queueing.");
                        }
                        mPendingRestores.add(task);
                        // This task will be picked up and executed when the the currently running
                        // restore task finishes.
                    } else {
                        if (DEBUG) {
                            Slog.d(TAG, "Starting restore.");
                        }
                        mIsRestoreInProgress = true;
                        Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
                        sendMessage(restoreMsg);
                    }
                }
                break;
            }

@@ -9103,6 +9127,24 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF

            // done; we can finally release the wakelock and be legitimately done.
            Slog.i(TAG, "Restore complete.");

            synchronized (mPendingRestores) {
                if (mPendingRestores.size() > 0) {
                    if (DEBUG) {
                        Slog.d(TAG, "Starting next pending restore.");
                    }
                    PerformUnifiedRestoreTask task = mPendingRestores.remove();
                    mBackupHandler.sendMessage(
                            mBackupHandler.obtainMessage(MSG_BACKUP_RESTORE_STEP, task));

                } else {
                    mIsRestoreInProgress = false;
                    if (MORE_DEBUG) {
                        Slog.d(TAG, "No pending restores.");
                    }
                }
            }

            mWakelock.release();
        }