Merge "DO NOT MERGE Unrevert update references to backup agent timeouts" into pi-dev
diff --git a/services/backup/java/com/android/server/backup/BackupAgentTimeoutParameters.java b/services/backup/java/com/android/server/backup/BackupAgentTimeoutParameters.java
index 4de2c9b..49fa1cc 100644
--- a/services/backup/java/com/android/server/backup/BackupAgentTimeoutParameters.java
+++ b/services/backup/java/com/android/server/backup/BackupAgentTimeoutParameters.java
@@ -21,6 +21,7 @@
 import android.provider.Settings;
 import android.util.KeyValueListParser;
 import android.util.KeyValueSettingObserver;
+import android.util.Slog;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -31,6 +32,8 @@
  * are represented as a comma-delimited key value list.
  */
 public class BackupAgentTimeoutParameters extends KeyValueSettingObserver {
+    private static final String TAG = "BackupAgentTimeout";
+
     @VisibleForTesting
     public static final String SETTING = Settings.Global.BACKUP_AGENT_TIMEOUT_PARAMETERS;
 
@@ -120,30 +123,50 @@
 
     public long getKvBackupAgentTimeoutMillis() {
         synchronized (mLock) {
+            if (BackupManagerService.DEBUG_SCHEDULING) {
+                Slog.v(TAG, "getKvBackupAgentTimeoutMillis(): " + mKvBackupAgentTimeoutMillis);
+            }
             return mKvBackupAgentTimeoutMillis;
         }
     }
 
     public long getFullBackupAgentTimeoutMillis() {
         synchronized (mLock) {
+            if (BackupManagerService.DEBUG_SCHEDULING) {
+                Slog.v(TAG, "getFullBackupAgentTimeoutMillis(): " + mFullBackupAgentTimeoutMillis);
+            }
             return mFullBackupAgentTimeoutMillis;
         }
     }
 
     public long getSharedBackupAgentTimeoutMillis() {
         synchronized (mLock) {
+            if (BackupManagerService.DEBUG_SCHEDULING) {
+                Slog.v(
+                        TAG,
+                        "getSharedBackupAgentTimeoutMillis(): " + mSharedBackupAgentTimeoutMillis);
+            }
             return mSharedBackupAgentTimeoutMillis;
         }
     }
 
     public long getRestoreAgentTimeoutMillis() {
         synchronized (mLock) {
+            if (BackupManagerService.DEBUG_SCHEDULING) {
+                Slog.v(TAG, "getRestoreAgentTimeoutMillis(): " + mRestoreAgentTimeoutMillis);
+            }
             return mRestoreAgentTimeoutMillis;
         }
     }
 
     public long getRestoreAgentFinishedTimeoutMillis() {
         synchronized (mLock) {
+            if (BackupManagerService.DEBUG_SCHEDULING) {
+                Slog.v(
+                        TAG,
+                        "getRestoreAgentFinishedTimeoutMillis(): "
+                                + mRestoreAgentFinishedTimeoutMillis);
+            }
             return mRestoreAgentFinishedTimeoutMillis;
         }
     }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index d6f6c6c..bd51af2 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -215,13 +215,6 @@
     // Timeout interval for deciding that a bind or clear-data has taken too long
     private static final long TIMEOUT_INTERVAL = 10 * 1000;
 
-    // Timeout intervals for agent backup & restore operations
-    public static final long TIMEOUT_BACKUP_INTERVAL = 30 * 1000;
-    public static final long TIMEOUT_FULL_BACKUP_INTERVAL = 5 * 60 * 1000;
-    public static final long TIMEOUT_SHARED_BACKUP_INTERVAL = 30 * 60 * 1000;
-    public static final long TIMEOUT_RESTORE_INTERVAL = 60 * 1000;
-    public static final long TIMEOUT_RESTORE_FINISHED_INTERVAL = 30 * 1000;
-
     // User confirmation timeout for a full backup/restore operation.  It's this long in
     // order to give them time to enter the backup password.
     private static final long TIMEOUT_FULL_CONFIRMATION = 60 * 1000;
@@ -232,6 +225,7 @@
     private static final int BUSY_BACKOFF_FUZZ = 1000 * 60 * 60 * 2;  // two hours
 
     private BackupManagerConstants mConstants;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
     private Context mContext;
     private PackageManager mPackageManager;
     private IPackageManager mPackageManagerBinder;
@@ -315,6 +309,10 @@
         return mConstants;
     }
 
