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

Commit 0ef24848 authored by Alex Bianchi's avatar Alex Bianchi Committed by Android (Google) Code Review
Browse files

Merge "Decrease number of sElapsedRealtimeClock.millis() calls in Flexibility Controller"

parents b95efe18 b5480ac5
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -176,12 +176,13 @@ public final class BatteryController extends RestrictingController {
            Slog.d(TAG, "maybeReportNewChargingStateLocked: "
            Slog.d(TAG, "maybeReportNewChargingStateLocked: "
                    + powerConnected + "/" + stablePower + "/" + batteryNotLow);
                    + powerConnected + "/" + stablePower + "/" + batteryNotLow);
        }
        }
        final long nowElapsed = sElapsedRealtimeClock.millis();

        mFlexibilityController.setConstraintSatisfied(
        mFlexibilityController.setConstraintSatisfied(
                JobStatus.CONSTRAINT_CHARGING, mService.isBatteryCharging());
                JobStatus.CONSTRAINT_CHARGING, mService.isBatteryCharging(), nowElapsed);
        mFlexibilityController
        mFlexibilityController.setConstraintSatisfied(
            .setConstraintSatisfied(JobStatus.CONSTRAINT_BATTERY_NOT_LOW, batteryNotLow);
                        JobStatus.CONSTRAINT_BATTERY_NOT_LOW, batteryNotLow, nowElapsed);


        final long nowElapsed = sElapsedRealtimeClock.millis();
        for (int i = mTrackedTasks.size() - 1; i >= 0; i--) {
        for (int i = mTrackedTasks.size() - 1; i >= 0; i--) {
            final JobStatus ts = mTrackedTasks.valueAt(i);
            final JobStatus ts = mTrackedTasks.valueAt(i);
            if (ts.hasChargingConstraint()) {
            if (ts.hasChargingConstraint()) {
+19 −22
Original line number Original line Diff line number Diff line
@@ -137,9 +137,9 @@ public final class FlexibilityController extends StateController {
            new PrefetchController.PrefetchChangedListener() {
            new PrefetchController.PrefetchChangedListener() {
                @Override
                @Override
                public void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId,
                public void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId,
                        String pkgName, long prevEstimatedLaunchTime, long newEstimatedLaunchTime) {
                        String pkgName, long prevEstimatedLaunchTime,
                        long newEstimatedLaunchTime, long nowElapsed) {
                    synchronized (mLock) {
                    synchronized (mLock) {
                        final long nowElapsed = sElapsedRealtimeClock.millis();
                        final long prefetchThreshold =
                        final long prefetchThreshold =
                                mPrefetchController.getLaunchTimeThresholdMs();
                                mPrefetchController.getLaunchTimeThresholdMs();
                        boolean jobWasInPrefetchWindow  = prevEstimatedLaunchTime
                        boolean jobWasInPrefetchWindow  = prevEstimatedLaunchTime
@@ -158,8 +158,8 @@ public final class FlexibilityController extends StateController {
                            if (!js.hasFlexibilityConstraint()) {
                            if (!js.hasFlexibilityConstraint()) {
                                continue;
                                continue;
                            }
                            }
                            mFlexibilityTracker.resetJobNumDroppedConstraints(js);
                            mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed);
                            mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js);
                            mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed);
                        }
                        }
                    }
                    }
                }
                }
@@ -191,7 +191,7 @@ public final class FlexibilityController extends StateController {
            js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY);
            js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY);
            final long nowElapsed = sElapsedRealtimeClock.millis();
            final long nowElapsed = sElapsedRealtimeClock.millis();
            js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
            js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
            mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js);
            mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed);
        }
        }
    }
    }


