Stop ConnectivityController from processing non-network jobs.
Jobs that don't require network won't have a NetworkRequest object, so
trying to process them fully in ConnectivityController will lead to
NPEs.
Bug: 148218476
Test: atest com.android.server.job.controllers.ConnectivityControllerTest#testRestrictedJobTracking
Change-Id: Ibcb4162c19fc97d09f860bb1732e465de5c8374e
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index a0e83da..bb94275 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -144,14 +144,18 @@
public void startTrackingRestrictedJobLocked(JobStatus jobStatus) {
// Don't need to start tracking the job. If the job needed network, it would already be
// tracked.
- updateConstraintsSatisfied(jobStatus);
+ if (jobStatus.hasConnectivityConstraint()) {
+ updateConstraintsSatisfied(jobStatus);
+ }
}
@Override
public void stopTrackingRestrictedJobLocked(JobStatus jobStatus) {
// Shouldn't stop tracking the job here. If the job was tracked, it still needs network,
// even after being unrestricted.
- updateConstraintsSatisfied(jobStatus);
+ if (jobStatus.hasConnectivityConstraint()) {
+ updateConstraintsSatisfied(jobStatus);
+ }
}
/**
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 1c88c40..e724e60 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -20,6 +20,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
@@ -27,6 +28,9 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static com.android.server.job.JobSchedulerService.FREQUENT_INDEX;
+import static com.android.server.job.JobSchedulerService.RARE_INDEX;
+import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -568,6 +572,48 @@
assertFalse(controller.isStandbyExceptionRequestedLocked(UID_RED));
}
+ @Test
+ public void testRestrictedJobTracking() {
+ final JobStatus networked = createJobStatus(createJob()
+ .setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1), 0)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_CELLULAR), UID_RED);
+ final JobStatus unnetworked = createJobStatus(createJob(), UID_BLUE);
+ networked.setStandbyBucket(FREQUENT_INDEX);
+ unnetworked.setStandbyBucket(FREQUENT_INDEX);
+
+ final Network cellularNet = new Network(101);
+ final NetworkCapabilities cellularCaps =
+ createCapabilities().addTransportType(TRANSPORT_CELLULAR);
+ reset(mConnManager);
+ answerNetwork(UID_RED, cellularNet, cellularCaps);
+ answerNetwork(UID_BLUE, cellularNet, cellularCaps);
+
+ final ConnectivityController controller = new ConnectivityController(mService);
+ controller.maybeStartTrackingJobLocked(networked, null);
+ controller.maybeStartTrackingJobLocked(unnetworked, null);
+
+ assertTrue(networked.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
+ assertFalse(unnetworked.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
+
+ networked.setStandbyBucket(RESTRICTED_INDEX);
+ unnetworked.setStandbyBucket(RESTRICTED_INDEX);
+ controller.startTrackingRestrictedJobLocked(networked);
+ controller.startTrackingRestrictedJobLocked(unnetworked);
+ assertFalse(networked.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
+ // Unnetworked shouldn't be affected by ConnectivityController since it doesn't have a
+ // connectivity constraint.
+ assertFalse(unnetworked.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
+
+ networked.setStandbyBucket(RARE_INDEX);
+ unnetworked.setStandbyBucket(RARE_INDEX);
+ controller.stopTrackingRestrictedJobLocked(networked);
+ controller.stopTrackingRestrictedJobLocked(unnetworked);
+ assertTrue(networked.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
+ // Unnetworked shouldn't be affected by ConnectivityController since it doesn't have a
+ // connectivity constraint.
+ assertFalse(unnetworked.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
+ }
+
private void answerNetwork(int uid, Network net, NetworkCapabilities caps) {
when(mConnManager.getActiveNetworkForUid(eq(uid))).thenReturn(net);
when(mConnManager.getNetworkCapabilities(eq(net))).thenReturn(caps);