+    public BackupAgentTimeoutParameters getAgentTimeoutParameters() {
+        return mAgentTimeoutParameters;
+    }
+
     public Context getContext() {
         return mContext;
     }
@@ -799,6 +797,10 @@
 
         mBackupManagerBinder = Trampoline.asInterface(parent.asBinder());
 
+        mAgentTimeoutParameters = new
+                BackupAgentTimeoutParameters(Handler.getMain(), mContext.getContentResolver());
+        mAgentTimeoutParameters.start();
+
         // spin up the backup/restore handler thread
         mBackupHandler = new BackupHandler(this, backupThread.getLooper());
 
@@ -3407,7 +3409,7 @@
             }
             mActiveRestoreSession = new ActiveRestoreSession(this, packageName, transport);
             mBackupHandler.sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT,
-                    TIMEOUT_RESTORE_INTERVAL);
+                    mAgentTimeoutParameters.getRestoreAgentTimeoutMillis());
         }
         return mActiveRestoreSession;
     }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
index 7b021c6..aabe7f6 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
@@ -191,4 +191,7 @@
   void dump(FileDescriptor fd, PrintWriter pw, String[] args);
 
   IBackupManager getBackupManagerBinder();
+
+  // Gets access to the backup/restore agent timeout parameters.
+  BackupAgentTimeoutParameters getAgentTimeoutParameters();
 }
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
index 4755877..7f0030a 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
@@ -4,8 +4,8 @@
 import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
 import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
 import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
+
 import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_BACKUP_INTERVAL;
 
 import android.app.ApplicationThreadConstants;
 import android.app.IBackupAgent;
@@ -19,6 +19,7 @@
 import android.os.SELinux;
 import android.util.Slog;
 
+import com.android.internal.util.Preconditions;
 import com.android.server.backup.utils.FullBackupUtils;
 
 import libcore.io.IoUtils;
@@ -59,6 +60,7 @@
     private ParcelFileDescriptor mSavedState;
     private ParcelFileDescriptor mBackupData;
     private ParcelFileDescriptor mNewState;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
 
     public KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
             BackupManagerServiceInterface backupManagerService, PackageManager packageManager,