@@ -239,7 +239,7 @@ public final class FlexibilityController extends StateController {
     * Changes flexibility constraint satisfaction for affected jobs.
     * Changes flexibility constraint satisfaction for affected jobs.
     */
     */
    @VisibleForTesting
    @VisibleForTesting
    void setConstraintSatisfied(int constraint, boolean state) {
    void setConstraintSatisfied(int constraint, boolean state, long nowElapsed) {
        synchronized (mLock) {
        synchronized (mLock) {
            final boolean old = (mSatisfiedFlexibleConstraints & constraint) != 0;
            final boolean old = (mSatisfiedFlexibleConstraints & constraint) != 0;
            if (old == state) {
            if (old == state) {
@@ -255,8 +255,6 @@ public final class FlexibilityController extends StateController {
            // The rest did not have a change in state and are still satisfied or unsatisfied.
            // The rest did not have a change in state and are still satisfied or unsatisfied.
            final int numConstraintsToUpdate = Math.max(curSatisfied, prevSatisfied);
            final int numConstraintsToUpdate = Math.max(curSatisfied, prevSatisfied);


            final long nowElapsed = sElapsedRealtimeClock.millis();

            // In order to get the range of all potentially satisfied jobs, we start at the number
            // In order to get the range of all potentially satisfied jobs, we start at the number
            // of satisfied system-wide constraints and iterate to the max number of potentially
            // of satisfied system-wide constraints and iterate to the max number of potentially
            // satisfied constraints, determined by how many job-specific constraints exist.
            // satisfied constraints, determined by how many job-specific constraints exist.
@@ -329,10 +327,9 @@ public final class FlexibilityController extends StateController {


    @VisibleForTesting
    @VisibleForTesting
    @GuardedBy("mLock")
    @GuardedBy("mLock")
    int getCurPercentOfLifecycleLocked(JobStatus js) {
    int getCurPercentOfLifecycleLocked(JobStatus js, long nowElapsed) {
        final long earliest = getLifeCycleBeginningElapsedLocked(js);
        final long earliest = getLifeCycleBeginningElapsedLocked(js);
        final long latest = getLifeCycleEndElapsedLocked(js, earliest);
        final long latest = getLifeCycleEndElapsedLocked(js, earliest);
        final long nowElapsed = sElapsedRealtimeClock.millis();
        if (latest == NO_LIFECYCLE_END || earliest >= nowElapsed) {
        if (latest == NO_LIFECYCLE_END || earliest >= nowElapsed) {
            return 0;
            return 0;
        }
        }
@@ -414,8 +411,8 @@ public final class FlexibilityController extends StateController {
                                .getJobsByNumRequiredConstraints(j);
                                .getJobsByNumRequiredConstraints(j);
                        for (int i = 0; i < jobs.size(); i++) {
                        for (int i = 0; i < jobs.size(); i++) {
                            JobStatus js = jobs.valueAt(i);
                            JobStatus js = jobs.valueAt(i);
                            mFlexibilityTracker.resetJobNumDroppedConstraints(js);
                            mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed);
                            mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js);
                            mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js, nowElapsed);
                            if (js.setFlexibilityConstraintSatisfied(
                            if (js.setFlexibilityConstraintSatisfied(
                                    nowElapsed, isFlexibilitySatisfiedLocked(js))) {
                                    nowElapsed, isFlexibilitySatisfiedLocked(js))) {
                                changedJobs.add(js);
                                changedJobs.add(js);
@@ -479,8 +476,8 @@ public final class FlexibilityController extends StateController {
            mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).remove(js);
            mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).remove(js);
        }
        }


        public void resetJobNumDroppedConstraints(JobStatus js) {
        public void resetJobNumDroppedConstraints(JobStatus js, long nowElapsed) {
            final int curPercent = getCurPercentOfLifecycleLocked(js);
            final int curPercent = getCurPercentOfLifecycleLocked(js, nowElapsed);
            int toDrop = 0;
            int toDrop = 0;
            final int jsMaxFlexibleConstraints = NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS
            final int jsMaxFlexibleConstraints = NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS
                    + (js.getPreferUnmetered() ? 1 : 0);
                    + (js.getPreferUnmetered() ? 1 : 0);
@@ -489,7 +486,8 @@ public final class FlexibilityController extends StateController {
                    toDrop++;
                    toDrop++;
                }
                }
            }
            }
            adjustJobsRequiredConstraints(js, js.getNumDroppedFlexibleConstraints() - toDrop);
            adjustJobsRequiredConstraints(
                    js, js.getNumDroppedFlexibleConstraints() - toDrop, nowElapsed);
        }
        }


        /** Returns all tracked jobs. */
        /** Returns all tracked jobs. */
@@ -502,13 +500,12 @@ public final class FlexibilityController extends StateController {
         * Returns false if the job status's number of flexible constraints is now 0.
         * Returns false if the job status's number of flexible constraints is now 0.
         * Jobs with 0 required flexible constraints are removed from the tracker.
         * Jobs with 0 required flexible constraints are removed from the tracker.
         */
         */
        public boolean adjustJobsRequiredConstraints(JobStatus js, int n) {
        public boolean adjustJobsRequiredConstraints(JobStatus js, int n, long nowElapsed) {
            if (n == 0) {
            if (n == 0) {
                return false;
                return false;
            }
            }
            remove(js);
            remove(js);
            js.adjustNumRequiredFlexibleConstraints(n);
            js.adjustNumRequiredFlexibleConstraints(n);
            final long nowElapsed = sElapsedRealtimeClock.millis();
            js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
            js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
            if (js.getNumRequiredFlexibleConstraints() <= 0) {
            if (js.getNumRequiredFlexibleConstraints() <= 0) {
                maybeStopTrackingJobLocked(js, null, false);
                maybeStopTrackingJobLocked(js, null, false);
@@ -553,7 +550,7 @@ public final class FlexibilityController extends StateController {
            return js.getSourceUserId() == userId;
            return js.getSourceUserId() == userId;
        }
        }


        public void scheduleDropNumConstraintsAlarm(JobStatus js) {
        public void scheduleDropNumConstraintsAlarm(JobStatus js, long nowElapsed) {
            long nextTimeElapsed;
            long nextTimeElapsed;
            synchronized (mLock) {
            synchronized (mLock) {
                final long earliest = getLifeCycleBeginningElapsedLocked(js);
                final long earliest = getLifeCycleBeginningElapsedLocked(js);
@@ -567,7 +564,7 @@ public final class FlexibilityController extends StateController {


                if (latest - nextTimeElapsed < mDeadlineProximityLimitMs) {
                if (latest - nextTimeElapsed < mDeadlineProximityLimitMs) {
                    mFlexibilityTracker.adjustJobsRequiredConstraints(
                    mFlexibilityTracker.adjustJobsRequiredConstraints(
                            js, -js.getNumRequiredFlexibleConstraints());
                            js, -js.getNumRequiredFlexibleConstraints(), nowElapsed);
                    return;
                    return;
                }
                }
                addAlarm(js, nextTimeElapsed);
                addAlarm(js, nextTimeElapsed);
@@ -578,21 +575,21 @@ public final class FlexibilityController extends StateController {
        protected void processExpiredAlarms(@NonNull ArraySet<JobStatus> expired) {
        protected void processExpiredAlarms(@NonNull ArraySet<JobStatus> expired) {
            synchronized (mLock) {
            synchronized (mLock) {
                ArraySet<JobStatus> changedJobs = new ArraySet<>();
                ArraySet<JobStatus> changedJobs = new ArraySet<>();
                final long nowElapsed = sElapsedRealtimeClock.millis();
                for (int i = 0; i < expired.size(); i++) {
                for (int i = 0; i < expired.size(); i++) {
                    JobStatus js = expired.valueAt(i);
                    JobStatus js = expired.valueAt(i);
                    boolean wasFlexibilitySatisfied = js.isConstraintSatisfied(CONSTRAINT_FLEXIBLE);
                    boolean wasFlexibilitySatisfied = js.isConstraintSatisfied(CONSTRAINT_FLEXIBLE);


                    final long earliest = getLifeCycleBeginningElapsedLocked(js);
                    final long earliest = getLifeCycleBeginningElapsedLocked(js);
                    final long latest = getLifeCycleEndElapsedLocked(js, earliest);
                    final long latest = getLifeCycleEndElapsedLocked(js, earliest);
                    final long nowElapsed = sElapsedRealtimeClock.millis();


                    if (latest - nowElapsed < mDeadlineProximityLimitMs) {
                    if (latest - nowElapsed < mDeadlineProximityLimitMs) {
                        mFlexibilityTracker.adjustJobsRequiredConstraints(js,
                        mFlexibilityTracker.adjustJobsRequiredConstraints(js,
                                -js.getNumRequiredFlexibleConstraints());
                                -js.getNumRequiredFlexibleConstraints(), nowElapsed);
                    } else {
                    } else {
                        long nextTimeElapsed =
                        long nextTimeElapsed =
                                getNextConstraintDropTimeElapsedLocked(js, earliest, latest);
                                getNextConstraintDropTimeElapsedLocked(js, earliest, latest);
                        if (mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1)
                        if (mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1,  nowElapsed)
                                && nextTimeElapsed != NO_LIFECYCLE_END) {
                                && nextTimeElapsed != NO_LIFECYCLE_END) {
                            mFlexibilityAlarmQueue.addAlarm(js, nextTimeElapsed);
                            mFlexibilityAlarmQueue.addAlarm(js, nextTimeElapsed);
                        }
                        }
+2 −1
Original line number Original line Diff line number Diff line
@@ -95,9 +95,10 @@ public final class IdleController extends RestrictingController implements Idlen
     */
     */
    @Override
    @Override
    public void reportNewIdleState(boolean isIdle) {
    public void reportNewIdleState(boolean isIdle) {
        mFlexibilityController.setConstraintSatisfied(JobStatus.CONSTRAINT_IDLE, isIdle);
        synchronized (mLock) {
        synchronized (mLock) {
            final long nowElapsed = sElapsedRealtimeClock.millis();
            final long nowElapsed = sElapsedRealtimeClock.millis();
            mFlexibilityController.setConstraintSatisfied(
                    JobStatus.CONSTRAINT_IDLE, isIdle, nowElapsed);
            for (int i = mTrackedTasks.size()-1; i >= 0; i--) {
            for (int i = mTrackedTasks.size()-1; i >= 0; i--) {
                mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(nowElapsed, isIdle);
                mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(nowElapsed, isIdle);
            }
            }
+4 −3
Original line number Original line Diff line number Diff line
@@ -105,7 +105,7 @@ public class PrefetchController extends StateController {
    public interface PrefetchChangedListener {
    public interface PrefetchChangedListener {
        /** Callback to inform listeners when estimated launch times change. */
        /** Callback to inform listeners when estimated launch times change. */
        void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, String pkgName,
        void onPrefetchCacheUpdated(ArraySet<JobStatus> jobs, int userId, String pkgName,
                long prevEstimatedLaunchTime, long newEstimatedLaunchTime);
                long prevEstimatedLaunchTime, long newEstimatedLaunchTime, long nowElapsed);
    }
    }


    @SuppressWarnings("FieldCanBeLocal")
    @SuppressWarnings("FieldCanBeLocal")
@@ -308,8 +308,9 @@ public class PrefetchController extends StateController {
                    final long nowElapsed = sElapsedRealtimeClock.millis();
                    final long nowElapsed = sElapsedRealtimeClock.millis();
                    updateThresholdAlarmLocked(userId, pkgName, now, nowElapsed);
                    updateThresholdAlarmLocked(userId, pkgName, now, nowElapsed);
                    for (int i = 0; i < mPrefetchChangedListeners.size(); i++) {
                    for (int i = 0; i < mPrefetchChangedListeners.size(); i++) {
                        mPrefetchChangedListeners.valueAt(i).onPrefetchCacheUpdated(jobs,
                        mPrefetchChangedListeners.valueAt(i).onPrefetchCacheUpdated(
                                userId, pkgName, prevEstimatedLaunchTime, newEstimatedLaunchTime);
                                jobs, userId, pkgName, prevEstimatedLaunchTime,
                                newEstimatedLaunchTime, nowElapsed);
                    }
                    }
                    if (maybeUpdateConstraintForPkgLocked(now, nowElapsed, userId, pkgName)) {
                    if (maybeUpdateConstraintForPkgLocked(now, nowElapsed, userId, pkgName)) {
                        mStateChangedListener.onControllerStateChanged(jobs);
                        mStateChangedListener.onControllerStateChanged(jobs);
+63 −43
Original line number Original line Diff line number Diff line
@@ -209,7 +209,8 @@ public class FlexibilityControllerTest {
    public void testOnConstantsUpdated_DeadlineProximity() {
    public void testOnConstantsUpdated_DeadlineProximity() {
        JobStatus js = createJobStatus("testDeadlineProximityConfig", createJob(0));
        JobStatus js = createJobStatus("testDeadlineProximityConfig", createJob(0));
        setDeviceConfigLong(KEY_DEADLINE_PROXIMITY_LIMIT, Long.MAX_VALUE);
        setDeviceConfigLong(KEY_DEADLINE_PROXIMITY_LIMIT, Long.MAX_VALUE);
        mFlexibilityController.mFlexibilityAlarmQueue.scheduleDropNumConstraintsAlarm(js);
        mFlexibilityController.mFlexibilityAlarmQueue
                .scheduleDropNumConstraintsAlarm(js, FROZEN_TIME);
        assertEquals(0, js.getNumRequiredFlexibleConstraints());
        assertEquals(0, js.getNumRequiredFlexibleConstraints());
    }
    }


@@ -336,26 +337,31 @@ public class FlexibilityControllerTest {
    @Test
    @Test
    public void testCurPercent() {
    public void testCurPercent() {
        long deadline = 1000;
        long deadline = 1000;
        long nowElapsed;
        JobInfo.Builder jb = createJob(0).setOverrideDeadline(deadline);
        JobInfo.Builder jb = createJob(0).setOverrideDeadline(deadline);
        JobStatus js = createJobStatus("time", jb);
        JobStatus js = createJobStatus("time", jb);


        assertEquals(FROZEN_TIME, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js));
        assertEquals(FROZEN_TIME, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js));
        assertEquals(deadline + FROZEN_TIME,
        assertEquals(deadline + FROZEN_TIME,
                mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME));
                mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME));
        nowElapsed = 600 + FROZEN_TIME;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(600 + FROZEN_TIME), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);
        assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js));
        assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed));


        nowElapsed = 1400;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(1400), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);
        assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js));
        assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed));


        nowElapsed = 950 + FROZEN_TIME;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(950 + FROZEN_TIME), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);
        assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js));
        assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed));


        nowElapsed = FROZEN_TIME;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(FROZEN_TIME), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);
        long delay = 100;
        long delay = 100;
        deadline = 1100;
        deadline = 1100;
        jb = createJob(0).setOverrideDeadline(deadline).setMinimumLatency(delay);
        jb = createJob(0).setOverrideDeadline(deadline).setMinimumLatency(delay);
@@ -366,18 +372,21 @@ public class FlexibilityControllerTest {
        assertEquals(deadline + FROZEN_TIME,
        assertEquals(deadline + FROZEN_TIME,
                mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME + delay));
                mFlexibilityController.getLifeCycleEndElapsedLocked(js, FROZEN_TIME + delay));


        nowElapsed = 600 + FROZEN_TIME + delay;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(600 + FROZEN_TIME + delay), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);


        assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js));
        assertEquals(60, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed));


        nowElapsed = 1400;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(1400), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);
        assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js));
        assertEquals(100, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed));


        nowElapsed = 950 + FROZEN_TIME + delay;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(950 + FROZEN_TIME + delay), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);
        assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js));
        assertEquals(95, mFlexibilityController.getCurPercentOfLifecycleLocked(js, nowElapsed));
    }
    }


    @Test
    @Test
@@ -491,19 +500,19 @@ public class FlexibilityControllerTest {
            assertEquals(3, trackedJobs.get(2).size());
            assertEquals(3, trackedJobs.get(2).size());
            assertEquals(0, trackedJobs.get(3).size());
            assertEquals(0, trackedJobs.get(3).size());


            flexTracker.adjustJobsRequiredConstraints(jobs[0], -1);
            flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME);
            assertEquals(0, trackedJobs.get(0).size());
            assertEquals(0, trackedJobs.get(0).size());
            assertEquals(1, trackedJobs.get(1).size());
            assertEquals(1, trackedJobs.get(1).size());
            assertEquals(2, trackedJobs.get(2).size());
            assertEquals(2, trackedJobs.get(2).size());
            assertEquals(0, trackedJobs.get(3).size());
            assertEquals(0, trackedJobs.get(3).size());


            flexTracker.adjustJobsRequiredConstraints(jobs[0], -1);
            flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME);
            assertEquals(1, trackedJobs.get(0).size());
            assertEquals(1, trackedJobs.get(0).size());
            assertEquals(0, trackedJobs.get(1).size());
            assertEquals(0, trackedJobs.get(1).size());
            assertEquals(2, trackedJobs.get(2).size());
            assertEquals(2, trackedJobs.get(2).size());
            assertEquals(0, trackedJobs.get(3).size());
            assertEquals(0, trackedJobs.get(3).size());


            flexTracker.adjustJobsRequiredConstraints(jobs[0], -1);
            flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME);
            assertEquals(0, trackedJobs.get(0).size());
            assertEquals(0, trackedJobs.get(0).size());
            assertEquals(0, trackedJobs.get(1).size());
            assertEquals(0, trackedJobs.get(1).size());
            assertEquals(2, trackedJobs.get(2).size());
            assertEquals(2, trackedJobs.get(2).size());
