diff options
6 files changed, 214 insertions, 39 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java index 900c90203f41..903248f5f0b4 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java +++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java @@ -159,6 +159,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Predicate; @@ -301,6 +302,8 @@ public class JobSchedulerService extends com.android.server.SystemService private final ConnectivityController mConnectivityController; /** Need directly for sending uid state changes */ private final DeviceIdleJobsController mDeviceIdleJobsController; + /** Need directly for sending exempted bucket changes */ + private final FlexibilityController mFlexibilityController; /** Needed to get next estimated launch time. */ private final PrefetchController mPrefetchController; /** Needed to get remaining quota time. */ @@ -513,6 +516,10 @@ public class JobSchedulerService extends com.android.server.SystemService if (name == null) { continue; } + if (DEBUG) { + Slog.d(TAG, "DeviceConfig " + name + + " changed to " + properties.getString(name, null)); + } switch (name) { case Constants.KEY_ENABLE_API_QUOTAS: case Constants.KEY_ENABLE_EXECUTION_SAFEGUARDS_UDC: @@ -2532,17 +2539,17 @@ public class JobSchedulerService extends com.android.server.SystemService mControllers = new ArrayList<StateController>(); mPrefetchController = new PrefetchController(this); mControllers.add(mPrefetchController); - final FlexibilityController flexibilityController = + mFlexibilityController = new FlexibilityController(this, mPrefetchController); - mControllers.add(flexibilityController); + mControllers.add(mFlexibilityController); mConnectivityController = - new ConnectivityController(this, flexibilityController); + new ConnectivityController(this, mFlexibilityController); mControllers.add(mConnectivityController); mControllers.add(new TimeController(this)); - final IdleController idleController = new IdleController(this, flexibilityController); + final IdleController idleController = new IdleController(this, mFlexibilityController); mControllers.add(idleController); final BatteryController batteryController = - new BatteryController(this, flexibilityController); + new BatteryController(this, mFlexibilityController); mControllers.add(batteryController); mStorageController = new StorageController(this); mControllers.add(mStorageController); @@ -3191,6 +3198,13 @@ public class JobSchedulerService extends com.android.server.SystemService } @Override + public void onExemptedBucketChanged(@NonNull ArraySet<JobStatus> changedJobs) { + if (changedJobs.size() > 0) { + mFlexibilityController.onExemptedBucketChanged(changedJobs); + } + } + + @Override public void onRestrictionStateChanged(@NonNull JobRestriction restriction, boolean stopOvertimeJobs) { mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget(); @@ -3497,7 +3511,10 @@ public class JobSchedulerService extends com.android.server.SystemService } final boolean shouldForceBatchJob; - if (job.shouldTreatAsExpeditedJob() || job.shouldTreatAsUserInitiatedJob()) { + if (job.overrideState > JobStatus.OVERRIDE_NONE) { + // The job should run for some test. Don't force batch it. + shouldForceBatchJob = false; + } else if (job.shouldTreatAsExpeditedJob() || job.shouldTreatAsUserInitiatedJob()) { // Never batch expedited or user-initiated jobs, even for RESTRICTED apps. shouldForceBatchJob = false; } else if (job.getEffectiveStandbyBucket() == RESTRICTED_INDEX) { @@ -4950,6 +4967,8 @@ public class JobSchedulerService extends com.android.server.SystemService Slog.d(TAG, "executeRunCommand(): " + pkgName + "/" + namespace + "/" + userId + " " + jobId + " s=" + satisfied + " f=" + force); + final CountDownLatch delayLatch = new CountDownLatch(1); + final JobStatus js; try { final int uid = AppGlobals.getPackageManager().getPackageUid(pkgName, 0, userId != UserHandle.USER_ALL ? userId : UserHandle.USER_SYSTEM); @@ -4958,7 +4977,7 @@ public class JobSchedulerService extends com.android.server.SystemService } synchronized (mLock) { - final JobStatus js = mJobs.getJobByUidAndJobId(uid, namespace, jobId); + js = mJobs.getJobByUidAndJobId(uid, namespace, jobId); if (js == null) { return JobSchedulerShellCommand.CMD_ERR_NO_JOB; } @@ -4969,23 +4988,71 @@ public class JobSchedulerService extends com.android.server.SystemService // Re-evaluate constraints after the override is set in case one of the overridden // constraints was preventing another constraint from thinking it needed to update. for (int c = mControllers.size() - 1; c >= 0; --c) { - mControllers.get(c).reevaluateStateLocked(uid); + mControllers.get(c).evaluateStateLocked(js); } if (!js.isConstraintsSatisfied()) { - js.overrideState = JobStatus.OVERRIDE_NONE; - return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS; + if (js.hasConnectivityConstraint() + && !js.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY) + && js.wouldBeReadyWithConstraint(JobStatus.CONSTRAINT_CONNECTIVITY)) { + // Because of how asynchronous the connectivity signals are, JobScheduler + // may not get the connectivity satisfaction signal immediately. In this + // case, wait a few seconds to see if it comes in before saying the + // connectivity constraint isn't satisfied. + mHandler.postDelayed( + checkConstraintRunnableForTesting( + mHandler, js, delayLatch, 5, 1000), + 1000); + } else { + // There's no asynchronous signal to wait for. We can immediately say the + // job's constraints aren't satisfied and return. + js.overrideState = JobStatus.OVERRIDE_NONE; + return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS; + } + } else { + delayLatch.countDown(); } - - queueReadyJobsForExecutionLocked(); - maybeRunPendingJobsLocked(); } } catch (RemoteException e) { // can't happen + return 0; + } + + // Choose to block the return until we're sure about the state of the connectivity job + // so that tests can expect a reliable state after calling the run command. + try { + delayLatch.await(7L, TimeUnit.SECONDS); + } catch (InterruptedException e) { + Slog.e(TAG, "Couldn't wait for asynchronous constraint change", e); + } + + synchronized (mLock) { + if (!js.isConstraintsSatisfied()) { + js.overrideState = JobStatus.OVERRIDE_NONE; + return JobSchedulerShellCommand.CMD_ERR_CONSTRAINTS; + } + + queueReadyJobsForExecutionLocked(); + maybeRunPendingJobsLocked(); } return 0; } + private static Runnable checkConstraintRunnableForTesting(@NonNull final Handler handler, + @NonNull final JobStatus js, @NonNull final CountDownLatch latch, + final int remainingAttempts, final long delayMs) { + return () -> { + if (remainingAttempts <= 0 || js.isConstraintsSatisfied()) { + latch.countDown(); + return; + } + handler.postDelayed( + checkConstraintRunnableForTesting( + handler, js, latch, remainingAttempts - 1, delayMs), + delayMs); + }; + } + // Shell command infrastructure: immediately timeout currently executing jobs int executeStopCommand(PrintWriter pw, String pkgName, int userId, @Nullable String namespace, boolean hasJobId, int jobId, diff --git a/apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java b/apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java index 50064bde0bbe..411a24de4bcb 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java +++ b/apex/jobscheduler/service/java/com/android/server/job/StateChangedListener.java @@ -62,6 +62,12 @@ public interface StateChangedListener { /** * Called when these jobs are added or removed from the + * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_EXEMPTED} bucket. + */ + void onExemptedBucketChanged(@NonNull ArraySet<JobStatus> jobs); + + /** + * Called when these jobs are added or removed from the * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket. */ void onRestrictedBucketChanged(@NonNull List<JobStatus> jobs); diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java index 0e67b9ac944f..e4cb569d3d35 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java @@ -20,6 +20,7 @@ import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.HOUR_IN_MILLIS; import static android.text.format.DateUtils.MINUTE_IN_MILLIS; +import static com.android.server.job.JobSchedulerService.EXEMPTED_INDEX; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import static com.android.server.job.controllers.JobStatus.CONSTRAINT_BATTERY_NOT_LOW; import static com.android.server.job.controllers.JobStatus.CONSTRAINT_CHARGING; @@ -180,8 +181,12 @@ public final class FlexibilityController extends StateController { } }; - private static final int MSG_UPDATE_JOBS = 0; - private static final int MSG_UPDATE_JOB = 1; + private static final int MSG_CHECK_ALL_JOBS = 0; + /** Check the jobs in {@link #mJobsToCheck} */ + private static final int MSG_CHECK_JOBS = 1; + + @GuardedBy("mLock") + private final ArraySet<JobStatus> mJobsToCheck = new ArraySet<>(); public FlexibilityController( JobSchedulerService service, PrefetchController prefetchController) { @@ -266,7 +271,14 @@ public final class FlexibilityController extends StateController { @GuardedBy("mLock") boolean isFlexibilitySatisfiedLocked(JobStatus js) { return !mFlexibilityEnabled + // Exclude all jobs of the TOP app || mService.getUidBias(js.getSourceUid()) == JobInfo.BIAS_TOP_APP + // Only exclude DEFAULT+ priority jobs for BFGS+ apps + || (mService.getUidBias(js.getSourceUid()) >= JobInfo.BIAS_BOUND_FOREGROUND_SERVICE + && js.getEffectivePriority() >= JobInfo.PRIORITY_DEFAULT) + // Only exclude DEFAULT+ priority jobs for EXEMPTED apps + || (js.getStandbyBucket() == EXEMPTED_INDEX + && js.getEffectivePriority() >= JobInfo.PRIORITY_DEFAULT) || hasEnoughSatisfiedConstraintsLocked(js) || mService.isCurrentlyRunningLocked(js); } @@ -371,11 +383,19 @@ public final class FlexibilityController extends StateController { // Push the job update to the handler to avoid blocking other controllers and // potentially batch back-to-back controller state updates together. - mHandler.obtainMessage(MSG_UPDATE_JOBS).sendToTarget(); + mHandler.obtainMessage(MSG_CHECK_ALL_JOBS).sendToTarget(); } } } + /** Called with a set of apps who have been added to or removed from the exempted bucket. */ + public void onExemptedBucketChanged(@NonNull ArraySet<JobStatus> changedJobs) { + synchronized (mLock) { + mJobsToCheck.addAll(changedJobs); + mHandler.sendEmptyMessage(MSG_CHECK_JOBS); + } + } + /** Checks if the given constraint is satisfied in the flexibility controller. */ @VisibleForTesting boolean isConstraintSatisfied(int constraint) { @@ -485,7 +505,9 @@ public final class FlexibilityController extends StateController { @Override @GuardedBy("mLock") public void onUidBiasChangedLocked(int uid, int prevBias, int newBias) { - if (prevBias != JobInfo.BIAS_TOP_APP && newBias != JobInfo.BIAS_TOP_APP) { + if (prevBias < JobInfo.BIAS_BOUND_FOREGROUND_SERVICE + && newBias < JobInfo.BIAS_BOUND_FOREGROUND_SERVICE) { + // All changes are below BFGS. There's no significant change to care about. return; } final long nowElapsed = sElapsedRealtimeClock.millis(); @@ -710,7 +732,8 @@ public final class FlexibilityController extends StateController { } mFlexibilityTracker.setNumDroppedFlexibleConstraints(js, js.getNumAppliedFlexibleConstraints()); - mHandler.obtainMessage(MSG_UPDATE_JOB, js).sendToTarget(); + mJobsToCheck.add(js); + mHandler.sendEmptyMessage(MSG_CHECK_JOBS); return; } if (nextTimeElapsed == NO_LIFECYCLE_END) { @@ -761,10 +784,11 @@ public final class FlexibilityController extends StateController { @Override public void handleMessage(Message msg) { switch (msg.what) { - case MSG_UPDATE_JOBS: - removeMessages(MSG_UPDATE_JOBS); + case MSG_CHECK_ALL_JOBS: + removeMessages(MSG_CHECK_ALL_JOBS); synchronized (mLock) { + mJobsToCheck.clear(); final long nowElapsed = sElapsedRealtimeClock.millis(); final ArraySet<JobStatus> changedJobs = new ArraySet<>(); @@ -790,19 +814,25 @@ public final class FlexibilityController extends StateController { } break; - case MSG_UPDATE_JOB: + case MSG_CHECK_JOBS: synchronized (mLock) { - final JobStatus js = (JobStatus) msg.obj; - if (DEBUG) { - Slog.d("blah", "Checking on " + js.toShortString()); - } final long nowElapsed = sElapsedRealtimeClock.millis(); - if (js.setFlexibilityConstraintSatisfied( - nowElapsed, isFlexibilitySatisfiedLocked(js))) { - // TODO(141645789): add method that will take a single job - ArraySet<JobStatus> changedJob = new ArraySet<>(); - changedJob.add(js); - mStateChangedListener.onControllerStateChanged(changedJob); + ArraySet<JobStatus> changedJobs = new ArraySet<>(); + + for (int i = mJobsToCheck.size() - 1; i >= 0; --i) { + final JobStatus js = mJobsToCheck.valueAt(i); + if (DEBUG) { + Slog.d(TAG, "Checking on " + js.toShortString()); + } + if (js.setFlexibilityConstraintSatisfied( + nowElapsed, isFlexibilitySatisfiedLocked(js))) { + changedJobs.add(js); + } + } + + mJobsToCheck.clear(); + if (changedJobs.size() > 0) { + mStateChangedListener.onControllerStateChanged(changedJobs); } } break; @@ -985,7 +1015,10 @@ public final class FlexibilityController extends StateController { pw.println(":"); pw.increaseIndent(); - pw.print(KEY_APPLIED_CONSTRAINTS, APPLIED_CONSTRAINTS).println(); + pw.print(KEY_APPLIED_CONSTRAINTS, APPLIED_CONSTRAINTS); + pw.print("("); + JobStatus.dumpConstraints(pw, APPLIED_CONSTRAINTS); + pw.println(")"); pw.print(KEY_DEADLINE_PROXIMITY_LIMIT, DEADLINE_PROXIMITY_LIMIT_MS).println(); pw.print(KEY_FALLBACK_FLEXIBILITY_DEADLINE, FALLBACK_FLEXIBILITY_DEADLINE_MS).println(); pw.print(KEY_MIN_TIME_BETWEEN_FLEXIBILITY_ALARMS_MS, diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java index 0d5d11e98860..a095a16817d8 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java @@ -106,11 +106,8 @@ public final class JobStatus { public static final long NO_LATEST_RUNTIME = Long.MAX_VALUE; public static final long NO_EARLIEST_RUNTIME = 0L; - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public static final int CONSTRAINT_CHARGING = JobInfo.CONSTRAINT_FLAG_CHARGING; // 1 < 0 - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public static final int CONSTRAINT_IDLE = JobInfo.CONSTRAINT_FLAG_DEVICE_IDLE; // 1 << 2 - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public static final int CONSTRAINT_BATTERY_NOT_LOW = JobInfo.CONSTRAINT_FLAG_BATTERY_NOT_LOW; // 1 << 1 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) @@ -2194,7 +2191,7 @@ public final class JobStatus { * @return Whether or not this job would be ready to run if it had the specified constraint * granted, based on its requirements. */ - boolean wouldBeReadyWithConstraint(int constraint) { + public boolean wouldBeReadyWithConstraint(int constraint) { return readinessStatusWithConstraint(constraint, true); } diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java index 8ddbf691359f..04da7814244e 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java @@ -2511,6 +2511,7 @@ public final class QuotaController extends StateController { + " to bucketIndex " + bucketIndex); } List<JobStatus> restrictedChanges = new ArrayList<>(); + ArraySet<JobStatus> exemptedChanges = new ArraySet<>(); synchronized (mLock) { ShrinkableDebits debits = mEJStats.get(userId, packageName); if (debits != null) { @@ -2530,6 +2531,10 @@ public final class QuotaController extends StateController { && bucketIndex != js.getStandbyBucket()) { restrictedChanges.add(js); } + if ((bucketIndex == EXEMPTED_INDEX || js.getStandbyBucket() == EXEMPTED_INDEX) + && bucketIndex != js.getStandbyBucket()) { + exemptedChanges.add(js); + } js.setStandbyBucket(bucketIndex); } Timer timer = mPkgTimers.get(userId, packageName); @@ -2544,6 +2549,9 @@ public final class QuotaController extends StateController { maybeUpdateConstraintForPkgLocked( sElapsedRealtimeClock.millis(), userId, packageName)); } + if (exemptedChanges.size() > 0) { + mStateChangedListener.onExemptedBucketChanged(exemptedChanges); + } if (restrictedChanges.size() > 0) { mStateChangedListener.onRestrictedBucketChanged(restrictedChanges); } diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java index 650c473533ed..d24500d180f2 100644 --- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java @@ -28,6 +28,8 @@ import static android.text.format.DateUtils.MINUTE_IN_MILLIS; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; +import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX; +import static com.android.server.job.JobSchedulerService.EXEMPTED_INDEX; import static com.android.server.job.controllers.FlexibilityController.FcConfig.DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_MS; import static com.android.server.job.controllers.FlexibilityController.FcConfig.DEFAULT_UNSEEN_CONSTRAINT_GRACE_PERIOD_MS; import static com.android.server.job.controllers.FlexibilityController.FcConfig.KEY_APPLIED_CONSTRAINTS; @@ -212,6 +214,7 @@ public class FlexibilityControllerTest { JobStatus js = JobStatus.createFromJobInfo( jobInfo, 1000, SOURCE_PACKAGE, SOURCE_USER_ID, "FCTest", testTag); js.enqueueTime = FROZEN_TIME; + js.setStandbyBucket(ACTIVE_INDEX); if (js.hasFlexibilityConstraint()) { js.setNumAppliedFlexibleConstraints(Integer.bitCount( mFlexibilityController.getRelevantAppliedConstraintsLocked(js))); @@ -847,14 +850,75 @@ public class FlexibilityControllerTest { } @Test + public void testAllowlistedAppBypass() { + JobStatus jsHigh = createJobStatus("testAllowlistedAppBypass", + createJob(0).setPriority(JobInfo.PRIORITY_HIGH)); + JobStatus jsDefault = createJobStatus("testAllowlistedAppBypass", + createJob(0).setPriority(JobInfo.PRIORITY_DEFAULT)); + JobStatus jsLow = createJobStatus("testAllowlistedAppBypass", + createJob(0).setPriority(JobInfo.PRIORITY_LOW)); + JobStatus jsMin = createJobStatus("testAllowlistedAppBypass", + createJob(0).setPriority(JobInfo.PRIORITY_MIN)); + jsHigh.setStandbyBucket(EXEMPTED_INDEX); + jsDefault.setStandbyBucket(EXEMPTED_INDEX); + jsLow.setStandbyBucket(EXEMPTED_INDEX); + jsMin.setStandbyBucket(EXEMPTED_INDEX); + + synchronized (mFlexibilityController.mLock) { + assertTrue(mFlexibilityController.isFlexibilitySatisfiedLocked(jsHigh)); + assertTrue(mFlexibilityController.isFlexibilitySatisfiedLocked(jsDefault)); + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsLow)); + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsMin)); + } + } + + @Test + public void testForegroundAppBypass() { + JobStatus jsHigh = createJobStatus("testAllowlistedAppBypass", + createJob(0).setPriority(JobInfo.PRIORITY_HIGH)); + JobStatus jsDefault = createJobStatus("testAllowlistedAppBypass", + createJob(0).setPriority(JobInfo.PRIORITY_DEFAULT)); + JobStatus jsLow = createJobStatus("testAllowlistedAppBypass", + createJob(0).setPriority(JobInfo.PRIORITY_LOW)); + JobStatus jsMin = createJobStatus("testAllowlistedAppBypass", + createJob(0).setPriority(JobInfo.PRIORITY_MIN)); + + when(mJobSchedulerService.getUidBias(mSourceUid)).thenReturn(JobInfo.BIAS_DEFAULT); + synchronized (mFlexibilityController.mLock) { + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsHigh)); + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsDefault)); + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsLow)); + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsMin)); + } + + when(mJobSchedulerService.getUidBias(mSourceUid)) + .thenReturn(JobInfo.BIAS_BOUND_FOREGROUND_SERVICE); + synchronized (mFlexibilityController.mLock) { + assertTrue(mFlexibilityController.isFlexibilitySatisfiedLocked(jsHigh)); + assertTrue(mFlexibilityController.isFlexibilitySatisfiedLocked(jsDefault)); + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsLow)); + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsMin)); + } + + when(mJobSchedulerService.getUidBias(mSourceUid)) + .thenReturn(JobInfo.BIAS_FOREGROUND_SERVICE); + synchronized (mFlexibilityController.mLock) { + assertTrue(mFlexibilityController.isFlexibilitySatisfiedLocked(jsHigh)); + assertTrue(mFlexibilityController.isFlexibilitySatisfiedLocked(jsDefault)); + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsLow)); + assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(jsMin)); + } + } + + @Test public void testTopAppBypass() { - JobInfo.Builder jb = createJob(0); + JobInfo.Builder jb = createJob(0).setPriority(JobInfo.PRIORITY_MIN); JobStatus js = createJobStatus("testTopAppBypass", jb); mJobStore.add(js); // Needed because if before and after Uid bias is the same, nothing happens. when(mJobSchedulerService.getUidBias(mSourceUid)) - .thenReturn(JobInfo.BIAS_FOREGROUND_SERVICE); + .thenReturn(JobInfo.BIAS_DEFAULT); synchronized (mFlexibilityController.mLock) { mFlexibilityController.maybeStartTrackingJobLocked(js, null); @@ -865,7 +929,7 @@ public class FlexibilityControllerTest { assertTrue(mFlexibilityController.isFlexibilitySatisfiedLocked(js)); assertTrue(js.isConstraintSatisfied(CONSTRAINT_FLEXIBLE)); - setUidBias(mSourceUid, JobInfo.BIAS_FOREGROUND_SERVICE); + setUidBias(mSourceUid, JobInfo.BIAS_SYNC_INITIALIZATION); assertFalse(mFlexibilityController.isFlexibilitySatisfiedLocked(js)); assertFalse(js.isConstraintSatisfied(CONSTRAINT_FLEXIBLE)); |