Merge "Fix and clean up JS tests." into sc-dev
diff --git a/tests/JobScheduler/AndroidManifest.xml b/tests/JobScheduler/AndroidManifest.xml
index b6f319b..b06a7d8 100755
--- a/tests/JobScheduler/AndroidManifest.xml
+++ b/tests/JobScheduler/AndroidManifest.xml
@@ -23,6 +23,7 @@
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.TOGGLE_AUTOMOTIVE_PROJECTION" />
diff --git a/tests/JobScheduler/JobTestApp/AndroidManifest.xml b/tests/JobScheduler/JobTestApp/AndroidManifest.xml
index 9266377..8842541 100644
--- a/tests/JobScheduler/JobTestApp/AndroidManifest.xml
+++ b/tests/JobScheduler/JobTestApp/AndroidManifest.xml
@@ -17,6 +17,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="android.jobscheduler.cts.jobtestapp">
 
+    <uses-permission android:name="android.permission.INTERNET" />
+
     <!-- This application schedules jobs independently of the test instrumentation to make
     it possible to test behaviour for different app states, whitelists and device idle modes -->
     <application android:debuggable="true">
diff --git a/tests/JobScheduler/JobTestApp/src/android/jobscheduler/cts/jobtestapp/TestActivity.java b/tests/JobScheduler/JobTestApp/src/android/jobscheduler/cts/jobtestapp/TestActivity.java
index 1bb500d..89a317c 100644
--- a/tests/JobScheduler/JobTestApp/src/android/jobscheduler/cts/jobtestapp/TestActivity.java
+++ b/tests/JobScheduler/JobTestApp/src/android/jobscheduler/cts/jobtestapp/TestActivity.java
@@ -32,7 +32,6 @@
 public class TestActivity extends Activity {
     private static final String TAG = TestActivity.class.getSimpleName();
     private static final String PACKAGE_NAME = "android.jobscheduler.cts.jobtestapp";
-    private static final long DEFAULT_WAIT_DURATION = 30_000;
 
     static final int FINISH_ACTIVITY_MSG = 1;
     public static final String ACTION_FINISH_ACTIVITY = PACKAGE_NAME + ".action.FINISH_ACTIVITY";
@@ -61,8 +60,6 @@
     public void onCreate(Bundle savedInstance) {
         Log.d(TAG, "Started test activity: " + TestActivity.class.getCanonicalName());
         super.onCreate(savedInstance);
-        // automatically finish after 30 seconds.
-        mFinishHandler.sendEmptyMessageDelayed(FINISH_ACTIVITY_MSG, DEFAULT_WAIT_DURATION);
         registerReceiver(mFinishReceiver, new IntentFilter(ACTION_FINISH_ACTIVITY));
     }
 }
diff --git a/tests/JobScheduler/JobTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobSchedulerReceiver.java b/tests/JobScheduler/JobTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobSchedulerReceiver.java
index a132eb0..49fbcc8 100644
--- a/tests/JobScheduler/JobTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobSchedulerReceiver.java
+++ b/tests/JobScheduler/JobTestApp/src/android/jobscheduler/cts/jobtestapp/TestJobSchedulerReceiver.java
@@ -33,10 +33,14 @@
     private static final String TAG = TestJobSchedulerReceiver.class.getSimpleName();
     private static final String PACKAGE_NAME = "android.jobscheduler.cts.jobtestapp";
 
+    public static final String ACTION_JOB_SCHEDULE_RESULT =
+            PACKAGE_NAME + ".action.SCHEDULE_RESULT";
+    public static final String EXTRA_SCHEDULE_RESULT = PACKAGE_NAME + ".extra.SCHEDULE_RESULT";
+
     public static final String EXTRA_JOB_ID_KEY = PACKAGE_NAME + ".extra.JOB_ID";
     public static final String EXTRA_ALLOW_IN_IDLE = PACKAGE_NAME + ".extra.ALLOW_IN_IDLE";
-    public static final String EXTRA_REQUIRE_NETWORK_ANY = PACKAGE_NAME
-            + ".extra.REQUIRE_NETWORK_ANY";
+    public static final String EXTRA_REQUIRED_NETWORK_TYPE =
+            PACKAGE_NAME + ".extra.REQUIRED_NETWORK_TYPE";
     public static final String EXTRA_AS_EXPEDITED = PACKAGE_NAME + ".extra.AS_EXPEDITED";
     public static final String EXTRA_REQUEST_JOB_UID_STATE =
             PACKAGE_NAME + ".extra.REQUEST_JOB_UID_STATE";
