diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
new file mode 100644
index 0000000..687693c
--- /dev/null
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.job.controllers;
+
+import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
+
+import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
+
+import android.annotation.ElapsedRealtimeLong;
+import android.annotation.NonNull;
+import android.app.job.JobInfo;
+import android.content.Context;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.util.ArraySet;
+import android.util.IndentingPrintWriter;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.JobSchedulerBackgroundThread;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.utils.AlarmQueue;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
+
+/**
+ * Controller that tracks the number of flexible constraints being actively satisfied.
+ * Drops constraint for TOP apps and lowers number of required constraints with time.
+ *
+ * TODO: Plug in to other controllers (b/239047584), handle prefetch (b/238887951)
+ */
+public final class FlexibilityController extends StateController {
+    /**
+     * List of all potential flexible constraints
+     */
+    @VisibleForTesting
+    static final int FLEXIBLE_CONSTRAINTS = JobStatus.CONSTRAINT_BATTERY_NOT_LOW
+            | JobStatus.CONSTRAINT_CHARGING
+            | JobStatus.CONSTRAINT_CONNECTIVITY
+            | JobStatus.CONSTRAINT_IDLE;
+
+    /** Hard cutoff to remove flexible constraints */
+    private static final long DEADLINE_PROXIMITY_LIMIT_MS = 15 * MINUTE_IN_MILLIS;
+
+    /**
+     * Keeps track of what flexible constraints are satisfied at the moment.
+     * Is updated by the other controllers.
+     */
+    private int mSatisfiedFlexibleConstraints;
+
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    final FlexibilityTracker mFlexibilityTracker;
+
+    private final FlexibilityAlarmQueue mFlexibilityAlarmQueue;
+    private final long mMinTimeBetweenAlarmsMs = MINUTE_IN_MILLIS;
+
+    /**
+     * The percent of a Jobs lifecycle to drop number of required constraints.
+     * mPercentToDropConstraints[i] denotes that at x% of a Jobs lifecycle,
+     * the controller should have i+1 constraints dropped.
+     */
+    private final int[] mPercentToDropConstraints = {50, 60, 70, 80};
+
+    /** The default deadline that all flexible constraints should be dropped by. */
+    private final long mDefaultFlexibleDeadline = 72 * HOUR_IN_MILLIS;
+
+    public FlexibilityController(JobSchedulerService service) {
+        super(service);
+        mFlexibilityTracker = new FlexibilityTracker(FLEXIBLE_CONSTRAINTS);
+        mFlexibilityAlarmQueue = new FlexibilityAlarmQueue(
+                mContext, JobSchedulerBackgroundThread.get().getLooper());
+    }
+
+    /**
+     * StateController interface
+     */
+    @Override
+    public void maybeStartTrackingJobLocked(JobStatus js, JobStatus lastJob) {
+        if (js.hasFlexibilityConstraint()) {
+            mFlexibilityTracker.add(js);
+            js.setTrackingController(JobStatus.TRACKING_FLEXIBILITY);
+            final long nowElapsed = sElapsedRealtimeClock.millis();
+            js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
+            mFlexibilityAlarmQueue.addAlarm(js, getNextConstraintDropTimeElapsed(js));
+        }
+    }
+
+    @Override
+    public void maybeStopTrackingJobLocked(JobStatus js, JobStatus incomingJob, boolean forUpdate) {
+        if (js.clearTrackingController(JobStatus.TRACKING_FLEXIBILITY)) {
+            mFlexibilityAlarmQueue.removeAlarmForKey(js);
+            mFlexibilityTracker.remove(js);
+        }
+    }
+
+    /** Checks if the flexibility constraint is actively satisfied for a given job. */
+    @VisibleForTesting
+    boolean isFlexibilitySatisfiedLocked(JobStatus js) {
+        synchronized (mLock) {
+            return mService.getUidBias(js.getUid()) == JobInfo.BIAS_TOP_APP
+                    || mService.isCurrentlyRunningLocked(js)
+                    || getNumSatisfiedRequiredConstraintsLocked(js)
+                    >= js.getNumRequiredFlexibleConstraints();
+        }
+    }
+
+    @VisibleForTesting
+    @GuardedBy("mLock")
+    int getNumSatisfiedRequiredConstraintsLocked(JobStatus js) {
+        return Integer.bitCount(js.getFlexibleConstraints() & mSatisfiedFlexibleConstraints);
+    }
+
+    /**
+     * Sets the controller's constraint to a given state.
+     * Changes flexibility constraint satisfaction for affected jobs.
+     */
+    @VisibleForTesting
+    void setConstraintSatisfied(int constraint, boolean state) {
+        synchronized (mLock) {
+            final boolean old = (mSatisfiedFlexibleConstraints & constraint) != 0;
+            if (old == state) {
+                return;
+            }
+
+            final int prevSatisfied = Integer.bitCount(mSatisfiedFlexibleConstraints);
+            mSatisfiedFlexibleConstraints =
+                    (mSatisfiedFlexibleConstraints & ~constraint) | (state ? constraint : 0);
+            final int curSatisfied = Integer.bitCount(mSatisfiedFlexibleConstraints);
+
+            // Only the max of the number of required flexible constraints will need to be updated
+            // The rest did not have a change in state and are still satisfied or unsatisfied.
+            final int numConstraintsToUpdate = Math.max(curSatisfied, prevSatisfied);
+
+            final ArraySet<JobStatus> jobs = mFlexibilityTracker.getJobsByNumRequiredConstraints(
+                    numConstraintsToUpdate);
+            final long nowElapsed = sElapsedRealtimeClock.millis();
+
+            for (int i = 0; i < jobs.size(); i++) {
+                JobStatus js = jobs.valueAt(i);
+                js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
+            }
+        }
+    }
+
+    /** Checks if the given constraint is satisfied in the flexibility controller. */
+    @VisibleForTesting
+    boolean isConstraintSatisfied(int constraint) {
+        return (mSatisfiedFlexibleConstraints & constraint) != 0;
+    }
+
+    /** The elapsed time that marks when the next constraint should be dropped. */
+    @VisibleForTesting
+    @ElapsedRealtimeLong
+    long getNextConstraintDropTimeElapsed(JobStatus js) {
+        final long earliest = js.getEarliestRunTime() == JobStatus.NO_EARLIEST_RUNTIME
+                ? js.enqueueTime : js.getEarliestRunTime();
+        final long latest = js.getLatestRunTimeElapsed() == JobStatus.NO_LATEST_RUNTIME
+                ? earliest + mDefaultFlexibleDeadline
+                : js.getLatestRunTimeElapsed();
+        final int percent = mPercentToDropConstraints[js.getNumDroppedFlexibleConstraints()];
+        final long percentInTime = ((latest - earliest) * percent) / 100;
+        return earliest + percentInTime;
+    }
+
+    @Override
+    @GuardedBy("mLock")
+    public void onUidBiasChangedLocked(int uid, int prevBias, int newBias) {
+        if (prevBias != JobInfo.BIAS_TOP_APP && newBias != JobInfo.BIAS_TOP_APP) {
+            return;
+        }
+        final long nowElapsed = sElapsedRealtimeClock.millis();
+        List<JobStatus> jobsByUid = mService.getJobStore().getJobsByUid(uid);
+        for (int i = 0; i < jobsByUid.size(); i++) {
+            JobStatus js = jobsByUid.get(i);
+            if (js.hasFlexibilityConstraint()) {
+                js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
+            }
+        }
+    }
+
+    @VisibleForTesting
+    class FlexibilityTracker {
+        final ArrayList<ArraySet<JobStatus>> mTrackedJobs;
+
+        FlexibilityTracker(int flexibleConstraints) {
+            mTrackedJobs = new ArrayList<>();
+            int numFlexibleConstraints = Integer.bitCount(flexibleConstraints);
+            for (int i = 0; i <= numFlexibleConstraints; i++) {
+                mTrackedJobs.add(new ArraySet<JobStatus>());
+            }
+        }
+
+        /** Gets every tracked job with a given number of required constraints. */
+        public ArraySet<JobStatus> getJobsByNumRequiredConstraints(int numRequired) {
+            return mTrackedJobs.get(numRequired - 1);
+        }
+
+        /** adds a JobStatus object based on number of required flexible constraints. */
+        public void add(JobStatus js) {
+            if (js.getNumRequiredFlexibleConstraints() <= 0) {
+                return;
+            }
+            mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).add(js);
+        }
+
+        /** Removes a JobStatus object. */
+        public void remove(JobStatus js) {
+            if (js.getNumRequiredFlexibleConstraints() == 0) {
+                return;
+            }
+            mTrackedJobs.get(js.getNumRequiredFlexibleConstraints() - 1).remove(js);
+        }
+
+        /** Returns all tracked jobs. */
+        public ArrayList<ArraySet<JobStatus>> getArrayList() {
+            return mTrackedJobs;
+        }
+
+        /**
+         * Adjusts number of required flexible constraints and sorts it into the tracker.
+         * 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.
+         */
+        public boolean adjustJobsRequiredConstraints(JobStatus js, int n) {
+            remove(js);
+            js.adjustNumRequiredFlexibleConstraints(n);
+            final long nowElapsed = sElapsedRealtimeClock.millis();
+            js.setFlexibilityConstraintSatisfied(nowElapsed, isFlexibilitySatisfiedLocked(js));
+            if (js.getNumRequiredFlexibleConstraints() <= 0) {
+                maybeStopTrackingJobLocked(js, null, false);
+                return false;
+            }
+            add(js);
+            return true;
+        }
+
+        public void dump(IndentingPrintWriter pw, Predicate<JobStatus> predicate) {
+            for (int i = 0; i < mTrackedJobs.size(); i++) {
+                ArraySet<JobStatus> jobs = mTrackedJobs.get(i);
+                for (int j = 0; j < mTrackedJobs.size(); j++) {
+                    final JobStatus js = jobs.valueAt(j);
+                    if (!predicate.test(js)) {
+                        continue;
+                    }
+                    pw.print("#");
+                    js.printUniqueId(pw);
+                    pw.print(" from ");
+                    UserHandle.formatUid(pw, js.getSourceUid());
+                    pw.println();
+                }
+            }
+        }
+    }
+
+    private class FlexibilityAlarmQueue extends AlarmQueue<JobStatus> {
+        private FlexibilityAlarmQueue(Context context, Looper looper) {
+            super(context, looper, "*job.flexibility_check*",
+                    "Flexible Constraint Check", false, mMinTimeBetweenAlarmsMs);
+        }
+
+        @Override
+        protected boolean isForUser(@NonNull JobStatus js, int userId) {
+            return js.getSourceUserId() == userId;
+        }
+
+        @Override
+        protected void processExpiredAlarms(@NonNull ArraySet<JobStatus> expired) {
+            synchronized (mLock) {
+                JobStatus js;
+                for (int i = 0; i < expired.size(); i++) {
+                    js = expired.valueAt(i);
+                    long time = getNextConstraintDropTimeElapsed(js);
+                    if (js.getLatestRunTimeElapsed() - time < DEADLINE_PROXIMITY_LIMIT_MS) {
+                        mFlexibilityTracker.adjustJobsRequiredConstraints(js,
+                                -js.getNumRequiredFlexibleConstraints());
+                        continue;
+                    }
+                    if (mFlexibilityTracker.adjustJobsRequiredConstraints(js, -1)) {
+                        mFlexibilityAlarmQueue.addAlarm(js, time);
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    @GuardedBy("mLock")
+    public void dumpControllerStateLocked(IndentingPrintWriter pw, Predicate<JobStatus> predicate) {
+        pw.println("# Constraints Satisfied: " + Integer.bitCount(mSatisfiedFlexibleConstraints));
+        pw.println();
+
+        mFlexibilityTracker.dump(pw, predicate);
+    }
+}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index e0f58e3..41cf4212 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -16,6 +16,9 @@
 
 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;
 import static com.android.server.job.JobSchedulerService.EXEMPTED_INDEX;
 import static com.android.server.job.JobSchedulerService.NEVER_INDEX;
@@ -99,6 +102,7 @@
     static final int CONSTRAINT_WITHIN_QUOTA = 1 << 24;      // Implicit constraint
     static final int CONSTRAINT_PREFETCH = 1 << 23;
     static final int CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 1 << 22; // Implicit constraint
+    static final int CONSTRAINT_FLEXIBLE = 1 << 21; // Implicit constraint
 
     // The following set of dynamic constraints are for specific use cases (as explained in their
     // relative naming and comments). Right now, they apply different constraints, which is fine,
@@ -118,6 +122,22 @@
                     | CONSTRAINT_IDLE;
 
     /**
+     * The set of constraints that are required to satisfy flexible constraints.
+     * Constraints explicitly requested by the job will not be added to the set.
+     */
+    private int mFlexibleConstraints;
+
+    /**
+     * Keeps track of how many flexible constraints must be satisfied for the job to execute.
+     */
+    private int mNumRequiredFlexibleConstraints;
+
+    /**
+     * Number of required flexible constraints that have been dropped.
+     */
+    private int mNumDroppedFlexibleConstraints;
+
+    /**
      * The additional set of dynamic constraints that must be met if this is an expedited job that
      * had a long enough run while the device was Dozing or in battery saver.
      */
@@ -305,6 +325,12 @@
     public static final int TRACKING_QUOTA = 1 << 6;
 
     /**
+     * Flag for {@link #trackingControllers}: the flexibility controller is currently tracking this
+     * job.
+     */
+    public static final int TRACKING_FLEXIBILITY = 1 << 7;
+
+    /**
      * Bit mask of controllers that are currently tracking the job.
      */
     private int trackingControllers;
@@ -318,6 +344,8 @@
      */
     public static final int INTERNAL_FLAG_HAS_FOREGROUND_EXEMPTION = 1 << 0;
 
+    /** Minimum difference between start and end time to have flexible constraint */
+    private static final long MIN_WINDOW_FOR_FLEXIBILITY_MS = HOUR_IN_MILLIS;
     /**
      * Versatile, persistable flags for a job that's updated within the system server,
      * as opposed to {@link JobInfo#flags} that's set by callers.
@@ -525,6 +553,33 @@
             }
         }
         mHasExemptedMediaUrisOnly = exemptedMediaUrisOnly;
+
+        if (isRequestedExpeditedJob()
+                || ((latestRunTimeElapsedMillis - earliestRunTimeElapsedMillis)
+                < MIN_WINDOW_FOR_FLEXIBILITY_MS)
+                || job.isPrefetch()) {
+            mFlexibleConstraints = 0;
+        } else {
+            if ((requiredConstraints & CONSTRAINT_CHARGING) == 0) {
+                mFlexibleConstraints |= CONSTRAINT_CHARGING;
+            }
+            if ((requiredConstraints & CONSTRAINT_BATTERY_NOT_LOW) == 0) {
+                mFlexibleConstraints |= CONSTRAINT_BATTERY_NOT_LOW;
+            }
+            if ((requiredConstraints & CONSTRAINT_IDLE) == 0) {
+                mFlexibleConstraints |= CONSTRAINT_IDLE;
+            }
+            if (job.getRequiredNetwork() != null
+                    && !job.getRequiredNetwork().hasCapability(NET_CAPABILITY_NOT_METERED)) {
+                mFlexibleConstraints |= CONSTRAINT_CONNECTIVITY;
+            }
+        }
+        if (mFlexibleConstraints != 0) {
+            // TODO(b/239047584): Uncomment once Flexibility Controller is plugged in.
+            // requiredConstraints |= CONSTRAINT_FLEXIBLE;
+            mNumRequiredFlexibleConstraints = Integer.bitCount(mFlexibleConstraints);
+        }
+
         this.requiredConstraints = requiredConstraints;
         mRequiredConstraintsOfInterest = requiredConstraints & CONSTRAINTS_OF_INTEREST;
         addDynamicConstraints(dynamicConstraints);
@@ -1082,12 +1137,35 @@
         return hasConstraint(CONSTRAINT_IDLE);
     }
 
+    /** Returns true if the job has a prefetch constraint */
+    public boolean hasPrefetchConstraint() {
+        return hasConstraint(CONSTRAINT_PREFETCH);
+    }
+
     public boolean hasContentTriggerConstraint() {
         // No need to check mDynamicConstraints since content trigger will only be in that list if
         // it's already in the requiredConstraints list.
         return (requiredConstraints&CONSTRAINT_CONTENT_TRIGGER) != 0;
     }
 
+    /** Returns true if the job has flexible job constraints enabled */
+    public boolean hasFlexibilityConstraint() {
+        return (requiredConstraints & CONSTRAINT_FLEXIBLE) != 0;
+    }
+
+    /** Returns the number of flexible job constraints required to be satisfied to execute */
+    public int getNumRequiredFlexibleConstraints() {
+        return mNumRequiredFlexibleConstraints;
+    }
+
+    /**
+     * Returns the number of required flexible job constraints that have been dropped with time.
+     * The lower this number is the easier it is for the flexibility constraint to be satisfied.
+     */
+    public int getNumDroppedFlexibleConstraints() {
+        return mNumDroppedFlexibleConstraints;
+    }
+
     /**
      * Checks both {@link #requiredConstraints} and {@link #mDynamicConstraints} to see if this job
      * requires the specified constraint.
@@ -1128,6 +1206,10 @@
         return mOriginalLatestRunTimeElapsedMillis;
     }
 
+    public int getFlexibleConstraints() {
+        return mFlexibleConstraints;
+    }
+
     public void setOriginalLatestRunTimeElapsed(long latestRunTimeElapsed) {
         mOriginalLatestRunTimeElapsedMillis = latestRunTimeElapsed;
     }
@@ -1301,6 +1383,11 @@
         return false;
     }
 
+    /** @return true if the constraint was changed, false otherwise. */
+    boolean setFlexibilityConstraintSatisfied(final long nowElapsed, boolean state) {
+        return setConstraintSatisfied(CONSTRAINT_FLEXIBLE, nowElapsed, state);
+    }
+
     /**
      * Sets whether or not this job is approved to be treated as an expedited job based on quota
      * policy.
@@ -1490,6 +1577,18 @@
         trackingControllers |= which;
     }
 
+    /** Adjusts the number of required flexible constraints by the given number */
+    public void adjustNumRequiredFlexibleConstraints(int adjustment) {
+        mNumRequiredFlexibleConstraints += adjustment;
+        if (mNumRequiredFlexibleConstraints < 0) {
+            mNumRequiredFlexibleConstraints = 0;
+        }
+        mNumDroppedFlexibleConstraints -= adjustment;
+        if (mNumDroppedFlexibleConstraints < 0) {
+            mNumDroppedFlexibleConstraints = 0;
+        }
+    }
+
     /**
      * Add additional constraints to prevent this job from running when doze or battery saver are
      * active.
@@ -1650,12 +1749,14 @@
     /** All constraints besides implicit and deadline. */
     static final int CONSTRAINTS_OF_INTEREST = CONSTRAINT_CHARGING | CONSTRAINT_BATTERY_NOT_LOW
             | CONSTRAINT_STORAGE_NOT_LOW | CONSTRAINT_TIMING_DELAY | CONSTRAINT_CONNECTIVITY
-            | CONSTRAINT_IDLE | CONSTRAINT_CONTENT_TRIGGER | CONSTRAINT_PREFETCH;
+            | CONSTRAINT_IDLE | CONSTRAINT_CONTENT_TRIGGER | CONSTRAINT_PREFETCH
+            | CONSTRAINT_FLEXIBLE;
 
     // Soft override covers all non-"functional" constraints
     static final int SOFT_OVERRIDE_CONSTRAINTS =
             CONSTRAINT_CHARGING | CONSTRAINT_BATTERY_NOT_LOW | CONSTRAINT_STORAGE_NOT_LOW
-                    | CONSTRAINT_TIMING_DELAY | CONSTRAINT_IDLE | CONSTRAINT_PREFETCH;
+                    | CONSTRAINT_TIMING_DELAY | CONSTRAINT_IDLE | CONSTRAINT_PREFETCH
+                    | CONSTRAINT_FLEXIBLE;
 
     /** Returns true whenever all dynamically set constraints are satisfied. */
     public boolean areDynamicConstraintsSatisfied() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
new file mode 100644
index 0000000..c7ccef2
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.job.controllers;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.app.AlarmManager;
+import android.app.job.JobInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManagerInternal;
+import android.os.Looper;
+import android.util.ArraySet;
+
+import com.android.server.LocalServices;
+import com.android.server.job.JobSchedulerService;
+import com.android.server.job.JobStore;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.util.ArrayList;
+
+public class FlexibilityControllerTest {
+    private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests";
+    private static final int SOURCE_USER_ID = 0;
+
+    private MockitoSession mMockingSession;
+    private FlexibilityController mFlexibilityController;
+    @Mock
+    private AlarmManager mAlarmManager;
+    @Mock
+    private Context mContext;
+    @Mock
+    private JobSchedulerService mJobSchedulerService;
+    private JobStore mJobStore;
+
+    @Before
+    public void setup() {
+        mMockingSession = mockitoSession()
+                .initMocks(this)
+                .strictness(Strictness.LENIENT)
+                .mockStatic(LocalServices.class)
+                .startMocking();
+        // Called in StateController constructor.
+        when(mJobSchedulerService.getTestableContext()).thenReturn(mContext);
+        when(mJobSchedulerService.getLock()).thenReturn(mJobSchedulerService);
+        when(mJobSchedulerService.getConstants()).thenReturn(
+                mock(JobSchedulerService.Constants.class));
+        // Called in FlexibilityController constructor.
+        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
+        when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mAlarmManager);
+        //used to get jobs by UID
+        mJobStore = JobStore.initAndGetForTesting(mContext, mContext.getFilesDir());
+        when(mJobSchedulerService.getJobStore()).thenReturn(mJobStore);
+        // Used in JobStatus.
+        doReturn(mock(PackageManagerInternal.class))
+                .when(() -> LocalServices.getService(PackageManagerInternal.class));
+        // Freeze the clocks at a moment in time
+        JobSchedulerService.sSystemClock =
+                Clock.fixed(Instant.ofEpochMilli(100L), ZoneOffset.UTC);
+        JobSchedulerService.sElapsedRealtimeClock =
+                Clock.fixed(Instant.ofEpochMilli(100L), ZoneOffset.UTC);
+        // Initialize real objects.
+        mFlexibilityController = new FlexibilityController(mJobSchedulerService);
+    }
+
+    @After
+    public void teardown() {
+        if (mMockingSession != null) {
+            mMockingSession.finishMocking();
+        }
+    }
+
+    private static JobInfo.Builder createJob(int id) {
+        return new JobInfo.Builder(id, new ComponentName("foo", "bar"));
+    }
+
+    private JobStatus createJobStatus(String testTag, JobInfo.Builder job) {
+        JobInfo jobInfo = job.build();
+        return JobStatus.createFromJobInfo(
+                jobInfo, 1000, SOURCE_PACKAGE, SOURCE_USER_ID, testTag);
+    }
+
+    @Test
+    public void testGetNextConstraintDropTimeElapsed() {
+        long nextTimeToDropNumConstraints;
+
+        // no delay, deadline
+        JobInfo.Builder jb = createJob(0).setOverrideDeadline(1000);
+        JobStatus js = createJobStatus("time", jb);
+        js.enqueueTime = 100L;
+
+        assertEquals(0, js.getEarliestRunTime());
+        assertEquals(1100L, js.getLatestRunTimeElapsed());
+        assertEquals(100L, js.enqueueTime);
+
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(600L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(700L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(800L, nextTimeToDropNumConstraints);
+
+        // delay, no deadline
+        jb = createJob(0).setMinimumLatency(800000L);
+        js = createJobStatus("time", jb);
+        js.enqueueTime = 100L;
+
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(130400100, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(156320100L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(182240100L, nextTimeToDropNumConstraints);
+
+        // no delay, no deadline
+        jb = createJob(0);
+        js = createJobStatus("time", jb);
+        js.enqueueTime = 100L;
+
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(129600100, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(155520100L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(181440100L, nextTimeToDropNumConstraints);
+
+        // delay, deadline
+        jb = createJob(0).setOverrideDeadline(1100).setMinimumLatency(100);
+        js = createJobStatus("time", jb);
+        js.enqueueTime = 100L;
+
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(700L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(800L, nextTimeToDropNumConstraints);
+        js.adjustNumRequiredFlexibleConstraints(-1);
+        nextTimeToDropNumConstraints = mFlexibilityController.getNextConstraintDropTimeElapsed(js);
+        assertEquals(900L, nextTimeToDropNumConstraints);
+    }
+
+    @Test
+    public void testWontStopJobFromRunning() {
+        JobStatus js = createJobStatus("testWontStopJobFromRunning", createJob(101));
+        // Stop satisfied constraints from causing a false positive.
+        js.adjustNumRequiredFlexibleConstraints(100);
+        synchronized (mFlexibilityController.mLock) {
+            when(mJobSchedulerService.isCurrentlyRunningLocked(js)).thenReturn(true);
+            assertTrue(mFlexibilityController.isFlexibilitySatisfiedLocked(js));
+        }
+    }
+
+    @Test
+    public void testFlexibilityTracker() {
+        FlexibilityController.FlexibilityTracker flexTracker =
+                mFlexibilityController.new
+                        FlexibilityTracker(FlexibilityController.FLEXIBLE_CONSTRAINTS);
+
+        JobStatus[] jobs = new JobStatus[4];
+        JobInfo.Builder jb;
+        for (int i = 0; i < jobs.length; i++) {
+            jb = createJob(i);
+            if (i > 0) {
+                jb.setRequiresDeviceIdle(true);
+            }
+            if (i > 1) {
+                jb.setRequiresBatteryNotLow(true);
+            }
+            if (i > 2) {
+                jb.setRequiresCharging(true);
+            }
+            jobs[i] = createJobStatus("", jb);
+            flexTracker.add(jobs[i]);
+
+        }
+
+        ArrayList<ArraySet<JobStatus>> trackedJobs = flexTracker.getArrayList();
+        assertEquals(1, trackedJobs.get(0).size());
+        assertEquals(1, trackedJobs.get(1).size());
+        assertEquals(1, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+
+        flexTracker.adjustJobsRequiredConstraints(jobs[0], -1);
+        assertEquals(1, trackedJobs.get(0).size());
+        assertEquals(2, trackedJobs.get(1).size());
+        assertEquals(0, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+
+        flexTracker.adjustJobsRequiredConstraints(jobs[0], -1);
+        assertEquals(2, trackedJobs.get(0).size());
+        assertEquals(1, trackedJobs.get(1).size());
+        assertEquals(0, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+
+        flexTracker.adjustJobsRequiredConstraints(jobs[0], -1);
+        assertEquals(1, trackedJobs.get(0).size());
+        assertEquals(1, trackedJobs.get(1).size());
+        assertEquals(0, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+
+        flexTracker.remove(jobs[1]);
+        assertEquals(1, trackedJobs.get(0).size());
+        assertEquals(0, trackedJobs.get(1).size());
+        assertEquals(0, trackedJobs.get(2).size());
+        assertEquals(0, trackedJobs.get(3).size());
+    }
+}