@@ -81,6 +83,9 @@
                 pkg + BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX);
 
         mManifestFile = new File(mDataDir, BackupManagerService.BACKUP_MANIFEST_FILENAME);
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
     }
 
     public void backupOnePackage() throws IOException {
@@ -148,8 +153,9 @@
     // Return true on backup success, false otherwise
     private boolean invokeAgentForAdbBackup(String packageName, IBackupAgent agent) {
         int token = mBackupManagerService.generateRandomIntegerToken();
+        long kvBackupAgentTimeoutMillis = mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis();
         try {
-            mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
+            mBackupManagerService.prepareOperationTimeout(token, kvBackupAgentTimeoutMillis, null,
                     OP_TYPE_BACKUP_WAIT);
 
             // Start backup and wait for BackupManagerService to get callback for success or timeout
@@ -231,14 +237,14 @@
     }
 
     private void writeBackupData() throws IOException {
-
         int token = mBackupManagerService.generateRandomIntegerToken();
+        long kvBackupAgentTimeoutMillis = mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis();
 
         ParcelFileDescriptor[] pipes = null;
         try {
             pipes = ParcelFileDescriptor.createPipe();
 
-            mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
+            mBackupManagerService.prepareOperationTimeout(token, kvBackupAgentTimeoutMillis, null,
                     OP_TYPE_BACKUP_WAIT);
 
             // We will have to create a runnable that will read the manifest and backup data we
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
index 0582aba..5694659 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupEngine.java
@@ -25,9 +25,6 @@
 import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
 import static com.android.server.backup.BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
 import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
-import static com.android.server.backup.BackupManagerService
-        .TIMEOUT_SHARED_BACKUP_INTERVAL;
 
 import android.app.ApplicationThreadConstants;
 import android.app.IBackupAgent;
@@ -44,9 +41,11 @@
 import android.util.Slog;
 import android.util.StringBuilderPrinter;
 
+import com.android.internal.util.Preconditions;
 import com.android.server.AppWidgetBackupBridge;
-import com.android.server.backup.BackupRestoreTask;
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupManagerService;
+import com.android.server.backup.BackupRestoreTask;
 import com.android.server.backup.utils.FullBackupUtils;
 
 import java.io.BufferedOutputStream;
@@ -75,6 +74,7 @@
     private final long mQuota;
     private final int mOpToken;
     private final int mTransportFlags;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
 
     class FullBackupRunner implements Runnable {
 
@@ -137,8 +137,8 @@
                 final boolean isSharedStorage =
                         mPackage.packageName.equals(SHARED_BACKUP_AGENT_PACKAGE);
                 final long timeout = isSharedStorage ?
-                        TIMEOUT_SHARED_BACKUP_INTERVAL :
-                        TIMEOUT_FULL_BACKUP_INTERVAL;
+                        mAgentTimeoutParameters.getSharedBackupAgentTimeoutMillis() :
+                        mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
 
                 if (DEBUG) {
                     Slog.d(TAG, "Calling doFullBackup() on " + mPackage.packageName);
@@ -180,6 +180,9 @@
         mQuota = quota;
         mOpToken = opToken;
         mTransportFlags = transportFlags;
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
     }
 
     public int preflightCheck() throws RemoteException {
diff --git a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
index 40b6967..bc7d9fc 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/FullBackupObbConnection.java
@@ -19,7 +19,6 @@
 import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
 import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
 import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
 
 import android.app.backup.IBackupManager;
 import android.content.ComponentName;
@@ -33,6 +32,8 @@
 import android.util.Slog;
 
 import com.android.internal.backup.IObbBackupService;
+import com.android.internal.util.Preconditions;
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.utils.FullBackupUtils;
 
@@ -46,10 +47,14 @@
 
     private BackupManagerService backupManagerService;
     volatile IObbBackupService mService;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
 
     public FullBackupObbConnection(BackupManagerService backupManagerService) {
         this.backupManagerService = backupManagerService;
         mService = null;
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
     }
 
     public void establish() {
@@ -75,8 +80,10 @@
         try {
             pipes = ParcelFileDescriptor.createPipe();
             int token = backupManagerService.generateRandomIntegerToken();
+            long fullBackupAgentTimeoutMillis =
+                    mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
             backupManagerService.prepareOperationTimeout(
-                    token, TIMEOUT_FULL_BACKUP_INTERVAL, null, OP_TYPE_BACKUP_WAIT);
+                    token, fullBackupAgentTimeoutMillis, null, OP_TYPE_BACKUP_WAIT);
             mService.backupObbs(pkg.packageName, pipes[1], token,
                     backupManagerService.getBackupManagerBinder());
             FullBackupUtils.routeSocketDataToOutput(pipes[0], out);
diff --git a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
index 2c2dd85..a40afc3 100644
--- a/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
+++ b/services/backup/java/com/android/server/backup/fullbackup/PerformFullTransportBackupTask.java
@@ -22,7 +22,6 @@
 import static com.android.server.backup.BackupManagerService.OP_PENDING;
 import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP;
 import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
 
 import android.annotation.Nullable;
 import android.app.IBackupAgent;
@@ -43,7 +42,9 @@
 import android.util.Slog;
 
 import com.android.internal.backup.IBackupTransport;
+import com.android.internal.util.Preconditions;
 import com.android.server.EventLogTags;
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupRestoreTask;
 import com.android.server.backup.FullBackupJob;
 import com.android.server.backup.BackupManagerService;
@@ -146,6 +147,7 @@
     private volatile boolean mIsDoingBackup;
     private volatile boolean mCancelAll;
     private final int mCurrentOpToken;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
 
     public PerformFullTransportBackupTask(BackupManagerService backupManagerService,
             TransportClient transportClient,
@@ -167,6 +169,9 @@
         mUserInitiated = userInitiated;
         mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
         mBackupRunnerOpToken = backupManagerService.generateRandomIntegerToken();
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
 
         if (backupManagerService.isBackupOperationInProgress()) {
             if (DEBUG) {
@@ -698,9 +703,11 @@
         @Override
         public int preflightFullBackup(PackageInfo pkg, IBackupAgent agent) {
             int result;
+            long fullBackupAgentTimeoutMillis =
+                    mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
             try {
                 backupManagerService.prepareOperationTimeout(
-                        mCurrentOpToken, TIMEOUT_FULL_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
+                        mCurrentOpToken, fullBackupAgentTimeoutMillis, this, OP_TYPE_BACKUP_WAIT);
                 backupManagerService.addBackupTrace("preflighting");
                 if (MORE_DEBUG) {
                     Slog.d(TAG, "Preflighting full payload of " + pkg.packageName);
@@ -713,7 +720,7 @@
                 // timeout had been produced.  In case of a real backstop timeout, mResult
                 // will still contain the value it was constructed with, AGENT_ERROR, which
                 // intentionaly falls into the "just report failure" code.
-                mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                mLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
 
                 long totalSize = mResult.get();
                 // If preflight timed out, mResult will contain error code as int.
@@ -769,8 +776,10 @@
 
         @Override
         public long getExpectedSizeOrErrorCode() {
+            long fullBackupAgentTimeoutMillis =
+                    mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
             try {
-                mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                mLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
                 return mResult.get();
             } catch (InterruptedException e) {
                 return BackupTransport.NO_MORE_DATA;
@@ -863,8 +872,10 @@
         // If preflight succeeded, returns positive number - preflight size,
         // otherwise return negative error code.
         long getPreflightResultBlocking() {
+            long fullBackupAgentTimeoutMillis =
+                    mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
             try {
-                mPreflightLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                mPreflightLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
                 if (mIsCancelled) {
                     return BackupManager.ERROR_BACKUP_CANCELLED;
                 }
@@ -879,8 +890,10 @@
         }
 
         int getBackupResultBlocking() {
+            long fullBackupAgentTimeoutMillis =
+                    mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
             try {
-                mBackupLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+                mBackupLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
                 if (mIsCancelled) {
                     return BackupManager.ERROR_BACKUP_CANCELLED;
                 }
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
index 136fada..69f08ae 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupHandler.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -19,7 +19,6 @@
 import static com.android.server.backup.BackupManagerService.DEBUG;
 import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
 import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_RESTORE_INTERVAL;
 
 import android.app.backup.RestoreSet;
 import android.content.Intent;
@@ -33,7 +32,9 @@
 import android.util.Slog;
 
 import com.android.internal.backup.IBackupTransport;
+import com.android.internal.util.Preconditions;
 import com.android.server.EventLogTags;
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.BackupRestoreTask;
 import com.android.server.backup.DataChangedJournal;
@@ -81,10 +82,14 @@
     public static final int MSG_OP_COMPLETE = 21;
 
     private final BackupManagerService backupManagerService;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
 
     public BackupHandler(BackupManagerService backupManagerService, Looper looper) {
         super(looper);
         this.backupManagerService = backupManagerService;
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
     }
 
     public void handleMessage(Message msg) {
@@ -322,7 +327,8 @@
 
                     // Done: reset the session timeout clock
                     removeMessages(MSG_RESTORE_SESSION_TIMEOUT);
-                    sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT, TIMEOUT_RESTORE_INTERVAL);
+                    sendEmptyMessageDelayed(MSG_RESTORE_SESSION_TIMEOUT,
+                            mAgentTimeoutParameters.getRestoreAgentTimeoutMillis());
 
                     params.listener.onFinished(callerLogString);
                 }
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
index 11394e66..ac605b1 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -24,7 +24,6 @@
 import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP;
 import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
 import static com.android.server.backup.BackupManagerService.PACKAGE_MANAGER_SENTINEL;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_BACKUP_INTERVAL;
 import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_OPERATION_TIMEOUT;
 import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
 
@@ -55,8 +54,10 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.backup.IBackupTransport;
+import com.android.internal.util.Preconditions;
 import com.android.server.AppWidgetBackupBridge;
 import com.android.server.EventLogTags;
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupRestoreTask;
 import com.android.server.backup.DataChangedJournal;
 import com.android.server.backup.KeyValueBackupJob;
@@ -142,6 +143,7 @@
     private boolean mFinished;
     private final boolean mUserInitiated;
     private final boolean mNonIncremental;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
 
     private volatile boolean mCancelAll;
 
@@ -162,6 +164,9 @@
         mPendingFullBackups = pendingFullBackups;
         mUserInitiated = userInitiated;
         mNonIncremental = nonIncremental;
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
 
         mStateDir = new File(backupManagerService.getBaseStateDir(), dirName);
         mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
@@ -711,8 +716,10 @@
 
             // Initiate the target's backup pass
             backupManagerService.addBackupTrace("setting timeout");
+            long kvBackupAgentTimeoutMillis =
+                    mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis();
             backupManagerService.prepareOperationTimeout(
-                    mEphemeralOpToken, TIMEOUT_BACKUP_INTERVAL, this, OP_TYPE_BACKUP_WAIT);
+                    mEphemeralOpToken, kvBackupAgentTimeoutMillis, this, OP_TYPE_BACKUP_WAIT);
             backupManagerService.addBackupTrace("calling agent doBackup()");
 
             agent.doBackup(
diff --git a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
index e4f3a9d..a8c7ce6 100644
--- a/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
+++ b/services/backup/java/com/android/server/backup/restore/AdbRestoreFinishedLatch.java
@@ -18,10 +18,11 @@
 
 import static com.android.server.backup.BackupManagerService.DEBUG;
 import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
 
 import android.util.Slog;
 
+import com.android.internal.util.Preconditions;
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.BackupRestoreTask;
 
@@ -37,18 +38,24 @@
     private BackupManagerService backupManagerService;
     final CountDownLatch mLatch;
     private final int mCurrentOpToken;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
 
     public AdbRestoreFinishedLatch(BackupManagerService backupManagerService,
             int currentOpToken) {
         this.backupManagerService = backupManagerService;
         mLatch = new CountDownLatch(1);
         mCurrentOpToken = currentOpToken;
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
     }
 
     void await() {
         boolean latched = false;
+        long fullBackupAgentTimeoutMillis =
+                mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
         try {
-            latched = mLatch.await(TIMEOUT_FULL_BACKUP_INTERVAL, TimeUnit.MILLISECONDS);
+            latched = mLatch.await(fullBackupAgentTimeoutMillis, TimeUnit.MILLISECONDS);
         } catch (InterruptedException e) {
             Slog.w(TAG, "Interrupted!");
         }
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index c1a1c1d..b1b0664 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -23,9 +23,6 @@
 import static com.android.server.backup.BackupManagerService.OP_TYPE_RESTORE_WAIT;
 import static com.android.server.backup.BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
 import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_RESTORE_INTERVAL;
-import static com.android.server.backup.BackupManagerService
-        .TIMEOUT_SHARED_BACKUP_INTERVAL;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 
 import android.app.ApplicationThreadConstants;
@@ -42,11 +39,13 @@
 import android.os.RemoteException;
 import android.util.Slog;
 
+import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
+import com.android.server.backup.BackupAgentTimeoutParameters;
+import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.BackupRestoreTask;
 import com.android.server.backup.FileMetadata;
 import com.android.server.backup.KeyValueAdbRestoreEngine;
-import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.fullbackup.FullBackupObbConnection;
 import com.android.server.backup.utils.BytesReadListener;
 import com.android.server.backup.utils.FullBackupRestoreObserverUtils;
@@ -121,6 +120,8 @@
 
     final int mEphemeralOpToken;
 
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
+
     public FullRestoreEngine(BackupManagerService backupManagerService,
             BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
             IBackupManagerMonitor monitor, PackageInfo onlyPackage, boolean allowApks,
@@ -135,6 +136,9 @@
         mAllowObbs = allowObbs;
         mBuffer = new byte[32 * 1024];
         mBytes = 0;
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
     }
 
     public IBackupAgent getAgent() {
@@ -381,8 +385,8 @@
                         long toCopy = info.size;
                         final boolean isSharedStorage = pkg.equals(SHARED_BACKUP_AGENT_PACKAGE);
                         final long timeout = isSharedStorage ?
-                                TIMEOUT_SHARED_BACKUP_INTERVAL :
-                                TIMEOUT_RESTORE_INTERVAL;
+                                mAgentTimeoutParameters.getSharedBackupAgentTimeoutMillis() :
+                                mAgentTimeoutParameters.getRestoreAgentTimeoutMillis();
                         try {
                             mBackupManagerService.prepareOperationTimeout(token,
                                     timeout,
diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
index dacde0b..77163d3 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java
@@ -16,8 +16,6 @@
 
 package com.android.server.backup.restore;
 
-import static com.android.server.backup.BackupPasswordManager.PBKDF_CURRENT;
-import static com.android.server.backup.BackupPasswordManager.PBKDF_FALLBACK;
 import static com.android.server.backup.BackupManagerService.BACKUP_FILE_HEADER_MAGIC;
 import static com.android.server.backup.BackupManagerService.BACKUP_FILE_VERSION;
 import static com.android.server.backup.BackupManagerService.BACKUP_MANIFEST_FILENAME;
@@ -28,8 +26,8 @@
 import static com.android.server.backup.BackupManagerService.SETTINGS_PACKAGE;
 import static com.android.server.backup.BackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
 import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_FULL_BACKUP_INTERVAL;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_RESTORE_INTERVAL;
+import static com.android.server.backup.BackupPasswordManager.PBKDF_CURRENT;
+import static com.android.server.backup.BackupPasswordManager.PBKDF_FALLBACK;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 
 import android.app.ApplicationThreadConstants;
@@ -48,7 +46,9 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.FileMetadata;
 import com.android.server.backup.KeyValueAdbRestoreEngine;
@@ -101,6 +101,7 @@
     private byte[] mWidgetData = null;
 
     private long mBytes;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
 
     // Runner that can be placed on a separate thread to do in-process invocation
     // of the "restore finished" API asynchronously.  Used by adb restore.
@@ -155,6 +156,9 @@
         mAgentPackage = null;
         mTargetApp = null;
         mObbConnection = new FullBackupObbConnection(backupManagerService);
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
 
         // Which packages we've already wiped data on.  We prepopulate this
         // with a whitelist of packages known to be unclearable.
@@ -643,9 +647,11 @@
                     if (okay) {
                         boolean agentSuccess = true;
                         long toCopy = info.size;
+                        long restoreAgentTimeoutMillis =
+                                mAgentTimeoutParameters.getRestoreAgentTimeoutMillis();
                         try {
                             mBackupManagerService.prepareOperationTimeout(
-                                    token, TIMEOUT_RESTORE_INTERVAL, null, OP_TYPE_RESTORE_WAIT);
+                                    token, restoreAgentTimeoutMillis, null, OP_TYPE_RESTORE_WAIT);
 
                             if (FullBackup.OBB_TREE_TOKEN.equals(info.domain)) {
                                 if (DEBUG) {
@@ -820,10 +826,12 @@
                 // In the adb restore case, we do restore-finished here
                 if (doRestoreFinished) {
                     final int token = mBackupManagerService.generateRandomIntegerToken();
+                    long fullBackupAgentTimeoutMillis =
+                            mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
                     final AdbRestoreFinishedLatch latch = new AdbRestoreFinishedLatch(
                             mBackupManagerService, token);
                     mBackupManagerService.prepareOperationTimeout(
-                            token, TIMEOUT_FULL_BACKUP_INTERVAL, latch, OP_TYPE_RESTORE_WAIT);
+                            token, fullBackupAgentTimeoutMillis, latch, OP_TYPE_RESTORE_WAIT);
                     if (mTargetApp.processName.equals("system")) {
                         if (MORE_DEBUG) {
                             Slog.d(TAG, "system agent - restoreFinished on thread");
diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
index 4b467e5..12d72d8 100644
--- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
+++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java
@@ -23,9 +23,6 @@
 import static com.android.server.backup.BackupManagerService.PACKAGE_MANAGER_SENTINEL;
 import static com.android.server.backup.BackupManagerService.SETTINGS_PACKAGE;
 import static com.android.server.backup.BackupManagerService.TAG;
-import static com.android.server.backup.BackupManagerService
-        .TIMEOUT_RESTORE_FINISHED_INTERVAL;
-import static com.android.server.backup.BackupManagerService.TIMEOUT_RESTORE_INTERVAL;
 import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
 import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_SESSION_TIMEOUT;
@@ -56,9 +53,11 @@
 import android.util.Slog;
 
 import com.android.internal.backup.IBackupTransport;
+import com.android.internal.util.Preconditions;
 import com.android.server.AppWidgetBackupBridge;
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupRestoreTask;
 import com.android.server.backup.BackupUtils;
 import com.android.server.backup.PackageManagerBackupAgent;
@@ -160,6 +159,7 @@
     ParcelFileDescriptor mNewState;
 
     private final int mEphemeralOpToken;
+    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
 
     // This task can assume that the wakelock is properly held for it and doesn't have to worry
     // about releasing it.
@@ -190,6 +190,9 @@
         mFinished = false;
         mDidLaunch = false;
         mListener = listener;
+        mAgentTimeoutParameters = Preconditions.checkNotNull(
+                backupManagerService.getAgentTimeoutParameters(),
+                "Timeout parameters cannot be null");
 
         if (targetPackage != null) {
             // Single package restore
@@ -760,8 +763,9 @@
             // Kick off the restore, checking for hung agents.  The timeout or
             // the operationComplete() callback will schedule the next step,
             // so we do not do that here.
+            long restoreAgentTimeoutMillis = mAgentTimeoutParameters.getRestoreAgentTimeoutMillis();
             backupManagerService.prepareOperationTimeout(
-                    mEphemeralOpToken, TIMEOUT_RESTORE_INTERVAL, this, OP_TYPE_RESTORE_WAIT);
+                    mEphemeralOpToken, restoreAgentTimeoutMillis, this, OP_TYPE_RESTORE_WAIT);
             mAgent.doRestore(mBackupData, appVersionCode, mNewState,
                     mEphemeralOpToken, backupManagerService.getBackupManagerBinder());
         } catch (Exception e) {
@@ -813,9 +817,11 @@
             Slog.d(TAG, "restoreFinished packageName=" + mCurrentPackage.packageName);
         }
         try {
+            long restoreAgentFinishedTimeoutMillis =
+                    mAgentTimeoutParameters.getRestoreAgentFinishedTimeoutMillis();
             backupManagerService
                     .prepareOperationTimeout(mEphemeralOpToken,
-                            TIMEOUT_RESTORE_FINISHED_INTERVAL, this,
+                            restoreAgentFinishedTimeoutMillis, this,
                             OP_TYPE_RESTORE_WAIT);
             mAgent.doRestoreFinished(mEphemeralOpToken,
                     backupManagerService.getBackupManagerBinder());
@@ -1109,9 +1115,10 @@
         } else {
             // We were invoked via an active restore session, not by the Package
             // Manager, so start up the session timeout again.
+            long restoreAgentTimeoutMillis = mAgentTimeoutParameters.getRestoreAgentTimeoutMillis();
             backupManagerService.getBackupHandler().sendEmptyMessageDelayed(
                     MSG_RESTORE_SESSION_TIMEOUT,
-                    TIMEOUT_RESTORE_INTERVAL);
+                    restoreAgentTimeoutMillis);
         }
 
         // Kick off any work that may be needed regarding app widget restores
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index f603a09..fa41220 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -147,6 +147,15 @@
 
         Looper backupLooper = startBackupThreadAndGetLooper();
         mShadowBackupLooper = shadowOf(backupLooper);
+
+        Handler mainHandler = new Handler(Looper.getMainLooper());
+        BackupAgentTimeoutParameters agentTimeoutParameters =
+                new BackupAgentTimeoutParameters(mainHandler, application.getContentResolver());
+        agentTimeoutParameters.start();
+
+        // We need to mock BMS timeout parameters before initializing the BackupHandler since
+        // the constructor of BackupHandler relies on the timeout parameters.
+        when(mBackupManagerService.getAgentTimeoutParameters()).thenReturn(agentTimeoutParameters);
         mBackupHandler = new BackupHandler(mBackupManagerService, backupLooper);
 
         mBackupManager = spy(FakeIBackupManager.class);
@@ -157,7 +166,8 @@
                 mTransportManager,
                 packageManager,
                 mBackupHandler,
-                mWakeLock);
+                mWakeLock,
+                agentTimeoutParameters);
         when(mBackupManagerService.getBaseStateDir()).thenReturn(mBaseStateDir);
         when(mBackupManagerService.getDataDir()).thenReturn(dataDir);
         when(mBackupManagerService.getBackupManagerBinder()).thenReturn(mBackupManager);
diff --git a/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java b/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
index 03792b1..92d6bbd 100644
--- a/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
+++ b/services/robotests/src/com/android/server/backup/restore/ActiveRestoreSessionTest.java
@@ -41,12 +41,14 @@
 import android.app.backup.RestoreSet;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.os.Handler;
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.platform.test.annotations.Presubmit;
 
 import com.android.server.EventLogTags;
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.TransportManager;
 import com.android.server.backup.internal.BackupHandler;
@@ -115,6 +117,15 @@
 
         Looper backupLooper = startBackupThreadAndGetLooper();
         mShadowBackupLooper = shadowOf(backupLooper);
+
+        Handler mainHandler = new Handler(Looper.getMainLooper());
+        BackupAgentTimeoutParameters agentTimeoutParameters =
+                new BackupAgentTimeoutParameters(mainHandler, application.getContentResolver());
+        agentTimeoutParameters.start();
+
+        // We need to mock BMS timeout parameters before initializing the BackupHandler since
+        // the constructor of BackupHandler relies on it.
+        when(mBackupManagerService.getAgentTimeoutParameters()).thenReturn(agentTimeoutParameters);
         BackupHandler backupHandler = new BackupHandler(mBackupManagerService, backupLooper);
 
         mWakeLock = createBackupWakeLock(application);
@@ -125,7 +136,8 @@
                 mTransportManager,
                 application.getPackageManager(),
                 backupHandler,
-                mWakeLock);
+                mWakeLock,
+                agentTimeoutParameters);
         when(mBackupManagerService.getPendingRestores()).thenReturn(new ArrayDeque<>());
     }
 
diff --git a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
index c210fde..5a886e3 100644
--- a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
@@ -28,6 +28,7 @@
 import android.os.PowerManager;
 import android.util.SparseArray;
 
+import com.android.server.backup.BackupAgentTimeoutParameters;
 import com.android.server.backup.BackupManagerService;
 import com.android.server.backup.TransportManager;
 import com.android.server.backup.internal.BackupHandler;
@@ -43,7 +44,8 @@
             TransportManager transportManager,
             PackageManager packageManager,
             BackupHandler backupHandler,
-            PowerManager.WakeLock wakeLock) {
+            PowerManager.WakeLock wakeLock,
+            BackupAgentTimeoutParameters agentTimeoutParameters) {
         when(backupManagerService.getContext()).thenReturn(context);
         when(backupManagerService.getTransportManager()).thenReturn(transportManager);
         when(backupManagerService.getPackageManager()).thenReturn(packageManager);
@@ -53,6 +55,7 @@
         when(backupManagerService.getCurrentOperations()).thenReturn(new SparseArray<>());
         when(backupManagerService.getActivityManager()).thenReturn(mock(IActivityManager.class));
         when(backupManagerService.getWakelock()).thenReturn(wakeLock);
+        when(backupManagerService.getAgentTimeoutParameters()).thenReturn(agentTimeoutParameters);
     }
 
     public static PowerManager.WakeLock createBackupWakeLock(Application application) {