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

Commit 366583d3 authored by Kweku Adams's avatar Kweku Adams
Browse files

Add transport affinities for flex scheduling.

Switch the flex network behavior from unmetered vs metered to looking at
network transports. Transport affinities indicate which transports are
preferred for running jobs, and which ones the system should try to
avoid, if possible. By default, when flex scheduling is enabled, the
system will avoid running jobs on the cellular network and prefer
running jobs on wifi and/or ethernet networks.

Watches tend to send most traffic over the bluetooth network. However,
there are plans to modify job network traffic in other ways for watches.
For now, watches will be excluded from network flex scheduling until
those plans are resolved.

Bug: 236261941
Bug: 299329948
Bug: 299346198
Test: atest CtsJobSchedulerTestCases:ConnectivityConstraintTest
Test: atest CtsJobSchedulerTestCases:FlexibilityConstraintTest
Test: atest frameworks/base/services/tests/mockingservicestests/src/com/android/server/job
Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/job
Change-Id: I675d72b18ae6ddc43fb1503d481ff9bb56c2dcb6
parent 896c5c42
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -998,6 +998,7 @@ public class JobSchedulerService extends com.android.server.SystemService
                    DEFAULT_SYSTEM_STOP_TO_FAILURE_RATIO);
        }

        // TODO(141645789): move into ConnectivityController.CcConfig
        private void updateConnectivityConstantsLocked() {
            CONN_CONGESTION_DELAY_FRAC = DeviceConfig.getFloat(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
                    KEY_CONN_CONGESTION_DELAY_FRAC,
+232 −23

File changed.

Preview size limit exceeded, changes collapsed.

+10 −4
Original line number Diff line number Diff line
@@ -247,6 +247,12 @@ public final class FlexibilityController extends StateController {
        mPrefetchLifeCycleStart.delete(userId);
    }

    boolean isEnabled() {
        synchronized (mLock) {
            return mFlexibilityEnabled;
        }
    }

    /** Checks if the flexibility constraint is actively satisfied for a given job. */
    @GuardedBy("mLock")
    boolean isFlexibilitySatisfiedLocked(JobStatus js) {
@@ -262,7 +268,8 @@ public final class FlexibilityController extends StateController {
    int getNumSatisfiedRequiredConstraintsLocked(JobStatus js) {
        return Integer.bitCount(mSatisfiedFlexibleConstraints)
                // Connectivity is job-specific, so must be handled separately.
                + (js.getHasAccessToUnmetered() ? 1 : 0);
                + (js.canApplyTransportAffinities()
                        && js.areTransportAffinitiesSatisfied() ? 1 : 0);
    }

    /**
@@ -495,7 +502,7 @@ public final class FlexibilityController extends StateController {
            final int curPercent = getCurPercentOfLifecycleLocked(js, nowElapsed);
            int toDrop = 0;
            final int jsMaxFlexibleConstraints = NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS
                    + (js.getPreferUnmetered() ? 1 : 0);
                    + (js.canApplyTransportAffinities() ? 1 : 0);
            for (int i = 0; i < jsMaxFlexibleConstraints; i++) {
                if (curPercent >= mPercentToDropConstraints[i]) {
                    toDrop++;
@@ -661,7 +668,6 @@ public final class FlexibilityController extends StateController {
        }
    }

    @VisibleForTesting
    class FcConfig {
        private boolean mShouldReevaluateConstraints = false;

@@ -682,7 +688,7 @@ public final class FlexibilityController extends StateController {
        static final String KEY_RESCHEDULED_JOB_DEADLINE_MS =
                FC_CONFIG_PREFIX + "rescheduled_job_deadline_ms";

        private static final boolean DEFAULT_FLEXIBILITY_ENABLED = false;
        static final boolean DEFAULT_FLEXIBILITY_ENABLED = false;
        @VisibleForTesting
        static final long DEFAULT_DEADLINE_PROXIMITY_LIMIT_MS = 15 * MINUTE_IN_MILLIS;
        @VisibleForTesting
+14 −20
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.server.job.controllers;

import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;

import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX;
@@ -163,9 +162,6 @@ public final class JobStatus {
     */
    private int mNumDroppedFlexibleConstraints;

    /** If the job is going to be passed an unmetered network. */
    private boolean mHasAccessToUnmetered;

    /** If the effective bucket has been downgraded once due to being buggy. */
    private boolean mIsDowngradedDueToBuggyApp;

@@ -562,11 +558,10 @@ public final class JobStatus {
    /** The job's dynamic requirements have been satisfied. */
    private boolean mReadyDynamicSatisfied;

    /**
     * The job prefers an unmetered network if it has the connectivity constraint but is
     * okay with any meteredness.
     */
    private final boolean mPreferUnmetered;
    /** Whether to apply the optimization transport preference logic to this job. */
    private final boolean mCanApplyTransportAffinities;
    /** True if the optimization transport preference is satisfied for this job. */
    private boolean mTransportAffinitiesSatisfied;

    /** The reason a job most recently went from ready to not ready. */
    private int mReasonReadyToUnready = JobParameters.STOP_REASON_UNDEFINED;
@@ -671,12 +666,12 @@ public final class JobStatus {
        }
        mHasExemptedMediaUrisOnly = exemptedMediaUrisOnly;

        mPreferUnmetered = job.getRequiredNetwork() != null
                && !job.getRequiredNetwork().hasCapability(NET_CAPABILITY_NOT_METERED);
        mCanApplyTransportAffinities = job.getRequiredNetwork() != null
                && job.getRequiredNetwork().getTransportTypes().length == 0;

        final boolean lacksSomeFlexibleConstraints =
                ((~requiredConstraints) & SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS) != 0
                        || mPreferUnmetered;
                        || mCanApplyTransportAffinities;
        final boolean satisfiesMinWindowException =
                (latestRunTimeElapsedMillis - earliestRunTimeElapsedMillis)
                >= MIN_WINDOW_FOR_FLEXIBILITY_MS;
@@ -688,7 +683,7 @@ public final class JobStatus {
                && (numFailures + numSystemStops) != 1
                && lacksSomeFlexibleConstraints) {
            mNumRequiredFlexibleConstraints =
                    NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS + (mPreferUnmetered ? 1 : 0);
                    NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS + (mCanApplyTransportAffinities ? 1 : 0);
            requiredConstraints |= CONSTRAINT_FLEXIBLE;
        } else {
            mNumRequiredFlexibleConstraints = 0;
@@ -1585,17 +1580,16 @@ public final class JobStatus {
        mOriginalLatestRunTimeElapsedMillis = latestRunTimeElapsed;
    }

    /** Sets the jobs access to an unmetered network. */
    void setHasAccessToUnmetered(boolean access) {
        mHasAccessToUnmetered = access;
    boolean areTransportAffinitiesSatisfied() {
        return mTransportAffinitiesSatisfied;
    }

    boolean getHasAccessToUnmetered() {
        return mHasAccessToUnmetered;
    void setTransportAffinitiesSatisfied(boolean isSatisfied) {
        mTransportAffinitiesSatisfied = isSatisfied;
    }

    boolean getPreferUnmetered() {
        return mPreferUnmetered;
    boolean canApplyTransportAffinities() {
        return mCanApplyTransportAffinities;
    }

    @JobParameters.StopReason
+199 −17

File changed.

Preview size limit exceeded, changes collapsed.

Loading