@@ -56,7 +60,8 @@
             case ACTION_SCHEDULE_JOB:
                 final int jobId = intent.getIntExtra(EXTRA_JOB_ID_KEY, hashCode());
                 final boolean allowInIdle = intent.getBooleanExtra(EXTRA_ALLOW_IN_IDLE, false);
-                final boolean network = intent.getBooleanExtra(EXTRA_REQUIRE_NETWORK_ANY, false);
+                final int networkType =
+                        intent.getIntExtra(EXTRA_REQUIRED_NETWORK_TYPE, JobInfo.NETWORK_TYPE_NONE);
                 final boolean expedited = intent.getBooleanExtra(EXTRA_AS_EXPEDITED, false);
                 final boolean requestJobUidState = intent.getBooleanExtra(
                         EXTRA_REQUEST_JOB_UID_STATE, false);
@@ -65,21 +70,19 @@
                 JobInfo.Builder jobBuilder = new JobInfo.Builder(jobId, jobServiceComponent)
                         .setBackoffCriteria(JOB_INITIAL_BACKOFF, JobInfo.BACKOFF_POLICY_LINEAR)
                         .setTransientExtras(extras)
-                        .setImportantWhileForeground(allowInIdle);
-                if (expedited) {
-                    jobBuilder.setExpedited(expedited);
-                } else {
-                    jobBuilder.setOverrideDeadline(0);
-                }
-                if (network) {
-                    jobBuilder = jobBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
-                }
+                        .setImportantWhileForeground(allowInIdle)
+                        .setExpedited(expedited)
+                        .setRequiredNetworkType(networkType);
                 final int result = jobScheduler.schedule(jobBuilder.build());
                 if (result != JobScheduler.RESULT_SUCCESS) {
                     Log.e(TAG, "Could not schedule job " + jobId);
                 } else {
                     Log.d(TAG, "Successfully scheduled job with id " + jobId);
                 }
+
+                final Intent scheduleJobResultIntent = new Intent(ACTION_JOB_SCHEDULE_RESULT);
+                scheduleJobResultIntent.putExtra(EXTRA_SCHEDULE_RESULT, result);
+                context.sendBroadcast(scheduleJobResultIntent);
                 break;
             default:
                 Log.e(TAG, "Unknown action " + intent.getAction());
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/BaseJobSchedulerTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/BaseJobSchedulerTest.java
index 2ee1edd..a92f8ac 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/BaseJobSchedulerTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/BaseJobSchedulerTest.java
@@ -35,6 +35,7 @@
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
+import com.android.compatibility.common.util.BatteryUtils;
 import com.android.compatibility.common.util.DeviceConfigStateHelper;
 import com.android.compatibility.common.util.SystemUtil;
 
@@ -207,6 +208,15 @@
         assertTrue("Job unexpectedly ready, in state: " + state, !state.contains("ready"));
     }
 
+    /**
+     * Set the screen state.
+     */
+    static void toggleScreenOn(final boolean screenon) throws Exception {
+        BatteryUtils.turnOnScreen(screenon);
+        // Wait a little bit for the broadcasts to be processed.
+        Thread.sleep(2_000);
+    }
+
     /** Asks (not forces) JobScheduler to run the job if constraints are met. */
     void runSatisfiedJob(int jobId) throws Exception {
         SystemUtil.runShellCommand(getInstrumentation(),
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
index c48b079..8bbcf58 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
@@ -366,10 +366,11 @@
 
         mTestAppInterface = new TestAppInterface(mContext, CONNECTIVITY_JOB_ID);
         mTestAppInterface.startAndKeepTestActivity();
+        toggleScreenOn(true);
 
-        mTestAppInterface.scheduleJob(false, true, false);
+        mTestAppInterface.scheduleJob(false,  JobInfo.NETWORK_TYPE_ANY, false);
 
-        runSatisfiedJob(CONNECTIVITY_JOB_ID);
+        mTestAppInterface.runSatisfiedJob();
         assertTrue("Job with metered connectivity constraint did not fire on a metered network.",
                 mTestAppInterface.awaitJobStart(30_000));
 
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ExpeditedJobTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ExpeditedJobTest.java
index 2bdba49..9f2db10 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ExpeditedJobTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ExpeditedJobTest.java
@@ -39,6 +39,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Collections;
 import java.util.Map;
 
 @RunWith(AndroidJUnit4.class)
@@ -73,7 +74,7 @@
         mTestAppInterface.scheduleJob(Map.of(
                 TestJobSchedulerReceiver.EXTRA_AS_EXPEDITED, true,
                 TestJobSchedulerReceiver.EXTRA_REQUEST_JOB_UID_STATE, true
-        ));
+        ), Collections.emptyMap());
         forceRunJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT_MS));
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/IdleConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/IdleConstraintTest.java
index ea540b4..3abdf03 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/IdleConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/IdleConstraintTest.java
@@ -21,17 +21,12 @@
 import android.annotation.TargetApi;
 import android.app.UiModeManager;
 import android.app.job.JobInfo;