@@ -515,24 +524,25 @@ public class FlexibilityControllerTest {
            assertEquals(1, trackedJobs.get(2).size());
            assertEquals(1, trackedJobs.get(2).size());
            assertEquals(0, trackedJobs.get(3).size());
            assertEquals(0, trackedJobs.get(3).size());


            flexTracker.resetJobNumDroppedConstraints(jobs[0]);
            flexTracker.resetJobNumDroppedConstraints(jobs[0], FROZEN_TIME);
            assertEquals(0, trackedJobs.get(0).size());
            assertEquals(0, trackedJobs.get(0).size());
            assertEquals(0, trackedJobs.get(1).size());
            assertEquals(0, trackedJobs.get(1).size());
            assertEquals(2, trackedJobs.get(2).size());
            assertEquals(2, trackedJobs.get(2).size());
            assertEquals(0, trackedJobs.get(3).size());
            assertEquals(0, trackedJobs.get(3).size());


            flexTracker.adjustJobsRequiredConstraints(jobs[0], -2);
            flexTracker.adjustJobsRequiredConstraints(jobs[0], -2, FROZEN_TIME);


            assertEquals(1, trackedJobs.get(0).size());
            assertEquals(1, trackedJobs.get(0).size());
            assertEquals(0, trackedJobs.get(1).size());
            assertEquals(0, trackedJobs.get(1).size());
            assertEquals(1, trackedJobs.get(2).size());
            assertEquals(1, trackedJobs.get(2).size());
            assertEquals(0, trackedJobs.get(3).size());
            assertEquals(0, trackedJobs.get(3).size());


            final long nowElapsed = ((DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_MS / 2)
                    + HOUR_IN_MILLIS);
            JobSchedulerService.sElapsedRealtimeClock =
            JobSchedulerService.sElapsedRealtimeClock =
                    Clock.fixed(Instant.ofEpochMilli((DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_MS / 2)
                    Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);
                            + HOUR_IN_MILLIS), ZoneOffset.UTC);


            flexTracker.resetJobNumDroppedConstraints(jobs[0]);
            flexTracker.resetJobNumDroppedConstraints(jobs[0], nowElapsed);
            assertEquals(0, trackedJobs.get(0).size());
            assertEquals(0, trackedJobs.get(0).size());
            assertEquals(1, trackedJobs.get(1).size());
            assertEquals(1, trackedJobs.get(1).size());
            assertEquals(1, trackedJobs.get(2).size());
            assertEquals(1, trackedJobs.get(2).size());
