Merge "Fix expedited job exemptions."

This commit is contained in:
Kweku Adams
2021-01-05 21:57:07 +00:00
committed by Android (Google) Code Review
5 changed files with 45 additions and 7 deletions

View File

@@ -1502,11 +1502,14 @@ public class JobSchedulerService extends com.android.server.SystemService
mControllers.add(mBatteryController);
mStorageController = new StorageController(this);
mControllers.add(mStorageController);
mControllers.add(new BackgroundJobsController(this));
final BackgroundJobsController backgroundJobsController =
new BackgroundJobsController(this);
mControllers.add(backgroundJobsController);
mControllers.add(new ContentObserverController(this));
mDeviceIdleJobsController = new DeviceIdleJobsController(this);
mControllers.add(mDeviceIdleJobsController);
mQuotaController = new QuotaController(this);
mQuotaController =
new QuotaController(this, backgroundJobsController, connectivityController);
mControllers.add(mQuotaController);
mControllers.add(new ComponentController(this));

View File

@@ -77,6 +77,11 @@ public final class BackgroundJobsController extends StateController {
boolean forUpdate) {
}
@Override
public void evaluateStateLocked(JobStatus jobStatus) {
updateSingleJobRestrictionLocked(jobStatus, UNKNOWN);
}
@Override
public void dumpControllerStateLocked(final IndentingPrintWriter pw,
final Predicate<JobStatus> predicate) {

View File

@@ -1151,6 +1151,11 @@ public final class JobStatus {
if (setConstraintSatisfied(CONSTRAINT_WITHIN_EXPEDITED_QUOTA, state)) {
// The constraint was changed. Update the ready flag.
mReadyWithinExpeditedQuota = state;
// DeviceIdleJobsController currently only tracks jobs with the WILL_BE_FOREGROUND flag.
// Making it also track requested-expedited jobs would add unnecessary hops since the
// controller would then defer to canRunInDoze. Avoid the hops and just update
// mReadyNotDozing directly.
mReadyNotDozing = isConstraintSatisfied(CONSTRAINT_DEVICE_NOT_DOZING) || canRunInDoze();
return true;
}
return false;

View File

@@ -347,6 +347,9 @@ public final class QuotaController extends StateController {
private final QcHandler mHandler;
private final QcConstants mQcConstants;
private final BackgroundJobsController mBackgroundJobsController;
private final ConnectivityController mConnectivityController;
/** How much time each app will have to run jobs within their standby bucket window. */
private long mAllowedTimePerPeriodMs = QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_MS;
@@ -552,7 +555,9 @@ public final class QuotaController extends StateController {
*/
private static final int MSG_PROCESS_USAGE_EVENT = 5;
public QuotaController(JobSchedulerService service) {
public QuotaController(@NonNull JobSchedulerService service,
@NonNull BackgroundJobsController backgroundJobsController,
@NonNull ConnectivityController connectivityController) {
super(service);
mHandler = new QcHandler(mContext.getMainLooper());
mChargeTracker = new ChargingTracker();
@@ -560,6 +565,8 @@ public final class QuotaController extends StateController {
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mQcConstants = new QcConstants();
mBackgroundJobsController = backgroundJobsController;
mConnectivityController = connectivityController;
final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
mContext.registerReceiverAsUser(mPackageAddedReceiver, UserHandle.ALL, filter, null, null);
@@ -596,7 +603,7 @@ public final class QuotaController extends StateController {
final boolean outOfEJQuota;
if (jobStatus.isRequestedExpeditedJob()) {
final boolean isWithinEJQuota = isWithinEJQuotaLocked(jobStatus);
jobStatus.setExpeditedJobQuotaConstraintSatisfied(isWithinEJQuota);
setExpeditedConstraintSatisfied(jobStatus, isWithinEJQuota);
outOfEJQuota = !isWithinEJQuota;
} else {
outOfEJQuota = false;
@@ -1473,7 +1480,7 @@ public final class QuotaController extends StateController {
if (js.isRequestedExpeditedJob()) {
boolean isWithinEJQuota = isWithinEJQuotaLocked(js);
changed |= js.setExpeditedJobQuotaConstraintSatisfied(isWithinEJQuota);
changed |= setExpeditedConstraintSatisfied(js, isWithinEJQuota);
outOfEJQuota |= !isWithinEJQuota;
}
}
@@ -1499,7 +1506,7 @@ public final class QuotaController extends StateController {
final boolean outOfEJQuota;
if (jobStatus.isRequestedExpeditedJob()) {
final boolean isWithinEJQuota = isWithinEJQuotaLocked(jobStatus);
wasJobChanged |= jobStatus.setExpeditedJobQuotaConstraintSatisfied(isWithinEJQuota);
wasJobChanged |= setExpeditedConstraintSatisfied(jobStatus, isWithinEJQuota);
outOfEJQuota = !isWithinEJQuota;
} else {
outOfEJQuota = false;
@@ -1650,6 +1657,23 @@ public final class QuotaController extends StateController {
return jobStatus.setQuotaConstraintSatisfied(isWithinQuota);
}
/**
* If the satisfaction changes, this will tell connectivity & background jobs controller to
* also re-evaluate their state.
*/
private boolean setExpeditedConstraintSatisfied(@NonNull JobStatus jobStatus,
boolean isWithinQuota) {
if (jobStatus.setExpeditedJobQuotaConstraintSatisfied(isWithinQuota)) {
mBackgroundJobsController.evaluateStateLocked(jobStatus);
mConnectivityController.evaluateStateLocked(jobStatus);
if (isWithinQuota && jobStatus.isReady()) {
mStateChangedListener.onRunJobNow(jobStatus);
}
return true;
}
return false;
}
private final class ChargingTracker extends BroadcastReceiver {
/**
* Track whether we're charging. This has a slightly different definition than that of

View File

@@ -209,7 +209,8 @@ public class QuotaControllerTest {
ArgumentCaptor.forClass(BroadcastReceiver.class);
ArgumentCaptor<IUidObserver> uidObserverCaptor =
ArgumentCaptor.forClass(IUidObserver.class);
mQuotaController = new QuotaController(mJobSchedulerService);
mQuotaController = new QuotaController(mJobSchedulerService,
mock(BackgroundJobsController.class), mock(ConnectivityController.class));
verify(mContext).registerReceiver(receiverCaptor.capture(), any());
mChargingReceiver = receiverCaptor.getValue();