Merge "[Multi-user] Schedule full backup jobs immediately"
diff --git a/services/backup/java/com/android/server/backup/FullBackupJob.java b/services/backup/java/com/android/server/backup/FullBackupJob.java
index 33d21cb0..f62a875 100644
--- a/services/backup/java/com/android/server/backup/FullBackupJob.java
+++ b/services/backup/java/com/android/server/backup/FullBackupJob.java
@@ -32,9 +32,9 @@
     private static final String USER_ID_EXTRA_KEY = "userId";
 
     @VisibleForTesting
-    static final int MIN_JOB_ID = 52418896;
+    public static final int MIN_JOB_ID = 52418896;
     @VisibleForTesting
-    static final int MAX_JOB_ID = 52419896;
+    public static final int MAX_JOB_ID = 52419896;
 
     private static ComponentName sIdleService =
             new ComponentName("android", FullBackupJob.class.getName());
diff --git a/services/backup/java/com/android/server/backup/KeyValueBackupJob.java b/services/backup/java/com/android/server/backup/KeyValueBackupJob.java
index d43859e..72d81d3 100644
--- a/services/backup/java/com/android/server/backup/KeyValueBackupJob.java
+++ b/services/backup/java/com/android/server/backup/KeyValueBackupJob.java
@@ -58,8 +58,10 @@
     @GuardedBy("KeyValueBackupJob.class")
     private static final SparseLongArray sNextScheduledForUserId = new SparseLongArray();
 
-    private static final int MIN_JOB_ID = 52417896;
-    private static final int MAX_JOB_ID = 52418896;
+    @VisibleForTesting
+    public static final int MIN_JOB_ID = 52417896;
+    @VisibleForTesting
+    public static final int MAX_JOB_ID = 52418896;
 
     public static void schedule(int userId, Context ctx, BackupManagerConstants constants) {
         schedule(userId, ctx, 0, constants);
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 115e924..7d228f1 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -1906,13 +1906,7 @@
                 final long interval = mConstants.getFullBackupIntervalMilliseconds();
                 final long appLatency = (timeSinceLast < interval) ? (interval - timeSinceLast) : 0;
                 final long latency = Math.max(transportMinLatency, appLatency);
-                Runnable r = new Runnable() {
-                    @Override
-                    public void run() {
-                        FullBackupJob.schedule(mUserId, mContext, latency, mConstants);
-                    }
-                };
-                mBackupHandler.postDelayed(r, 2500);
+                FullBackupJob.schedule(mUserId, mContext, latency, mConstants);
             } else {
                 if (DEBUG_SCHEDULING) {
                     Slog.i(TAG, "Full backup queue empty; not scheduling");
@@ -2144,12 +2138,7 @@
                     Slog.i(TAG, "Nothing pending full backup; rescheduling +" + latency);
                 }
                 final long deferTime = latency;     // pin for the closure
-                mBackupHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        FullBackupJob.schedule(mUserId, mContext, deferTime, mConstants);
-                    }
-                });
+                FullBackupJob.schedule(mUserId, mContext, deferTime, mConstants);
                 return false;
             }
 
diff --git a/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java b/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java
index bfb2b14..44e9e6a 100644
--- a/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/internal/SetupObserverTest.java
@@ -18,17 +18,19 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import android.app.job.JobScheduler;
 import android.content.Context;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.platform.test.annotations.Presubmit;
 import android.provider.Settings;
 
+import com.android.server.backup.FullBackupJob;
+import com.android.server.backup.JobIdManager;
 import com.android.server.backup.KeyValueBackupJob;
 import com.android.server.backup.TransportManager;
 import com.android.server.backup.UserBackupManagerService;
 import com.android.server.backup.testing.BackupManagerServiceTestUtils;
-import com.android.server.backup.testing.TestUtils;
 import com.android.server.testing.shadows.ShadowApplicationPackageManager;
 
 import org.junit.Before;
@@ -38,7 +40,9 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
 import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowJobScheduler;
 
 import java.io.File;
 
@@ -47,7 +51,7 @@
  * UserBackupManagerService}.
  */
 @RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowApplicationPackageManager.class})
+@Config(shadows = {ShadowApplicationPackageManager.class, ShadowJobScheduler.class})
 @Presubmit
 public class SetupObserverTest {
     private static final String TAG = "SetupObserverTest";
@@ -58,6 +62,7 @@
     private Context mContext;
     private UserBackupManagerService mUserBackupManagerService;
     private HandlerThread mHandlerThread;
+    private ShadowJobScheduler mShadowJobScheduler;
 
     /** Setup state. */
     @Before
@@ -73,6 +78,7 @@
                         new File(mContext.getDataDir(), "test1"),
                         new File(mContext.getDataDir(), "test2"),
                         mTransportManager);
+        mShadowJobScheduler = Shadows.shadowOf(mContext.getSystemService(JobScheduler.class));
     }
 
     /** Test observer handles changes from not setup -> setup correctly. */
@@ -121,17 +127,27 @@
         // Setup conditions for a full backup job to be scheduled.
         mUserBackupManagerService.setEnabled(true);
         mUserBackupManagerService.enqueueFullBackup("testPackage", /* lastBackedUp */ 0);
-        // Clear the handler of all pending tasks. This is to prevent the below assertion on the
-        // handler from encountering false positives due to other tasks being scheduled as part of
-        // setup work.
-        TestUtils.runToEndOfTasks(mHandlerThread.getLooper());
 
         setupObserver.onChange(true);
 
-        assertThat(KeyValueBackupJob.isScheduled(mUserBackupManagerService.getUserId())).isTrue();
-        // Verifies that the full backup job is scheduled. The job is scheduled via a posted message
-        // on the backup handler so we verify that a message exists.
-        assertThat(mUserBackupManagerService.getBackupHandler().hasMessagesOrCallbacks()).isTrue();
+        assertThat(
+                        mShadowJobScheduler.getPendingJob(
+                                getJobIdForUser(
+                                        KeyValueBackupJob.MIN_JOB_ID,
+                                        KeyValueBackupJob.MAX_JOB_ID,
+                                        USER_ID)))
+                .isNotNull();
+        assertThat(
+                        mShadowJobScheduler.getPendingJob(
+                                getJobIdForUser(
+                                        FullBackupJob.MIN_JOB_ID,
+                                        FullBackupJob.MAX_JOB_ID,
+                                        USER_ID)))
+                .isNotNull();
+    }
+
+    private int getJobIdForUser(int min, int max, int userId) {
+        return JobIdManager.getJobIdForUserId(min, max, userId);
     }
 
     private void changeSetupCompleteSettingForUser(boolean value, int userId) {