@@ -615,13 +625,13 @@ public class FlexibilityControllerTest {


    @Test
    @Test
    public void testSetConstraintSatisfied_Constraints() {
    public void testSetConstraintSatisfied_Constraints() {
        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false);
        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME);
        assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE));
        assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE));


        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, true);
        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, true, FROZEN_TIME);
        assertTrue(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE));
        assertTrue(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE));


        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false);
        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME);
        assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE));
        assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE));
    }
    }


@@ -651,20 +661,21 @@ public class FlexibilityControllerTest {
                        createJobStatus(String.valueOf(i), jb), null);
                        createJobStatus(String.valueOf(i), jb), null);
            }
            }
        }
        }
        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, false);
        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, false, FROZEN_TIME);
        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false);
        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME);
        mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, false);
        mFlexibilityController.setConstraintSatisfied(
                CONSTRAINT_BATTERY_NOT_LOW, false, FROZEN_TIME);


        assertEquals(0, mFlexibilityController.mSatisfiedFlexibleConstraints);
        assertEquals(0, mFlexibilityController.mSatisfiedFlexibleConstraints);


        for (int i = 0; i < constraintCombinations.length; i++) {
        for (int i = 0; i < constraintCombinations.length; i++) {
            constraints = constraintCombinations[i];
            constraints = constraintCombinations[i];
            mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING,
            mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING,
                    (constraints & CONSTRAINT_CHARGING) != 0);
                    (constraints & CONSTRAINT_CHARGING) != 0, FROZEN_TIME);
            mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE,
            mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE,
                    (constraints & CONSTRAINT_IDLE) != 0);
                    (constraints & CONSTRAINT_IDLE) != 0, FROZEN_TIME);
            mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW,
            mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW,
                    (constraints & CONSTRAINT_BATTERY_NOT_LOW) != 0);
                    (constraints & CONSTRAINT_BATTERY_NOT_LOW) != 0, FROZEN_TIME);


            assertEquals(constraints, mFlexibilityController.mSatisfiedFlexibleConstraints);
            assertEquals(constraints, mFlexibilityController.mSatisfiedFlexibleConstraints);
            synchronized (mFlexibilityController.mLock) {
            synchronized (mFlexibilityController.mLock) {
@@ -679,6 +690,7 @@ public class FlexibilityControllerTest {
        JobInfo.Builder jb = createJob(22).setOverrideDeadline(100L);
        JobInfo.Builder jb = createJob(22).setOverrideDeadline(100L);
        JobStatus js = createJobStatus("testResetJobNumDroppedConstraints", jb);
        JobStatus js = createJobStatus("testResetJobNumDroppedConstraints", jb);
        js.adjustNumRequiredFlexibleConstraints(3);
        js.adjustNumRequiredFlexibleConstraints(3);
        long nowElapsed;


        mFlexibilityController.mFlexibilityTracker.add(js);
        mFlexibilityController.mFlexibilityTracker.add(js);


@@ -687,45 +699,51 @@ public class FlexibilityControllerTest {
        assertEquals(1, mFlexibilityController
        assertEquals(1, mFlexibilityController
                .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size());
                .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size());



        nowElapsed = 155L;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(155L), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);


        mFlexibilityController.mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1);
        mFlexibilityController.mFlexibilityTracker
                .adjustJobsRequiredConstraints(js, -1, nowElapsed);


        assertEquals(2, js.getNumRequiredFlexibleConstraints());
        assertEquals(2, js.getNumRequiredFlexibleConstraints());
        assertEquals(1, js.getNumDroppedFlexibleConstraints());
        assertEquals(1, js.getNumDroppedFlexibleConstraints());
        assertEquals(1, mFlexibilityController
        assertEquals(1, mFlexibilityController
                .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size());
                .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size());


        mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js);
        mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed);


        assertEquals(2, js.getNumRequiredFlexibleConstraints());
        assertEquals(2, js.getNumRequiredFlexibleConstraints());
        assertEquals(1, js.getNumDroppedFlexibleConstraints());
        assertEquals(1, js.getNumDroppedFlexibleConstraints());
        assertEquals(1, mFlexibilityController
        assertEquals(1, mFlexibilityController
                .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size());
                .mFlexibilityTracker.getJobsByNumRequiredConstraints(2).size());


        nowElapsed = 140L;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(140L), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);


        mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js);
        mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed);


        assertEquals(3, js.getNumRequiredFlexibleConstraints());
        assertEquals(3, js.getNumRequiredFlexibleConstraints());
        assertEquals(0, js.getNumDroppedFlexibleConstraints());
        assertEquals(0, js.getNumDroppedFlexibleConstraints());
        assertEquals(1, mFlexibilityController
        assertEquals(1, mFlexibilityController
                .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size());
                .mFlexibilityTracker.getJobsByNumRequiredConstraints(3).size());


        nowElapsed = 175L;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(175), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);


        mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js);
        mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed);


        assertEquals(0, js.getNumRequiredFlexibleConstraints());
        assertEquals(0, js.getNumRequiredFlexibleConstraints());
        assertEquals(3, js.getNumDroppedFlexibleConstraints());
        assertEquals(3, js.getNumDroppedFlexibleConstraints());


        nowElapsed = 165L;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(165L), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);


        mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js);
        mFlexibilityController.mFlexibilityTracker.resetJobNumDroppedConstraints(js, nowElapsed);


        assertEquals(1, js.getNumRequiredFlexibleConstraints());
        assertEquals(1, js.getNumRequiredFlexibleConstraints());
        assertEquals(2, js.getNumDroppedFlexibleConstraints());
        assertEquals(2, js.getNumDroppedFlexibleConstraints());
