diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java index 9b55c7acab3af..8158d9e3507c9 100644 --- a/services/backup/java/com/android/server/backup/BackupManagerService.java +++ b/services/backup/java/com/android/server/backup/BackupManagerService.java @@ -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 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); - Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task); - sendMessage(restoreMsg); + + 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(); }