Fix metered-constraint job scheduler CTS test

The test was incurring false positives in the case of the job running
even when the metered-network constraint didn't hold.  We now have a
test that verifies the negative: that the job fails to run, as expected,
when the device is connected via an unmetered network.

Along the way, we made setup/teardown of the wifi state more robust;
there was some flakiness arising from the previous handling.

Fix 62545908
Test: bit CtsJobSchedulerTestCases:.ConnectivityConstraintTest

Change-Id: I40269728aea5c7fef314d36a4b163dfa7d9eafa3
diff --git a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
index 0ca3ecc..94aee20 100644
--- a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
+++ b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
@@ -360,7 +360,11 @@
          * @return True if the latch timed out waiting on an execution.
          */
         public boolean awaitTimeout() throws InterruptedException {
-            return !mLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+            return awaitTimeout(DEFAULT_TIMEOUT_MILLIS);
+        }
+
+        public boolean awaitTimeout(long timeoutMillis) throws InterruptedException {
+            return !mLatch.await(timeoutMillis, TimeUnit.MILLISECONDS);
         }
 
         public boolean awaitWaitingForStop() throws InterruptedException {
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
index 0a3ff9c..c08b249 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
@@ -75,22 +75,25 @@
 
     @Override
     public void tearDown() throws Exception {
+        mJobScheduler.cancel(CONNECTIVITY_JOB_ID);
+
         // Ensure that we leave WiFi in its previous state.
         if (mWifiManager.isWifiEnabled() == mInitialWiFiState) {
             return;
         }
         NetworkInfo.State expectedState = mInitialWiFiState ?
-            NetworkInfo.State.CONNECTED : NetworkInfo.State.DISCONNECTED;
+                NetworkInfo.State.CONNECTED : NetworkInfo.State.DISCONNECTED;
         ConnectivityActionReceiver receiver =
-            new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI,
-                                           expectedState);
+                new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI,
+                        expectedState);
         IntentFilter filter = new IntentFilter();
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         mContext.registerReceiver(receiver, filter);
 
         assertTrue(mWifiManager.setWifiEnabled(mInitialWiFiState));
-        assertTrue("Failure to restore previous WiFi state.",
-                    receiver.waitForStateChange());
+        receiver.waitForStateChange();
+        assertTrue("Failure to restore previous WiFi state",
+                mWifiManager.isWifiEnabled() == mInitialWiFiState);
 
         mContext.unregisterReceiver(receiver);
     }
@@ -143,8 +146,8 @@
     }
 
     /**
-     * Schedule a job with a connectivity constraint, and ensure that it executes on on a mobile
-     * data connection.
+     * Schedule a job with a generic connectivity constraint, and ensure that it executes
+     * on a cellular data connection.
      */
     public void testConnectivityConstraintExecutes_withMobile() throws Exception {
         if (!checkDeviceSupportsMobileData()) {
@@ -165,7 +168,7 @@
 
     /**
      * Schedule a job with a metered connectivity constraint, and ensure that it executes
-     * on on a mobile data connection.
+     * on a mobile data connection.
      */
     public void testConnectivityConstraintExecutes_metered() throws Exception {
         if (!checkDeviceSupportsMobileData()) {
@@ -179,7 +182,6 @@
                         .build());
 
         sendExpediteStableChargingBroadcast();
-
         assertTrue("Job with metered connectivity constraint did not fire on mobile.",
                 kTestEnvironment.awaitExecution());
     }
@@ -211,6 +213,37 @@
     }
 
     /**
+     * Schedule a job that requires a metered connection, and verify that it does not run when
+     * the device is connected to a WiFi provider.
+     * This test assumes that if the device supports a mobile data connection, then this connection
+     * will be available.
+     */
+    public void testMeteredConstraintFails_withWiFi() throws Exception {
+        if (!mHasWifi) {
+            Log.d(TAG, "Skipping test that requires the device be WiFi enabled.");
+            return;
+        }
+        if (!checkDeviceSupportsMobileData()) {
+            Log.d(TAG, "Skipping test that requires the device be mobile data enabled.");
+            return;
+        }
+        connectToWiFi();
+
+        kTestEnvironment.setExpectedExecutions(0);
+        mJobScheduler.schedule(
+                mBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_METERED)
+                        .build());
+        sendExpediteStableChargingBroadcast();
+
+        assertTrue("Job requiring metered connectivity still executed on WiFi.",
+                kTestEnvironment.awaitTimeout());
+    }
+
+    // --------------------------------------------------------------------------------------------
+    // Utility methods
+    // --------------------------------------------------------------------------------------------
+
+    /**
      * Determine whether the device running these CTS tests should be subject to tests involving
      * mobile data.
      * @return True if this device will support a mobile data connection.