@@ -745,12 +763,14 @@ public class FlexibilityControllerTest {


        mFlexibilityController.maybeStartTrackingJobLocked(js, null);
        mFlexibilityController.maybeStartTrackingJobLocked(js, null);


        final long nowElapsed = 150L;
        JobSchedulerService.sElapsedRealtimeClock =
        JobSchedulerService.sElapsedRealtimeClock =
                Clock.fixed(Instant.ofEpochMilli(150L), ZoneOffset.UTC);
                Clock.fixed(Instant.ofEpochMilli(nowElapsed), ZoneOffset.UTC);


        mFlexibilityController.mPrefetchChangedListener.onPrefetchCacheUpdated(
        mFlexibilityController.mPrefetchChangedListener.onPrefetchCacheUpdated(
                jobs, js.getUserId(), js.getSourcePackageName(), Long.MAX_VALUE,
                jobs, js.getUserId(), js.getSourcePackageName(), Long.MAX_VALUE,
                1150L + mFlexibilityController.mConstants.PREFETCH_FORCE_BATCH_RELAX_THRESHOLD_MS);
                1150L + mFlexibilityController.mConstants.PREFETCH_FORCE_BATCH_RELAX_THRESHOLD_MS,
                nowElapsed);


        assertEquals(150L,
        assertEquals(150L,
                (long) mFlexibilityController.mPrefetchLifeCycleStart
                (long) mFlexibilityController.mPrefetchLifeCycleStart
@@ -758,7 +778,7 @@ public class FlexibilityControllerTest {
        assertEquals(150L, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js));
        assertEquals(150L, mFlexibilityController.getLifeCycleBeginningElapsedLocked(js));
        assertEquals(1150L,
        assertEquals(1150L,
                mFlexibilityController.getLifeCycleEndElapsedLocked(js, 150L));
                mFlexibilityController.getLifeCycleEndElapsedLocked(js, 150L));
        assertEquals(0, mFlexibilityController.getCurPercentOfLifecycleLocked(js));
        assertEquals(0, mFlexibilityController.getCurPercentOfLifecycleLocked(js, FROZEN_TIME));
        assertEquals(650L, mFlexibilityController
        assertEquals(650L, mFlexibilityController
                .getNextConstraintDropTimeElapsedLocked(js));
                .getNextConstraintDropTimeElapsedLocked(js));
        assertEquals(3, js.getNumRequiredFlexibleConstraints());
        assertEquals(3, js.getNumRequiredFlexibleConstraints());
Loading