diff options
| -rw-r--r-- | apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java | 262 |
1 files changed, 227 insertions, 35 deletions
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java index be3a3ee2921b..bc7b49eff5d2 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java +++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java @@ -19,6 +19,7 @@ package com.android.server.job.controllers; import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock; import android.annotation.NonNull; +import android.app.job.JobInfo; import android.util.ArrayMap; import android.util.ArraySet; import android.util.IndentingPrintWriter; @@ -49,6 +50,56 @@ public class TareController extends StateController { || Log.isLoggable(TAG, Log.DEBUG); /** + * Bill to use while we're waiting to start a min priority job. If a job isn't running yet, + * don't consider it eligible to run unless it can pay for a job start and at least some + * period of execution time. We don't want min priority jobs to use up all available credits, + * so we make sure to only run them while there are enough credits to run higher priority jobs. + */ + private static final ActionBill BILL_JOB_START_MIN = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START, 1, 0), + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 120_000L) + )); + + /** + * Bill to use when a min priority job is currently running. We don't want min priority jobs + * to use up remaining credits, so we make sure to only run them while there are enough + * credits to run higher priority jobs. We stop the job when the app's credits get too low. + */ + private static final ActionBill BILL_JOB_RUNNING_MIN = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 60_000L) + )); + + /** + * Bill to use while we're waiting to start a low priority job. If a job isn't running yet, + * don't consider it eligible to run unless it can pay for a job start and at least some + * period of execution time. We don't want low priority jobs to use up all available credits, + * so we make sure to only run them while there are enough credits to run higher priority jobs. + */ + private static final ActionBill BILL_JOB_START_LOW = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_START, 1, 0), + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 60_000L) + )); + + /** + * Bill to use when a low priority job is currently running. We don't want low priority jobs + * to use up all available credits, so we make sure to only run them while there are enough + * credits to run higher priority jobs. We stop the job when the app's credits get too low. + */ + private static final ActionBill BILL_JOB_RUNNING_LOW = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_DEFAULT_RUNNING, 0, 30_000L) + )); + + /** * Bill to use while we're waiting to start a job. If a job isn't running yet, don't consider it * eligible to run unless it can pay for a job start and at least some period of execution time. */ @@ -61,9 +112,9 @@ public class TareController extends StateController { )); /** - * Bill to use when a default is currently running. We want to track and make sure the app can - * continue to pay for 1 more second of execution time. We stop the job when the app can no - * longer pay for that time. + * Bill to use when a default priority job is currently running. We want to track and make + * sure the app can continue to pay for 1 more second of execution time. We stop the job when + * the app can no longer pay for that time. */ private static final ActionBill BILL_JOB_RUNNING_DEFAULT = new ActionBill(List.of( @@ -75,7 +126,33 @@ public class TareController extends StateController { * Bill to use while we're waiting to start a job. If a job isn't running yet, don't consider it * eligible to run unless it can pay for a job start and at least some period of execution time. */ - private static final ActionBill BILL_JOB_START_EXPEDITED = + private static final ActionBill BILL_JOB_START_HIGH = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START, 1, 0), + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, 0, 30_000L) + )); + + /** + * Bill to use when a high priority job is currently running. We want to track and make sure + * the app can continue to pay for 1 more second of execution time. We stop the job when the + * app can no longer pay for that time. + */ + private static final ActionBill BILL_JOB_RUNNING_HIGH = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, 0, 1_000L) + )); + + + /** + * Bill to use while we're waiting to start a max priority job. This should only be used for + * requested-EJs that aren't allowed to run as EJs. If a job isn't running yet, don't consider + * it eligible to run unless it can pay for a job start and at least some period of execution + * time. + */ + private static final ActionBill BILL_JOB_START_MAX = new ActionBill(List.of( new EconomyManagerInternal.AnticipatedAction( JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0), @@ -84,16 +161,63 @@ public class TareController extends StateController { )); /** - * Bill to use when an EJ is currently running (as an EJ). We want to track and make sure the - * app can continue to pay for 1 more second of execution time. We stop the job when the app can - * no longer pay for that time. + * Bill to use when a max priority job is currently running. This should only be used for + * requested-EJs that aren't allowed to run as EJs. We want to track and make sure + * the app can continue to pay for 1 more second of execution time. We stop the job when the + * app can no longer pay for that time. */ - private static final ActionBill BILL_JOB_RUNNING_EXPEDITED = + private static final ActionBill BILL_JOB_RUNNING_MAX = new ActionBill(List.of( new EconomyManagerInternal.AnticipatedAction( JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 1_000L) )); + /** + * Bill to use while we're waiting to start a job. If a job isn't running yet, don't consider it + * eligible to run unless it can pay for a job start and at least some period of execution time. + */ + private static final ActionBill BILL_JOB_START_MAX_EXPEDITED = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_MAX_START, 1, 0), + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 30_000L) + )); + + /** + * Bill to use when a max priority EJ is currently running (as an EJ). We want to track and + * make sure the app can continue to pay for 1 more second of execution time. We stop the job + * when the app can no longer pay for that time. + */ + private static final ActionBill BILL_JOB_RUNNING_MAX_EXPEDITED = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 1_000L) + )); + + /** + * Bill to use while we're waiting to start a job. If a job isn't running yet, don't consider it + * eligible to run unless it can pay for a job start and at least some period of execution time. + */ + private static final ActionBill BILL_JOB_START_HIGH_EXPEDITED = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_START, 1, 0), + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, 0, 30_000L) + )); + + /** + * Bill to use when a high priority EJ is currently running (as an EJ). We want to track and + * make sure the app can continue to pay for 1 more second of execution time. We stop the job + * when the app can no longer pay for that time. + */ + private static final ActionBill BILL_JOB_RUNNING_HIGH_EXPEDITED = + new ActionBill(List.of( + new EconomyManagerInternal.AnticipatedAction( + JobSchedulerEconomicPolicy.ACTION_JOB_HIGH_RUNNING, 0, 1_000L) + )); + private final EconomyManagerInternal mEconomyManagerInternal; private final BackgroundJobsController mBackgroundJobsController; @@ -200,10 +324,7 @@ public class TareController extends StateController { removeJobFromBillList(jobStatus, billToJobMap.keyAt(i)); } } - if (jobStatus.shouldTreatAsExpeditedJob()) { - addJobToBillList(jobStatus, BILL_JOB_RUNNING_EXPEDITED); - } - addJobToBillList(jobStatus, BILL_JOB_RUNNING_DEFAULT); + addJobToBillList(jobStatus, getRunningBill(jobStatus)); } @Override @@ -270,7 +391,7 @@ public class TareController extends StateController { if (!mIsEnabled) { return true; } - return canAffordBillLocked(jobStatus, BILL_JOB_START_EXPEDITED); + return canAffordBillLocked(jobStatus, BILL_JOB_START_MAX_EXPEDITED); } @GuardedBy("mLock") @@ -278,14 +399,9 @@ public class TareController extends StateController { 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); + getRunningBill(jobStatus)); } @GuardedBy("mLock") @@ -336,12 +452,56 @@ public class TareController extends StateController { // TODO: factor in network cost when available final ArraySet<ActionBill> bills = new ArraySet<>(); if (jobStatus.isRequestedExpeditedJob()) { - bills.add(BILL_JOB_START_EXPEDITED); + if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) { + bills.add(BILL_JOB_START_MAX_EXPEDITED); + } else { + bills.add(BILL_JOB_START_HIGH_EXPEDITED); + } + } + switch (jobStatus.getEffectivePriority()) { + case JobInfo.PRIORITY_HIGH: + bills.add(BILL_JOB_START_HIGH); + break; + case JobInfo.PRIORITY_DEFAULT: + bills.add(BILL_JOB_START_DEFAULT); + break; + case JobInfo.PRIORITY_LOW: + bills.add(BILL_JOB_START_LOW); + break; + case JobInfo.PRIORITY_MIN: + bills.add(BILL_JOB_START_MIN); + break; } - bills.add(BILL_JOB_START_DEFAULT); return bills; } + @NonNull + private ActionBill getRunningBill(JobStatus jobStatus) { + // TODO: factor in network cost when available + if (jobStatus.shouldTreatAsExpeditedJob()) { + if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) { + return BILL_JOB_RUNNING_MAX_EXPEDITED; + } else { + return BILL_JOB_RUNNING_HIGH_EXPEDITED; + } + } + switch (jobStatus.getEffectivePriority()) { + case JobInfo.PRIORITY_MAX: + return BILL_JOB_RUNNING_MAX; + case JobInfo.PRIORITY_HIGH: + return BILL_JOB_RUNNING_HIGH; + case JobInfo.PRIORITY_LOW: + return BILL_JOB_RUNNING_LOW; + case JobInfo.PRIORITY_MIN: + return BILL_JOB_RUNNING_MIN; + default: + Slog.wtf(TAG, "Got unexpected priority: " + jobStatus.getEffectivePriority()); + // Intentional fallthrough + case JobInfo.PRIORITY_DEFAULT: + return BILL_JOB_RUNNING_DEFAULT; + } + } + @GuardedBy("mLock") private boolean canAffordBillLocked(@NonNull JobStatus jobStatus, @NonNull ActionBill bill) { if (!mIsEnabled) { @@ -370,11 +530,17 @@ public class TareController extends StateController { if (!mIsEnabled) { return true; } + if (!jobStatus.isRequestedExpeditedJob()) { + return false; + } if (mService.isCurrentlyRunningLocked(jobStatus)) { - return canAffordBillLocked(jobStatus, BILL_JOB_RUNNING_EXPEDITED); + return canAffordBillLocked(jobStatus, getRunningBill(jobStatus)); } - return canAffordBillLocked(jobStatus, BILL_JOB_START_EXPEDITED); + if (jobStatus.getEffectivePriority() == JobInfo.PRIORITY_MAX) { + return canAffordBillLocked(jobStatus, BILL_JOB_START_MAX_EXPEDITED); + } + return canAffordBillLocked(jobStatus, BILL_JOB_START_HIGH_EXPEDITED); } @GuardedBy("mLock") @@ -384,18 +550,20 @@ public class TareController extends StateController { } if (mService.isCurrentlyRunningLocked(jobStatus)) { if (jobStatus.isRequestedExpeditedJob()) { - return canAffordBillLocked(jobStatus, BILL_JOB_RUNNING_EXPEDITED) + return canAffordBillLocked(jobStatus, getRunningBill(jobStatus)) || canAffordBillLocked(jobStatus, BILL_JOB_RUNNING_DEFAULT); } - return canAffordBillLocked(jobStatus, BILL_JOB_RUNNING_DEFAULT); + return canAffordBillLocked(jobStatus, getRunningBill(jobStatus)); } - if (jobStatus.isRequestedExpeditedJob() - && canAffordBillLocked(jobStatus, BILL_JOB_START_EXPEDITED)) { - return true; + final ArraySet<ActionBill> bills = getPossibleStartBills(jobStatus); + for (int i = 0; i < bills.size(); ++i) { + ActionBill bill = bills.valueAt(i); + if (canAffordBillLocked(jobStatus, bill)) { + return true; + } } - - return canAffordBillLocked(jobStatus, BILL_JOB_START_DEFAULT); + return false; } /** @@ -417,11 +585,23 @@ public class TareController extends StateController { @NonNull private String getBillName(@NonNull ActionBill bill) { - if (bill.equals(BILL_JOB_START_EXPEDITED)) { - return "EJ_START_BILL"; + if (bill.equals(BILL_JOB_START_MAX_EXPEDITED)) { + return "EJ_MAX_START_BILL"; + } + if (bill.equals(BILL_JOB_RUNNING_MAX_EXPEDITED)) { + return "EJ_MAX_RUNNING_BILL"; + } + if (bill.equals(BILL_JOB_START_HIGH_EXPEDITED)) { + return "EJ_HIGH_START_BILL"; } - if (bill.equals(BILL_JOB_RUNNING_EXPEDITED)) { - return "EJ_RUNNING_BILL"; + if (bill.equals(BILL_JOB_RUNNING_HIGH_EXPEDITED)) { + return "EJ_HIGH_RUNNING_BILL"; + } + if (bill.equals(BILL_JOB_START_HIGH)) { + return "HIGH_START_BILL"; + } + if (bill.equals(BILL_JOB_RUNNING_HIGH)) { + return "HIGH_RUNNING_BILL"; } if (bill.equals(BILL_JOB_START_DEFAULT)) { return "DEFAULT_START_BILL"; @@ -429,7 +609,19 @@ public class TareController extends StateController { if (bill.equals(BILL_JOB_RUNNING_DEFAULT)) { return "DEFAULT_RUNNING_BILL"; } - return "UNKNOWN_BILL (" + bill.toString() + ")"; + if (bill.equals(BILL_JOB_START_LOW)) { + return "LOW_START_BILL"; + } + if (bill.equals(BILL_JOB_RUNNING_LOW)) { + return "LOW_RUNNING_BILL"; + } + if (bill.equals(BILL_JOB_START_MIN)) { + return "MIN_START_BILL"; + } + if (bill.equals(BILL_JOB_RUNNING_MIN)) { + return "MIN_RUNNING_BILL"; + } + return "UNKNOWN_BILL (" + bill + ")"; } @Override |