-import android.content.Context;
 import android.content.pm.PackageManager;
-import android.content.res.Configuration;
-import android.os.PowerManager;
 import android.os.UserHandle;
 import android.support.test.uiautomator.UiDevice;
-import android.util.Log;
 
 import androidx.test.InstrumentationRegistry;
 
-import com.android.compatibility.common.util.BatteryUtils;
 import com.android.compatibility.common.util.SystemUtil;
 
 /**
@@ -42,7 +37,6 @@
     private static final int STATE_JOB_ID = IdleConstraintTest.class.hashCode();
     private static final String TAG = "IdleConstraintTest";
 
-    private PowerManager mPowerManager;
     private JobInfo.Builder mBuilder;
     private UiDevice mUiDevice;
 
@@ -53,7 +47,6 @@
         super.setUp();
         mBuilder = new JobInfo.Builder(STATE_JOB_ID, kJobServiceComponent);
         mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
 
         // Make sure the screen doesn't turn off when the test turns it on.
         mInitialDisplayTimeout = mUiDevice.executeShellCommand(
@@ -97,15 +90,6 @@
     }
 
     /**
-     * Set the screen state.
-     */
-    private void toggleScreenOn(final boolean screenon) throws Exception {
-        BatteryUtils.turnOnScreen(screenon);
-        // Wait a little bit for the broadcasts to be processed.
-        Thread.sleep(2_000);
-    }
-
-    /**
      * Simulated for idle, and then perform idle maintenance now.
      */
     private void triggerIdleMaintenance() throws Exception {
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
index d71d506..44e5887 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/JobThrottlingTest.java
@@ -16,6 +16,8 @@
 
 package android.jobscheduler.cts;
 
+import static android.app.job.JobInfo.NETWORK_TYPE_ANY;
+import static android.app.job.JobInfo.NETWORK_TYPE_NONE;
 import static android.jobscheduler.cts.ConnectivityConstraintTest.ensureSavedWifiNetwork;
 import static android.jobscheduler.cts.ConnectivityConstraintTest.isWiFiConnected;
 import static android.jobscheduler.cts.ConnectivityConstraintTest.setWifiState;
@@ -32,6 +34,7 @@
 import static org.junit.Assume.assumeTrue;
 
 import android.app.AppOpsManager;
+import android.app.job.JobInfo;
 import android.app.job.JobParameters;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -296,7 +299,7 @@
 
     @Test
     public void testEJStoppedWhenRestricted() throws Exception {
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -310,7 +313,7 @@
     @Test
     public void testRestrictedEJStartedWhenUnrestricted() throws Exception {
         setTestPackageRestricted(true);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         assertFalse("Job started for restricted app",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
         setTestPackageRestricted(false);
@@ -321,7 +324,7 @@
     @Test
     public void testRestrictedEJAllowedWhenUidActive() throws Exception {
         setTestPackageRestricted(true);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         assertFalse("Job started for restricted app",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
         // Turn the screen on to ensure the app gets into the TOP state.
@@ -351,7 +354,7 @@
         setAirplaneMode(false);
         setWifiState(true, mCm, mWifiManager);
         assumeTrue("device idle not enabled", mDeviceIdleEnabled);
-        mTestAppInterface.scheduleJob(false, true, false);
+        mTestAppInterface.scheduleJob(false, NETWORK_TYPE_ANY, false);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -409,7 +412,7 @@
         BatteryUtils.runDumpsysBatteryUnplug();
         setTestPackageStandbyBucket(Bucket.RESTRICTED);
         Thread.sleep(DEFAULT_WAIT_TIMEOUT);
-        sendScheduleJobBroadcast(false);
+        mTestAppInterface.scheduleJob(false, NETWORK_TYPE_NONE, false);
         assertFalse("New job started in RESTRICTED bucket", mTestAppInterface.awaitJobStart(3_000));
 
         // Slowly add back required bucket constraints.
@@ -450,7 +453,7 @@
         BatteryUtils.runDumpsysBatteryUnplug();
         setTestPackageStandbyBucket(Bucket.RESTRICTED);
         Thread.sleep(DEFAULT_WAIT_TIMEOUT);
-        mTestAppInterface.scheduleJob(false, true, false);
+        mTestAppInterface.scheduleJob(false, NETWORK_TYPE_ANY, false);
         runJob();
         assertFalse("New job started in RESTRICTED bucket", mTestAppInterface.awaitJobStart(3_000));
 
@@ -579,7 +582,7 @@
 
         BatteryUtils.runDumpsysBatteryUnplug();
         BatteryUtils.enableBatterySaver(true);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         assertTrue("New expedited job failed to start with battery saver ON",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
     }
@@ -593,7 +596,7 @@
 
         BatteryUtils.runDumpsysBatteryUnplug();
         BatteryUtils.enableBatterySaver(false);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         assertTrue("New expedited job failed to start with battery saver ON",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
         BatteryUtils.enableBatterySaver(true);
@@ -606,7 +609,7 @@
         assumeTrue("device idle not enabled", mDeviceIdleEnabled);
 
         toggleDozeState(true);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -617,7 +620,7 @@
         assumeTrue("device idle not enabled", mDeviceIdleEnabled);
 
         toggleDozeState(false);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -632,7 +635,7 @@
         mDeviceConfigStateHelper.set("runtime_min_ej_guarantee_ms", Long.toString(60_000L));
 
         toggleDozeState(true);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -661,7 +664,7 @@
 
         BatteryUtils.runDumpsysBatteryUnplug();
         BatteryUtils.enableBatterySaver(true);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -690,7 +693,7 @@
 
         BatteryUtils.runDumpsysBatteryUnplug();
         toggleDozeState(true);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -720,7 +723,7 @@
         mDeviceConfigStateHelper.set("runtime_min_ej_guarantee_ms", Long.toString(60_000L));
 
         toggleDozeState(false);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -743,7 +746,7 @@
 
         BatteryUtils.runDumpsysBatteryUnplug();
         BatteryUtils.enableBatterySaver(false);
-        mTestAppInterface.scheduleJob(false, false, true);
+        mTestAppInterface.scheduleJob(false, JobInfo.NETWORK_TYPE_NONE, true);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -785,7 +788,7 @@
         // Toggle individual constraints
 
         // Connectivity
-        mTestAppInterface.scheduleJob(false, true, false);
+        mTestAppInterface.scheduleJob(false, NETWORK_TYPE_ANY, false);
         runJob();
         assertTrue("New job didn't start in RESTRICTED bucket",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -798,7 +801,7 @@
         setWifiState(true, mCm, mWifiManager);
 
         // Idle
-        mTestAppInterface.scheduleJob(false, true, false);
+        mTestAppInterface.scheduleJob(false, NETWORK_TYPE_ANY, false);
         runJob();
         assertTrue("New job didn't start in RESTRICTED bucket",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -811,7 +814,7 @@
         triggerJobIdle();
 
         // Charging
-        mTestAppInterface.scheduleJob(false, true, false);
+        mTestAppInterface.scheduleJob(false, NETWORK_TYPE_ANY, false);
         runJob();
         assertTrue("New job didn't start in RESTRICTED bucket",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -826,7 +829,7 @@
         // Battery not low
         setScreenState(false);
         triggerJobIdle();
-        mTestAppInterface.scheduleJob(false, true, false);
+        mTestAppInterface.scheduleJob(false, NETWORK_TYPE_ANY, false);
         runJob();
         assertTrue("New job didn't start in RESTRICTED bucket",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -880,7 +883,7 @@
         assumeTrue("device idle not enabled", mDeviceIdleEnabled);
 
         toggleDozeState(false);
-        sendScheduleJobBroadcast(false);
+        mTestAppInterface.scheduleJob(false, NETWORK_TYPE_NONE, false);
         runJob();
         assertTrue("Job did not start after scheduling",
                 mTestAppInterface.awaitJobStart(DEFAULT_WAIT_TIMEOUT));
@@ -949,7 +952,7 @@
     }
 
     private void sendScheduleJobBroadcast(boolean allowWhileIdle) throws Exception {
-        mTestAppInterface.scheduleJob(allowWhileIdle, false, false);
+        mTestAppInterface.scheduleJob(allowWhileIdle, NETWORK_TYPE_ANY, false);
     }
 
     private void toggleDozeState(final boolean idle) throws Exception {
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/TestAppInterface.java b/tests/JobScheduler/src/android/jobscheduler/cts/TestAppInterface.java
index 8f11408..8db459e 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/TestAppInterface.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/TestAppInterface.java
@@ -39,9 +39,13 @@
 import android.jobscheduler.cts.jobtestapp.TestActivity;
 import android.jobscheduler.cts.jobtestapp.TestJobSchedulerReceiver;
 import android.os.SystemClock;
+import android.os.UserHandle;
 import android.server.wm.WindowManagerStateHelper;
 import android.util.Log;
 
+import com.android.compatibility.common.util.CallbackAsserter;
+import com.android.compatibility.common.util.SystemUtil;
+
 import java.util.Map;
 
 /**
@@ -80,21 +84,38 @@
         mTestJobState.reset();
     }
 
-    void scheduleJob(boolean allowWhileIdle, boolean needNetwork, boolean asExpeditedJob) {
-        scheduleJob(Map.of(
-                TestJobSchedulerReceiver.EXTRA_ALLOW_IN_IDLE, allowWhileIdle,
-                TestJobSchedulerReceiver.EXTRA_REQUIRE_NETWORK_ANY, needNetwork,
-                TestJobSchedulerReceiver.EXTRA_AS_EXPEDITED, asExpeditedJob
-        ));
+    void scheduleJob(boolean allowWhileIdle, int requiredNetworkType, boolean asExpeditedJob)
+            throws Exception {
+        scheduleJob(
+                Map.of(
+                        TestJobSchedulerReceiver.EXTRA_ALLOW_IN_IDLE, allowWhileIdle,
+                        TestJobSchedulerReceiver.EXTRA_AS_EXPEDITED, asExpeditedJob
+                ),
+                Map.of(
+                        TestJobSchedulerReceiver.EXTRA_REQUIRED_NETWORK_TYPE, requiredNetworkType
+                ));
     }
 
-    void scheduleJob(Map<String, Boolean> booleanExtras) {
+    void scheduleJob(Map<String, Boolean> booleanExtras, Map<String, Integer> intExtras)
+            throws Exception {
         final Intent scheduleJobIntent = new Intent(TestJobSchedulerReceiver.ACTION_SCHEDULE_JOB);
         scheduleJobIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         scheduleJobIntent.putExtra(TestJobSchedulerReceiver.EXTRA_JOB_ID_KEY, mJobId);
-        booleanExtras.forEach((key, value) -> scheduleJobIntent.putExtra(key, value));
+        booleanExtras.forEach(scheduleJobIntent::putExtra);
+        intExtras.forEach(scheduleJobIntent::putExtra);
         scheduleJobIntent.setComponent(new ComponentName(TEST_APP_PACKAGE, TEST_APP_RECEIVER));
+
+        final CallbackAsserter resultBroadcastAsserter = CallbackAsserter.forBroadcast(
+                new IntentFilter(TestJobSchedulerReceiver.ACTION_JOB_SCHEDULE_RESULT));
         mContext.sendBroadcast(scheduleJobIntent);
+        resultBroadcastAsserter.assertCalled("Didn't get schedule job result broadcast",
+                15 /* 15 seconds */);
+    }
+
+    /** Asks (not forces) JobScheduler to run the job if constraints are met. */
+    void runSatisfiedJob() throws Exception {
+        SystemUtil.runShellCommand("cmd jobscheduler run -s"
+                + " -u " + UserHandle.myUserId() + " " + TEST_APP_PACKAGE + " " + mJobId);
     }
 
     void startAndKeepTestActivity() {