Add new test for job timing out while work is enqueued.

Takes advantage of new job scheduler command to force an immediate
timeout.

Test: ran this.
Change-Id: I721dc8974ce3303ae94705db79464cdc701026e0
diff --git a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
index 1955483..4ade3b5 100644
--- a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
+++ b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
@@ -50,11 +50,14 @@
 
     private JobParameters mParams;
 
-    ArrayList<Intent> mReceivedWork = new ArrayList<Intent>();
+    ArrayList<JobWorkItem> mReceivedWork = new ArrayList<>();
+
+    private boolean mWaitingForStop;
 
     @Override
     public void onDestroy() {
         super.onDestroy();
+        Log.i(TAG, "Destroying test service");
         if (TestEnvironment.getTestEnvironment().getExpectedWork() != null) {
             TestEnvironment.getTestEnvironment().notifyExecution(mParams, 0, 0, mReceivedWork,
                     null);
@@ -99,7 +102,7 @@
             int index = 0;
             while ((work = params.dequeueWork()) != null) {
                 Log.i(TAG, "Received work #" + index + ": " + work.getIntent());
-                mReceivedWork.add(work.getIntent());
+                mReceivedWork.add(work);
 
                 if (index < expectedWork.length) {
                     TestWorkItem expected = expectedWork[index];
@@ -166,9 +169,16 @@
                             }
                         }
                     }
+
+                    if ((expected.flags & TestWorkItem.FLAG_WAIT_FOR_STOP) != 0) {
+                        Log.i(TAG, "Now waiting to stop");
+                        mWaitingForStop = true;
+                        TestEnvironment.getTestEnvironment().notifyWaitingForStop();
+                        return true;
+                    }
                 }
 
-                params.completeWork(work);
+                mParams.completeWork(work);
 
                 if (index < expectedWork.length) {
                     TestWorkItem expected = expectedWork[index];
@@ -198,12 +208,17 @@
 
     @Override
     public boolean onStopJob(JobParameters params) {
-        return false;
+        Log.i(TAG, "Received stop callback");
+        return mWaitingForStop;
     }
 
     public static final class TestWorkItem {
+        public static final int FLAG_WAIT_FOR_STOP = 1<<0;
+
         public final Intent intent;
         public final JobInfo jobInfo;
+        public final int flags;
+        public final int deliveryCount;
         public final TestWorkItem[] subitems;
         public final Uri[] requireUrisGranted;
         public final Uri[] requireUrisNotGranted;
@@ -211,6 +226,18 @@
         public TestWorkItem(Intent _intent) {
             intent = _intent;
             jobInfo = null;
+            flags = 0;
+            deliveryCount = 1;
+            subitems = null;
+            requireUrisGranted = null;
+            requireUrisNotGranted = null;
+        }
+
+        public TestWorkItem(Intent _intent, int _flags, int _deliveryCount) {
+            intent = _intent;
+            jobInfo = null;
+            flags = _flags;
+            deliveryCount = _deliveryCount;
             subitems = null;
             requireUrisGranted = null;
             requireUrisNotGranted = null;
@@ -219,6 +246,8 @@
         public TestWorkItem(Intent _intent, JobInfo _jobInfo, TestWorkItem[] _subitems) {
             intent = _intent;
             jobInfo = _jobInfo;
+            flags = 0;
+            deliveryCount = 1;
             subitems = _subitems;
             requireUrisGranted = null;
             requireUrisNotGranted = null;
@@ -228,10 +257,17 @@
                 Uri[] _requireUrisNotGranted) {
             intent = _intent;
             jobInfo = null;
+            flags = 0;
+            deliveryCount = 1;
             subitems = null;
             requireUrisGranted = _requireUrisGranted;
             requireUrisNotGranted = _requireUrisNotGranted;
         }
+
+        @Override
+        public String toString() {
+            return "TestWorkItem { " + intent + " dc=" + deliveryCount + " }";
+        }
     }
 
     /**
@@ -245,12 +281,13 @@
         //public static final int INVALID_JOB_ID = -1;
 
         private CountDownLatch mLatch;
+        private CountDownLatch mWaitingForStopLatch;
         private CountDownLatch mDoWorkLatch;
         private TestWorkItem[] mExpectedWork;
         private JobParameters mExecutedJobParameters;
         private int mExecutedPermCheckRead;
         private int mExecutedPermCheckWrite;
-        private ArrayList<Intent> mExecutedReceivedWork;
+        private ArrayList<JobWorkItem> mExecutedReceivedWork;
         private String mExecutedErrorMessage;
 
         public static TestEnvironment getTestEnvironment() {
@@ -276,7 +313,7 @@
             return mExecutedPermCheckWrite;
         }
 
-        public ArrayList<Intent> getLastReceivedWork() {
+        public ArrayList<JobWorkItem> getLastReceivedWork() {
             return mExecutedReceivedWork;
         }
 
@@ -305,12 +342,16 @@
             return !mLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
         }
 
+        public boolean awaitWaitingForStop() throws InterruptedException {
+            return !mWaitingForStopLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+        }
+
         public boolean awaitDoWork() throws InterruptedException {
             return !mDoWorkLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
         }
 
         private void notifyExecution(JobParameters params, int permCheckRead, int permCheckWrite,
-                ArrayList<Intent> receivedWork, String errorMsg) {
+                ArrayList<JobWorkItem> receivedWork, String errorMsg) {
             //Log.d(TAG, "Job executed:" + params.getJobId());
             mExecutedJobParameters = params;
             mExecutedPermCheckRead = permCheckRead;
@@ -320,6 +361,10 @@
             mLatch.countDown();
         }
 
+        private void notifyWaitingForStop() {
+            mWaitingForStopLatch.countDown();
+        }
+
         public void setExpectedExecutions(int numExecutions) {
             // For no executions expected, set count to 1 so we can still block for the timeout.
             if (numExecutions == 0) {
@@ -329,6 +374,10 @@
             }
         }
 
+        public void setExpectedWaitForStop() {
+            mWaitingForStopLatch = new CountDownLatch(1);
+        }
+
         public void setExpectedWork(TestWorkItem[] work) {
             mExpectedWork = work;
             mDoWorkLatch = new CountDownLatch(1);