summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apex/jobscheduler/service/java/com/android/server/job/controllers/TareController.java262
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