Merge "Create start and running bills for all priorities."

This commit is contained in:
TreeHugger Robot
2021-12-15 18:49:37 +00:00
committed by Android (Google) Code Review

View File

@@ -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;
@@ -48,6 +49,56 @@ public class TareController extends StateController {
private static final boolean DEBUG = JobSchedulerService.DEBUG
|| 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_EXPEDITED)) {
return "EJ_RUNNING_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_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