Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a38d92b8 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 2012ff72 6771c6c9
Loading
Loading
Loading
Loading
+227 −35
Original line number Diff line number Diff line
@@ -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,57 @@ 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),
                    new EconomyManagerInternal.AnticipatedAction(
                            JobSchedulerEconomicPolicy.ACTION_JOB_MAX_RUNNING, 0, 30_000L)
            ));

    /**
     * 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_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),
@@ -84,16 +185,39 @@ 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 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_EXPEDITED =
    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;
        }
        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)) {
        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