Merge "Integrate JobScheduler with TARE."
This commit is contained in:
committed by
Android (Google) Code Review
commit
7e5c35b51a
@@ -40,6 +40,7 @@ import android.app.usage.UsageStatsManager;
|
||||
import android.app.usage.UsageStatsManagerInternal;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
@@ -50,6 +51,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.PackageManagerInternal;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.content.pm.ServiceInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.net.Uri;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.BatteryStatsInternal;
|
||||
@@ -66,6 +68,7 @@ import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.WorkSource;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Settings;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
@@ -106,6 +109,7 @@ import com.android.server.job.controllers.QuotaController;
|
||||
import com.android.server.job.controllers.RestrictingController;
|
||||
import com.android.server.job.controllers.StateController;
|
||||
import com.android.server.job.controllers.StorageController;
|
||||
import com.android.server.job.controllers.TareController;
|
||||
import com.android.server.job.controllers.TimeController;
|
||||
import com.android.server.job.restrictions.JobRestriction;
|
||||
import com.android.server.job.restrictions.ThermalStatusRestriction;
|
||||
@@ -250,6 +254,8 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
private final DeviceIdleJobsController mDeviceIdleJobsController;
|
||||
/** Needed to get remaining quota time. */
|
||||
private final QuotaController mQuotaController;
|
||||
/** Needed to get max execution time and expedited-job allowance. */
|
||||
private final TareController mTareController;
|
||||
/**
|
||||
* List of restrictions.
|
||||
* Note: do not add to or remove from this list at runtime except in the constructor, because we
|
||||
@@ -344,14 +350,40 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
// (ScheduledJobStateChanged and JobStatusDumpProto).
|
||||
public static final int RESTRICTED_INDEX = 5;
|
||||
|
||||
private class ConstantsObserver implements DeviceConfig.OnPropertiesChangedListener {
|
||||
private class ConstantsObserver extends ContentObserver
|
||||
implements DeviceConfig.OnPropertiesChangedListener {
|
||||
private final ContentResolver mContentResolver;
|
||||
|
||||
ConstantsObserver(Handler handler, Context context) {
|
||||
super(handler);
|
||||
mContentResolver = context.getContentResolver();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
|
||||
JobSchedulerBackgroundThread.getExecutor(), this);
|
||||
mContentResolver.registerContentObserver(
|
||||
Settings.Global.getUriFor(Settings.Global.ENABLE_TARE), false, this);
|
||||
// Load all the constants.
|
||||
synchronized (mLock) {
|
||||
mConstants.updateSettingsConstantsLocked(mContentResolver);
|
||||
}
|
||||
onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_JOB_SCHEDULER));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange) {
|
||||
synchronized (mLock) {
|
||||
if (mConstants.updateSettingsConstantsLocked(mContentResolver)) {
|
||||
for (int controller = 0; controller < mControllers.size(); controller++) {
|
||||
final StateController sc = mControllers.get(controller);
|
||||
sc.onConstantsUpdatedLocked();
|
||||
}
|
||||
onControllerStateChanged(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPropertiesChanged(DeviceConfig.Properties properties) {
|
||||
boolean apiQuotaScheduleUpdated = false;
|
||||
@@ -482,6 +514,7 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
public static final long DEFAULT_RUNTIME_MIN_GUARANTEE_MS = 10 * MINUTE_IN_MILLIS;
|
||||
@VisibleForTesting
|
||||
public static final long DEFAULT_RUNTIME_MIN_EJ_GUARANTEE_MS = 3 * MINUTE_IN_MILLIS;
|
||||
private static final boolean DEFAULT_USE_TARE_POLICY = false;
|
||||
|
||||
/**
|
||||
* Minimum # of non-ACTIVE jobs for which the JMS will be happy running some work early.
|
||||
@@ -559,6 +592,11 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
*/
|
||||
public long RUNTIME_MIN_EJ_GUARANTEE_MS = DEFAULT_RUNTIME_MIN_EJ_GUARANTEE_MS;
|
||||
|
||||
/**
|
||||
* If true, use TARE policy for job limiting. If false, use quotas.
|
||||
*/
|
||||
public boolean USE_TARE_POLICY = DEFAULT_USE_TARE_POLICY;
|
||||
|
||||
private void updateBatchingConstantsLocked() {
|
||||
MIN_READY_NON_ACTIVE_JOBS_COUNT = DeviceConfig.getInt(
|
||||
DeviceConfig.NAMESPACE_JOB_SCHEDULER,
|
||||
@@ -637,6 +675,17 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS));
|
||||
}
|
||||
|
||||
private boolean updateSettingsConstantsLocked(ContentResolver contentResolver) {
|
||||
boolean changed = false;
|
||||
final boolean isTareEnabled = Settings.Global.getInt(contentResolver,
|
||||
Settings.Global.ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE) == 1;
|
||||
if (USE_TARE_POLICY != isTareEnabled) {
|
||||
USE_TARE_POLICY = isTareEnabled;
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
void dump(IndentingPrintWriter pw) {
|
||||
pw.println("Settings:");
|
||||
pw.increaseIndent();
|
||||
@@ -665,6 +714,8 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
pw.print(KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
|
||||
.println();
|
||||
|
||||
pw.print(Settings.Global.ENABLE_TARE, USE_TARE_POLICY).println();
|
||||
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
|
||||
@@ -1130,9 +1181,12 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
JobStatus jobStatus = JobStatus.createFromJobInfo(job, uId, packageName, userId, tag);
|
||||
|
||||
// Return failure early if expedited job quota used up.
|
||||
if (jobStatus.isRequestedExpeditedJob()
|
||||
&& !mQuotaController.isWithinEJQuotaLocked(jobStatus)) {
|
||||
return JobScheduler.RESULT_FAILURE;
|
||||
if (jobStatus.isRequestedExpeditedJob()) {
|
||||
if ((mConstants.USE_TARE_POLICY && !mTareController.canScheduleEJ(jobStatus))
|
||||
|| (!mConstants.USE_TARE_POLICY
|
||||
&& !mQuotaController.isWithinEJQuotaLocked(jobStatus))) {
|
||||
return JobScheduler.RESULT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
// Give exemption if the source is in the foreground just now.
|
||||
@@ -1474,7 +1528,7 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
|
||||
mHandler = new JobHandler(context.getMainLooper());
|
||||
mConstants = new Constants();
|
||||
mConstantsObserver = new ConstantsObserver();
|
||||
mConstantsObserver = new ConstantsObserver(mHandler, context);
|
||||
mJobSchedulerStub = new JobSchedulerStub();
|
||||
|
||||
mConcurrencyManager = new JobConcurrencyManager(this);
|
||||
@@ -1519,6 +1573,9 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
new QuotaController(this, backgroundJobsController, connectivityController);
|
||||
mControllers.add(mQuotaController);
|
||||
mControllers.add(new ComponentController(this));
|
||||
mTareController =
|
||||
new TareController(this, backgroundJobsController, connectivityController);
|
||||
mControllers.add(mTareController);
|
||||
|
||||
mRestrictiveControllers = new ArrayList<>();
|
||||
mRestrictiveControllers.add(mBatteryController);
|
||||
@@ -2560,7 +2617,9 @@ public class JobSchedulerService extends com.android.server.SystemService
|
||||
public long getMaxJobExecutionTimeMs(JobStatus job) {
|
||||
synchronized (mLock) {
|
||||
return Math.min(mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
|
||||
mQuotaController.getMaxJobExecutionTimeMsLocked(job));
|
||||
mConstants.USE_TARE_POLICY
|
||||
? mTareController.getMaxJobExecutionTimeMsLocked(job)
|
||||
: mQuotaController.getMaxJobExecutionTimeMsLocked(job));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,9 @@ import com.android.internal.util.FrameworkStatsLog;
|
||||
import com.android.server.EventLogTags;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.job.controllers.JobStatus;
|
||||
import com.android.server.tare.EconomicPolicy;
|
||||
import com.android.server.tare.EconomyManagerInternal;
|
||||
import com.android.server.tare.JobSchedulerEconomicPolicy;
|
||||
|
||||
/**
|
||||
* Handles client binding and lifecycle of a job. Jobs execute one at a time on an instance of this
|
||||
@@ -107,6 +110,7 @@ public final class JobServiceContext implements ServiceConnection {
|
||||
private final Context mContext;
|
||||
private final Object mLock;
|
||||
private final IBatteryStats mBatteryStats;
|
||||
private final EconomyManagerInternal mEconomyManagerInternal;
|
||||
private final JobPackageTracker mJobPackageTracker;
|
||||
private final PowerManager mPowerManager;
|
||||
private PowerManager.WakeLock mWakeLock;
|
||||
@@ -211,6 +215,7 @@ public final class JobServiceContext implements ServiceConnection {
|
||||
mLock = service.getLock();
|
||||
mService = service;
|
||||
mBatteryStats = batteryStats;
|
||||
mEconomyManagerInternal = LocalServices.getService(EconomyManagerInternal.class);
|
||||
mJobPackageTracker = tracker;
|
||||
mCallbackHandler = new JobServiceHandler(looper);
|
||||
mJobConcurrencyManager = concurrencyManager;
|
||||
@@ -288,6 +293,11 @@ public final class JobServiceContext implements ServiceConnection {
|
||||
mWakeLock.setReferenceCounted(false);
|
||||
mWakeLock.acquire();
|
||||
|
||||
// Note the start when we try to bind so that the app is charged for some processing
|
||||
// even if binding fails.
|
||||
mEconomyManagerInternal.noteInstantaneousEvent(
|
||||
job.getSourceUserId(), job.getSourcePackageName(),
|
||||
getStartActionId(job), String.valueOf(job.getJobId()));
|
||||
mVerb = VERB_BINDING;
|
||||
scheduleOpTimeOutLocked();
|
||||
final Intent intent = new Intent().setComponent(job.getServiceComponent());
|
||||
@@ -350,6 +360,9 @@ public final class JobServiceContext implements ServiceConnection {
|
||||
} catch (RemoteException e) {
|
||||
// Whatever.
|
||||
}
|
||||
mEconomyManagerInternal.noteOngoingEventStarted(
|
||||
job.getSourceUserId(), job.getSourcePackageName(),
|
||||
getRunningActionId(job), String.valueOf(job.getJobId()));
|
||||
final String jobPackage = job.getSourcePackageName();
|
||||
final int jobUserId = job.getSourceUserId();
|
||||
UsageStatsManagerInternal usageStats =
|
||||
@@ -363,6 +376,22 @@ public final class JobServiceContext implements ServiceConnection {
|
||||
}
|
||||
}
|
||||
|
||||
@EconomicPolicy.AppAction
|
||||
private static int getStartActionId(@NonNull JobStatus job) {
|
||||
if (job.startedAsExpeditedJob || job.shouldTreatAsExpeditedJob()) {
|
||||
return JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START;
|
||||
}
|
||||
return JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START;
|
||||
}
|
||||
|
||||
@EconomicPolicy.AppAction
|
||||
private static int getRunningActionId(@NonNull JobStatus job) {
|
||||
if (job.startedAsExpeditedJob || job.shouldTreatAsExpeditedJob()) {
|
||||
return JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING;
|
||||
}
|
||||
return JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used externally to query the running job. Will return null if there is no job running.
|
||||
*/
|
||||
@@ -982,6 +1011,15 @@ public final class JobServiceContext implements ServiceConnection {
|
||||
} catch (RemoteException e) {
|
||||
// Whatever.
|
||||
}
|
||||
mEconomyManagerInternal.noteOngoingEventStopped(
|
||||
mRunningJob.getSourceUserId(), mRunningJob.getSourcePackageName(),
|
||||
getRunningActionId(mRunningJob), String.valueOf(mRunningJob.getJobId()));
|
||||
if (mParams.getStopReason() == JobParameters.STOP_REASON_TIMEOUT) {
|
||||
mEconomyManagerInternal.noteInstantaneousEvent(
|
||||
mRunningJob.getSourceUserId(), mRunningJob.getSourcePackageName(),
|
||||
JobSchedulerEconomicPolicy.ACTION_JOB_TIMEOUT,
|
||||
String.valueOf(mRunningJob.getJobId()));
|
||||
}
|
||||
if (mWakeLock != null) {
|
||||
mWakeLock.release();
|
||||
}
|
||||
|
||||
@@ -661,7 +661,8 @@ public final class ConnectivityController extends RestrictingController implemen
|
||||
NetworkCapabilities capabilities, Constants constants) {
|
||||
// A restricted job that's out of quota MUST use an unmetered network.
|
||||
if (jobStatus.getEffectiveStandbyBucket() == RESTRICTED_INDEX
|
||||
&& !jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)) {
|
||||
&& (!jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA)
|
||||
|| !jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_TARE_WEALTH))) {
|
||||
final NetworkCapabilities.Builder builder =
|
||||
copyCapabilities(jobStatus.getJob().getRequiredNetwork());
|
||||
builder.addCapability(NET_CAPABILITY_NOT_METERED);
|
||||
|
||||
@@ -1141,7 +1141,7 @@ public final class JobStatus {
|
||||
* treated as an expedited job.
|
||||
*/
|
||||
public boolean shouldTreatAsExpeditedJob() {
|
||||
return mExpeditedQuotaApproved && isRequestedExpeditedJob();
|
||||
return mExpeditedQuotaApproved && mExpeditedTareApproved && isRequestedExpeditedJob();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1564,7 +1564,8 @@ public final class JobStatus {
|
||||
// sessions (exempt from dynamic restrictions), we need the additional check to ensure
|
||||
// that NEVER jobs don't run.
|
||||
// TODO: cleanup quota and standby bucket management so we don't need the additional checks
|
||||
if ((!mReadyWithinQuota && !mReadyDynamicSatisfied && !shouldTreatAsExpeditedJob())
|
||||
if (((!mReadyWithinQuota || !mReadyTareWealth)
|
||||
&& !mReadyDynamicSatisfied && !shouldTreatAsExpeditedJob())
|
||||
|| getEffectiveStandbyBucket() == NEVER_INDEX) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -372,6 +372,9 @@ public final class QuotaController extends StateController {
|
||||
private final BackgroundJobsController mBackgroundJobsController;
|
||||
private final ConnectivityController mConnectivityController;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean mIsEnabled;
|
||||
|
||||
/** 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;
|
||||
|
||||
@@ -590,6 +593,7 @@ public final class QuotaController extends StateController {
|
||||
mQcConstants = new QcConstants();
|
||||
mBackgroundJobsController = backgroundJobsController;
|
||||
mConnectivityController = connectivityController;
|
||||
mIsEnabled = !mConstants.USE_TARE_POLICY;
|
||||
|
||||
// Set up the app standby bucketing tracker
|
||||
AppStandbyInternal appStandby = LocalServices.getService(AppStandbyInternal.class);
|
||||
@@ -837,6 +841,9 @@ public final class QuotaController extends StateController {
|
||||
/** @return true if the job is within expedited job quota. */
|
||||
@GuardedBy("mLock")
|
||||
public boolean isWithinEJQuotaLocked(@NonNull final JobStatus jobStatus) {
|
||||
if (!mIsEnabled) {
|
||||
return true;
|
||||
}
|
||||
if (isQuotaFreeLocked(jobStatus.getEffectiveStandbyBucket())) {
|
||||
return true;
|
||||
}
|
||||
@@ -884,6 +891,9 @@ public final class QuotaController extends StateController {
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isWithinQuotaLocked(@NonNull final JobStatus jobStatus) {
|
||||
if (!mIsEnabled) {
|
||||
return true;
|
||||
}
|
||||
final int standbyBucket = jobStatus.getEffectiveStandbyBucket();
|
||||
// A job is within quota if one of the following is true:
|
||||
// 1. it was started while the app was in the TOP state
|
||||
@@ -910,6 +920,9 @@ public final class QuotaController extends StateController {
|
||||
@GuardedBy("mLock")
|
||||
boolean isWithinQuotaLocked(final int userId, @NonNull final String packageName,
|
||||
final int standbyBucket) {
|
||||
if (!mIsEnabled) {
|
||||
return true;
|
||||
}
|
||||
if (standbyBucket == NEVER_INDEX) return false;
|
||||
|
||||
if (isQuotaFreeLocked(standbyBucket)) return true;
|
||||
@@ -2980,7 +2993,8 @@ public final class QuotaController extends StateController {
|
||||
|
||||
@Override
|
||||
public void onConstantsUpdatedLocked() {
|
||||
if (mQcConstants.mShouldReevaluateConstraints) {
|
||||
if (mQcConstants.mShouldReevaluateConstraints || mIsEnabled == mConstants.USE_TARE_POLICY) {
|
||||
mIsEnabled = !mConstants.USE_TARE_POLICY;
|
||||
// Update job bookkeeping out of band.
|
||||
JobSchedulerBackgroundThread.getHandler().post(() -> {
|
||||
synchronized (mLock) {
|
||||
@@ -4120,6 +4134,7 @@ public final class QuotaController extends StateController {
|
||||
@Override
|
||||
public void dumpControllerStateLocked(final IndentingPrintWriter pw,
|
||||
final Predicate<JobStatus> predicate) {
|
||||
pw.println("Is enabled: " + mIsEnabled);
|
||||
pw.println("Is charging: " + mChargeTracker.isChargingLocked());
|
||||
pw.println("Current elapsed time: " + sElapsedRealtimeClock.millis());
|
||||
pw.println();
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.util.Slog;
|
||||
import android.util.SparseArrayMap;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.server.JobSchedulerBackgroundThread;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.job.JobSchedulerService;
|
||||
import com.android.server.tare.EconomyManagerInternal;
|
||||
@@ -170,6 +171,7 @@ public class TareController extends StateController {
|
||||
mBackgroundJobsController = backgroundJobsController;
|
||||
mConnectivityController = connectivityController;
|
||||
mEconomyManagerInternal = LocalServices.getService(EconomyManagerInternal.class);
|
||||
mIsEnabled = mConstants.USE_TARE_POLICY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -237,6 +239,32 @@ public class TareController extends StateController {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@GuardedBy("mLock")
|
||||
public void onConstantsUpdatedLocked() {
|
||||
if (mIsEnabled != mConstants.USE_TARE_POLICY) {
|
||||
mIsEnabled = mConstants.USE_TARE_POLICY;
|
||||
// Update job bookkeeping out of band.
|
||||
JobSchedulerBackgroundThread.getHandler().post(() -> {
|
||||
synchronized (mLock) {
|
||||
final long nowElapsed = sElapsedRealtimeClock.millis();
|
||||
mService.getJobStore().forEachJob((jobStatus) -> {
|
||||
if (!mIsEnabled) {
|
||||
jobStatus.setTareWealthConstraintSatisfied(nowElapsed, true);
|
||||
setExpeditedTareApproved(jobStatus, nowElapsed, true);
|
||||
} else {
|
||||
jobStatus.setTareWealthConstraintSatisfied(
|
||||
nowElapsed, hasEnoughWealthLocked(jobStatus));
|
||||
setExpeditedTareApproved(jobStatus, nowElapsed,
|
||||
jobStatus.isRequestedExpeditedJob()
|
||||
&& canAffordExpeditedBillLocked(jobStatus));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
public boolean canScheduleEJ(@NonNull JobStatus jobStatus) {
|
||||
if (!mIsEnabled) {
|
||||
@@ -245,6 +273,21 @@ public class TareController extends StateController {
|
||||
return canAffordBillLocked(jobStatus, BILL_JOB_START_EXPEDITED);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
public long getMaxJobExecutionTimeMsLocked(@NonNull JobStatus jobStatus) {
|
||||
if (!mIsEnabled) {
|
||||
return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS;
|
||||
}
|
||||
if (jobStatus.shouldTreatAsExpeditedJob()) {
|
||||
return mEconomyManagerInternal.getMaxDurationMs(
|
||||
jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(),
|
||||
BILL_JOB_RUNNING_EXPEDITED);
|
||||
}
|
||||
return mEconomyManagerInternal.getMaxDurationMs(
|
||||
jobStatus.getSourceUserId(), jobStatus.getSourcePackageName(),
|
||||
BILL_JOB_RUNNING_DEFAULT);
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void addJobToBillList(@NonNull JobStatus jobStatus, @NonNull ActionBill bill) {
|
||||
final int userId = jobStatus.getSourceUserId();
|
||||
|
||||
@@ -678,6 +678,7 @@ public class JobStatusTest {
|
||||
|
||||
private void markImplicitConstraintsSatisfied(JobStatus job, boolean isSatisfied) {
|
||||
job.setQuotaConstraintSatisfied(sElapsedRealtimeClock.millis(), isSatisfied);
|
||||
job.setTareWealthConstraintSatisfied(sElapsedRealtimeClock.millis(), isSatisfied);
|
||||
job.setDeviceNotDozingConstraintSatisfied(
|
||||
sElapsedRealtimeClock.millis(), isSatisfied, false);
|
||||
job.setBackgroundNotRestrictedConstraintSatisfied(
|
||||
|
||||
@@ -389,6 +389,8 @@ public class QuotaControllerTest {
|
||||
/* state */ true, /* allowlisted */false);
|
||||
js.setBackgroundNotRestrictedConstraintSatisfied(
|
||||
sElapsedRealtimeClock.millis(), true, false);
|
||||
js.setTareWealthConstraintSatisfied(sElapsedRealtimeClock.millis(), true);
|
||||
js.setExpeditedJobTareApproved(sElapsedRealtimeClock.millis(), true);
|
||||
return js;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user