Creating separate flags for Time/QuotaControllers.

TimeController and QuotaController flags don't have to be changed
atomically with other JobScheduler constants, so it's best to have them
be separate. I think it's best to have the QuotaController constant
change be atomic, which is why the flag is set up as a key/value pair.

Bug: 120793892
Test: atest android.provider.SettingsBackupTest
Test: atest com.android.server.job.controllers.ConnectivityControllerTest
Test: atest com.android.server.job.controllers.QuotaControllerTest
Test: atest com.android.server.job.controllers.StateControllerTest
Test: atest com.android.server.job.controllers.TimeControllerTest
Test: atest CtsJobSchedulerTestCases
Change-Id: I5bf20c37ea87a58bbcf4326f8e81cd6bea0a7c08
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 7c30f25..2e7283c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -105,8 +105,9 @@
     private static final int SOURCE_USER_ID = 0;
 
     private BroadcastReceiver mChargingReceiver;
-    private Constants mConstants;
+    private Constants mJsConstants;
     private QuotaController mQuotaController;
+    private QuotaController.QcConstants mQcConstants;
     private int mSourceUid;
     private IUidObserver mUidObserver;
 
@@ -132,13 +133,13 @@
                 .mockStatic(LocalServices.class)
                 .startMocking();
         // Make sure constants turn on QuotaController.
-        mConstants = new Constants();
-        mConstants.USE_HEARTBEATS = false;
+        mJsConstants = new Constants();
+        mJsConstants.USE_HEARTBEATS = false;
 
         // Called in StateController constructor.
         when(mJobSchedulerService.getTestableContext()).thenReturn(mContext);
         when(mJobSchedulerService.getLock()).thenReturn(mJobSchedulerService);
-        when(mJobSchedulerService.getConstants()).thenReturn(mConstants);
+        when(mJobSchedulerService.getConstants()).thenReturn(mJsConstants);
         // Called in QuotaController constructor.
         IActivityManager activityManager = ActivityManager.getService();
         spyOn(activityManager);
@@ -196,6 +197,7 @@
         } catch (RemoteException e) {
             fail(e.getMessage());
         }
+        mQcConstants = mQuotaController.getQcConstants();
     }
 
     @After
@@ -531,7 +533,7 @@
         expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS;
         expectedStats.bgJobCountInMaxPeriod = 15;
         expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
-                + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
         assertEquals(expectedStats, inputStats);
 
@@ -544,7 +546,7 @@
         expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS;
         expectedStats.bgJobCountInMaxPeriod = 15;
         expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
-                + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
         assertEquals(expectedStats, inputStats);
 
@@ -557,7 +559,7 @@
         expectedStats.executionTimeInMaxPeriodMs = 22 * MINUTE_IN_MILLIS;
         expectedStats.bgJobCountInMaxPeriod = 15;
         expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
-                + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
         assertEquals(expectedStats, inputStats);
 
@@ -574,7 +576,7 @@
         expectedStats.executionTimeInMaxPeriodMs = 23 * MINUTE_IN_MILLIS;
         expectedStats.bgJobCountInMaxPeriod = 18;
         expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
-                + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
         assertEquals(expectedStats, inputStats);
 
@@ -590,7 +592,7 @@
         expectedStats.executionTimeInMaxPeriodMs = 24 * MINUTE_IN_MILLIS;
         expectedStats.bgJobCountInMaxPeriod = 20;
         expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - MINUTE_IN_MILLIS)
-                + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.updateExecutionStatsLocked(0, "com.android.test", inputStats);
         assertEquals(expectedStats, inputStats);
     }
@@ -630,7 +632,7 @@
         expectedStats.executionTimeInMaxPeriodMs = 33 * MINUTE_IN_MILLIS;
         expectedStats.bgJobCountInMaxPeriod = 20;
         expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS)
-                + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                + mQcConstants.IN_QUOTA_BUFFER_MS;
         assertEquals(expectedStats,
                 mQuotaController.getExecutionStatsLocked(0, "com.android.test", WORKING_INDEX));
 
@@ -642,7 +644,7 @@
         expectedStats.executionTimeInMaxPeriodMs = 33 * MINUTE_IN_MILLIS;
         expectedStats.bgJobCountInMaxPeriod = 20;
         expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS)
-                + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                + mQcConstants.IN_QUOTA_BUFFER_MS;
         assertEquals(expectedStats,
                 mQuotaController.getExecutionStatsLocked(0, "com.android.test", FREQUENT_INDEX));
 
@@ -654,7 +656,7 @@
         expectedStats.executionTimeInMaxPeriodMs = 33 * MINUTE_IN_MILLIS;
         expectedStats.bgJobCountInMaxPeriod = 20;
         expectedStats.quotaCutoffTimeElapsed = now - (2 * HOUR_IN_MILLIS - 3 * MINUTE_IN_MILLIS)
-                + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                + mQcConstants.IN_QUOTA_BUFFER_MS;
         assertEquals(expectedStats,
                 mQuotaController.getExecutionStatsLocked(0, "com.android.test", RARE_INDEX));
     }
@@ -685,8 +687,8 @@
         // Advance clock so that the working stats shouldn't be the same.
         advanceElapsedClock(MINUTE_IN_MILLIS);
         // Change frequent bucket size so that the stats need to be recalculated.
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS = 6 * HOUR_IN_MILLIS;
-        mQuotaController.onConstantsUpdatedLocked();
+        mQcConstants.WINDOW_SIZE_FREQUENT_MS = 6 * HOUR_IN_MILLIS;
+        mQcConstants.updateConstants();
 
         ExecutionStats expectedStats = new ExecutionStats();
         expectedStats.windowSizeMs = originalStatsActive.windowSizeMs;
@@ -778,7 +780,7 @@
         setStandbyBucket(ACTIVE_INDEX);
         assertEquals(7 * MINUTE_IN_MILLIS,
                 mQuotaController.getRemainingExecutionTimeLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
-        assertEquals(mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS,
+        assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 9 * MINUTE_IN_MILLIS,
                 mQuotaController.getTimeUntilQuotaConsumedLocked(SOURCE_USER_ID, SOURCE_PACKAGE));
     }
 
@@ -901,7 +903,7 @@
     public void testIsWithinQuotaLocked_UnderDuration_OverJobCount() {
         setDischarging();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
-        final int jobCount = mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME;
+        final int jobCount = mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME;
         mQuotaController.saveTimingSession(0, "com.android.test.spam",
                 createTimingSession(now - (HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 25));
         mQuotaController.saveTimingSession(0, "com.android.test.spam",
@@ -936,7 +938,7 @@
     public void testIsWithinQuotaLocked_OverDuration_OverJobCount() {
         setDischarging();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
-        final int jobCount = mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME;
+        final int jobCount = mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME;
         mQuotaController.saveTimingSession(0, "com.android.test",
                 createTimingSession(now - (HOUR_IN_MILLIS), 15 * MINUTE_IN_MILLIS, 25));
         mQuotaController.saveTimingSession(0, "com.android.test",
@@ -1098,8 +1100,7 @@
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         // Test with timing sessions out of window but still under max execution limit.
         final long expectedAlarmTime =
-                (now - 18 * HOUR_IN_MILLIS) + 24 * HOUR_IN_MILLIS
-                        + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                (now - 18 * HOUR_IN_MILLIS) + 24 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(now - 18 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, 1));
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
@@ -1156,8 +1157,7 @@
         final long end = now - (2 * HOUR_IN_MILLIS - 5 * MINUTE_IN_MILLIS);
         // Counting backwards, the quota will come back one minute before the end.
         final long expectedAlarmTime =
-                end - MINUTE_IN_MILLIS + 2 * HOUR_IN_MILLIS
-                        + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                end - MINUTE_IN_MILLIS + 2 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.saveTimingSession(0, "com.android.test",
                 new TimingSession(now - 2 * HOUR_IN_MILLIS, end, 1));
         mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
@@ -1207,8 +1207,7 @@
 
         // Test with timing sessions in window but still in quota.
         final long start = now - (6 * HOUR_IN_MILLIS);
-        final long expectedAlarmTime =
-                start + 8 * HOUR_IN_MILLIS + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+        final long expectedAlarmTime = start + 8 * HOUR_IN_MILLIS + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.saveTimingSession(0, "com.android.test",
                 createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1));
         mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
@@ -1262,7 +1261,7 @@
         // needs to be excluded.
         final long expectedAlarmTime =
                 start + MINUTE_IN_MILLIS + 24 * HOUR_IN_MILLIS
-                        + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                        + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.saveTimingSession(0, "com.android.test",
                 createTimingSession(start, 5 * MINUTE_IN_MILLIS, 1));
         mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", standbyBucket);
@@ -1324,21 +1323,21 @@
         // And down from there.
         final long expectedWorkingAlarmTime =
                 outOfQuotaTime + (2 * HOUR_IN_MILLIS)
-                        + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                        + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", WORKING_INDEX);
         inOrder.verify(mAlarmManager, times(1))
                 .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
 
         final long expectedFrequentAlarmTime =
                 outOfQuotaTime + (8 * HOUR_IN_MILLIS)
-                        + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                        + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", FREQUENT_INDEX);
         inOrder.verify(mAlarmManager, times(1))
                 .set(anyInt(), eq(expectedFrequentAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
 
         final long expectedRareAlarmTime =
                 outOfQuotaTime + (24 * HOUR_IN_MILLIS)
-                        + mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS;
+                        + mQcConstants.IN_QUOTA_BUFFER_MS;
         mQuotaController.maybeScheduleStartAlarmLocked(0, "com.android.test", RARE_INDEX);
         inOrder.verify(mAlarmManager, times(1))
                 .set(anyInt(), eq(expectedRareAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
@@ -1365,7 +1364,7 @@
         ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID,
                 SOURCE_PACKAGE, standbyBucket);
         stats.jobCountInAllowedTime =
-                mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME + 2;
+                mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME + 2;
 
         // Invalid time in the past, so the count shouldn't be used.
         stats.jobCountExpirationTimeElapsed =
@@ -1400,8 +1399,8 @@
     @Test
     public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedBufferSize() {
         // Make sure any new value is used correctly.
-        mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS *= 2;
-        mQuotaController.onConstantsUpdatedLocked();
+        mQcConstants.IN_QUOTA_BUFFER_MS *= 2;
+        mQcConstants.updateConstants();
         runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck();
         mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
         runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck();
@@ -1410,8 +1409,8 @@
     @Test
     public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedAllowedTime() {
         // Make sure any new value is used correctly.
-        mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS /= 2;
-        mQuotaController.onConstantsUpdatedLocked();
+        mQcConstants.ALLOWED_TIME_PER_PERIOD_MS /= 2;
+        mQcConstants.updateConstants();
         runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck();
         mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
         runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck();
@@ -1420,8 +1419,8 @@
     @Test
     public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedMaxTime() {
         // Make sure any new value is used correctly.
-        mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS /= 2;
-        mQuotaController.onConstantsUpdatedLocked();
+        mQcConstants.MAX_EXECUTION_TIME_MS /= 2;
+        mQcConstants.updateConstants();
         runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck();
         mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
         runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck();
@@ -1430,10 +1429,10 @@
     @Test
     public void testMaybeScheduleStartAlarmLocked_SmallRollingQuota_UpdatedEverything() {
         // Make sure any new value is used correctly.
-        mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS *= 2;
-        mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS /= 2;
-        mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS /= 2;
-        mQuotaController.onConstantsUpdatedLocked();
+        mQcConstants.IN_QUOTA_BUFFER_MS *= 2;
+        mQcConstants.ALLOWED_TIME_PER_PERIOD_MS /= 2;
+        mQcConstants.MAX_EXECUTION_TIME_MS /= 2;
+        mQcConstants.updateConstants();
         runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_AllowedTimeCheck();
         mQuotaController.getTimingSessions(SOURCE_USER_ID, SOURCE_PACKAGE).clear();
         runTestMaybeScheduleStartAlarmLocked_SmallRollingQuota_MaxTimeCheck();
@@ -1448,9 +1447,8 @@
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         // Working set window size is 2 hours.
         final int standbyBucket = WORKING_INDEX;
-        final long contributionMs = mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS / 2;
-        final long remainingTimeMs =
-                mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS - contributionMs;
+        final long contributionMs = mQcConstants.IN_QUOTA_BUFFER_MS / 2;
+        final long remainingTimeMs = mQcConstants.ALLOWED_TIME_PER_PERIOD_MS - contributionMs;
 
         // Session straddles edge of bucket window. Only the contribution should be counted towards
         // the quota.
@@ -1462,7 +1460,7 @@
         // Expected alarm time should be when the app will have QUOTA_BUFFER_MS time of quota, which
         // is 2 hours + (QUOTA_BUFFER_MS - contributionMs) after the start of the second session.
         final long expectedAlarmTime = now - HOUR_IN_MILLIS + 2 * HOUR_IN_MILLIS
-                + (mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS - contributionMs);
+                + (mQcConstants.IN_QUOTA_BUFFER_MS - contributionMs);
         mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE,
                 standbyBucket);
         verify(mAlarmManager, times(1))
@@ -1479,9 +1477,8 @@
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         // Working set window size is 2 hours.
         final int standbyBucket = WORKING_INDEX;
-        final long contributionMs = mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS / 2;
-        final long remainingTimeMs =
-                mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS - contributionMs;
+        final long contributionMs = mQcConstants.IN_QUOTA_BUFFER_MS / 2;
+        final long remainingTimeMs = mQcConstants.MAX_EXECUTION_TIME_MS - contributionMs;
 
         // Session straddles edge of 24 hour window. Only the contribution should be counted towards
         // the quota.
@@ -1493,9 +1490,8 @@
         // Expected alarm time should be when the app will have QUOTA_BUFFER_MS time of quota, which
         // is 24 hours + (QUOTA_BUFFER_MS - contributionMs) after the start of the second session.
         final long expectedAlarmTime = now - 20 * HOUR_IN_MILLIS
-                //+ mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS
                 + 24 * HOUR_IN_MILLIS
-                + (mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS - contributionMs);
+                + (mQcConstants.IN_QUOTA_BUFFER_MS - contributionMs);
         mQuotaController.maybeScheduleStartAlarmLocked(SOURCE_USER_ID, SOURCE_PACKAGE,
                 standbyBucket);
         verify(mAlarmManager, times(1))
@@ -1515,12 +1511,12 @@
         mQuotaController.maybeStartTrackingJobLocked(jobStatus, null);
         assertFalse(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
 
-        mConstants.USE_HEARTBEATS = true;
+        mJsConstants.USE_HEARTBEATS = true;
         mQuotaController.onConstantsUpdatedLocked();
         Thread.sleep(SECOND_IN_MILLIS); // Job updates are done in the background.
         assertTrue(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
 
-        mConstants.USE_HEARTBEATS = false;
+        mJsConstants.USE_HEARTBEATS = false;
         mQuotaController.onConstantsUpdatedLocked();
         Thread.sleep(SECOND_IN_MILLIS); // Job updates are done in the background.
         assertFalse(jobStatus.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
@@ -1528,20 +1524,20 @@
 
     @Test
     public void testConstantsUpdating_ValidValues() {
-        mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS = 5 * MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS = 2 * MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS = 15 * MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS = 30 * MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS = 45 * MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS = 60 * MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS = 3 * HOUR_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE = 5000;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING = 4000;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT = 3000;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE = 2000;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME = 500;
+        mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 5 * MINUTE_IN_MILLIS;
+        mQcConstants.IN_QUOTA_BUFFER_MS = 2 * MINUTE_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_ACTIVE_MS = 15 * MINUTE_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_WORKING_MS = 30 * MINUTE_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_FREQUENT_MS = 45 * MINUTE_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_RARE_MS = 60 * MINUTE_IN_MILLIS;
+        mQcConstants.MAX_EXECUTION_TIME_MS = 3 * HOUR_IN_MILLIS;
+        mQcConstants.MAX_JOB_COUNT_ACTIVE = 5000;
+        mQcConstants.MAX_JOB_COUNT_WORKING = 4000;
+        mQcConstants.MAX_JOB_COUNT_FREQUENT = 3000;
+        mQcConstants.MAX_JOB_COUNT_RARE = 2000;
+        mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME = 500;
 
-        mQuotaController.onConstantsUpdatedLocked();
+        mQcConstants.updateConstants();
 
         assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
         assertEquals(2 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs());
@@ -1561,20 +1557,20 @@
     @Test
     public void testConstantsUpdating_InvalidValues() {
         // Test negatives/too low.
-        mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS = -MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS = -MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS = -MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS = -MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS = -MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS = -MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS = -MINUTE_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_ACTIVE = -1;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_WORKING = 1;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_FREQUENT = 1;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_RARE = 1;
-        mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME = 0;
+        mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = -MINUTE_IN_MILLIS;
+        mQcConstants.IN_QUOTA_BUFFER_MS = -MINUTE_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_ACTIVE_MS = -MINUTE_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_WORKING_MS = -MINUTE_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_FREQUENT_MS = -MINUTE_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_RARE_MS = -MINUTE_IN_MILLIS;
+        mQcConstants.MAX_EXECUTION_TIME_MS = -MINUTE_IN_MILLIS;
+        mQcConstants.MAX_JOB_COUNT_ACTIVE = -1;
+        mQcConstants.MAX_JOB_COUNT_WORKING = 1;
+        mQcConstants.MAX_JOB_COUNT_FREQUENT = 1;
+        mQcConstants.MAX_JOB_COUNT_RARE = 1;
+        mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME = 0;
 
-        mQuotaController.onConstantsUpdatedLocked();
+        mQcConstants.updateConstants();
 
         assertEquals(MINUTE_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
         assertEquals(0, mQuotaController.getInQuotaBufferMs());
@@ -1590,15 +1586,15 @@
         assertEquals(100, mQuotaController.getBucketMaxJobCounts()[RARE_INDEX]);
 
         // Test larger than a day. Controller should cap at one day.
-        mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS = 25 * HOUR_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_IN_QUOTA_BUFFER_MS = 25 * HOUR_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_ACTIVE_MS = 25 * HOUR_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_WORKING_MS = 25 * HOUR_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_FREQUENT_MS = 25 * HOUR_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_WINDOW_SIZE_RARE_MS = 25 * HOUR_IN_MILLIS;
-        mConstants.QUOTA_CONTROLLER_MAX_EXECUTION_TIME_MS = 25 * HOUR_IN_MILLIS;
+        mQcConstants.ALLOWED_TIME_PER_PERIOD_MS = 25 * HOUR_IN_MILLIS;
+        mQcConstants.IN_QUOTA_BUFFER_MS = 25 * HOUR_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_ACTIVE_MS = 25 * HOUR_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_WORKING_MS = 25 * HOUR_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_FREQUENT_MS = 25 * HOUR_IN_MILLIS;
+        mQcConstants.WINDOW_SIZE_RARE_MS = 25 * HOUR_IN_MILLIS;
+        mQcConstants.MAX_EXECUTION_TIME_MS = 25 * HOUR_IN_MILLIS;
 
-        mQuotaController.onConstantsUpdatedLocked();
+        mQcConstants.updateConstants();
 
         assertEquals(24 * HOUR_IN_MILLIS, mQuotaController.getAllowedTimePerPeriodMs());
         assertEquals(5 * MINUTE_IN_MILLIS, mQuotaController.getInQuotaBufferMs());
@@ -2219,7 +2215,7 @@
         verify(mAlarmManager, never()).set(anyInt(), anyLong(), eq(TAG_QUOTA_CHECK), any(), any());
 
         // Ran jobs up to the job limit. All of them should be allowed to run.
-        for (int i = 0; i < mConstants.QUOTA_CONTROLLER_MAX_JOB_COUNT_PER_ALLOWED_TIME; ++i) {
+        for (int i = 0; i < mQcConstants.MAX_JOB_COUNT_PER_ALLOWED_TIME; ++i) {
             JobStatus job = createJobStatus("testStartAlarmScheduled_JobCount_AllowedTime", i);
             mQuotaController.maybeStartTrackingJobLocked(job, null);
             assertTrue(job.isConstraintSatisfied(JobStatus.CONSTRAINT_WITHIN_QUOTA));
@@ -2240,7 +2236,7 @@
         ExecutionStats stats = mQuotaController.getExecutionStatsLocked(SOURCE_USER_ID,
                 SOURCE_PACKAGE, standbyBucket);
         final long expectedWorkingAlarmTime =
-                stats.jobCountExpirationTimeElapsed + mConstants.QUOTA_CONTROLLER_ALLOWED_TIME_PER_PERIOD_MS;
+                stats.jobCountExpirationTimeElapsed + mQcConstants.ALLOWED_TIME_PER_PERIOD_MS;
         verify(mAlarmManager, times(1))
                 .set(anyInt(), eq(expectedWorkingAlarmTime), eq(TAG_QUOTA_CHECK), any(), any());
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
index 494677d..19369db 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/TimeControllerTest.java
@@ -39,6 +39,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.PackageManagerInternal;
+import android.os.Looper;
 import android.os.SystemClock;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -70,7 +71,7 @@
     private static final String SOURCE_PACKAGE = "com.android.frameworks.mockingservicestests";
     private static final int SOURCE_USER_ID = 0;
 
-    private Constants mConstants;
+    private TimeController.TcConstants mConstants;
     private TimeController mTimeController;
 
     private MockitoSession mMockingSession;
@@ -88,14 +89,13 @@
                 .strictness(Strictness.LENIENT)
                 .mockStatic(LocalServices.class)
                 .startMocking();
-        // Use default constants for now.
-        mConstants = new Constants();
 
         // Called in StateController constructor.
         when(mJobSchedulerService.getTestableContext()).thenReturn(mContext);
         when(mJobSchedulerService.getLock()).thenReturn(mJobSchedulerService);
-        when(mJobSchedulerService.getConstants()).thenReturn(mConstants);
+        when(mJobSchedulerService.getConstants()).thenReturn(mock(Constants.class));
         // Called in TimeController constructor.
+        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
         when(mContext.getSystemService(Context.ALARM_SERVICE)).thenReturn(mAlarmManager);
         // Used in JobStatus.
         doReturn(mock(PackageManagerInternal.class))
@@ -111,6 +111,7 @@
 
         // Initialize real objects.
         mTimeController = new TimeController(mJobSchedulerService);
+        mConstants = mTimeController.getTcConstants();
         spyOn(mTimeController);
     }
 
@@ -159,7 +160,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DelayInOrder_NoSkipping() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
+        mConstants.SKIP_NOT_READY_JOBS = false;
         mTimeController.onConstantsUpdatedLocked();
 
         runTestMaybeStartTrackingJobLocked_DelayInOrder();
@@ -167,7 +168,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DelayInOrder_WithSkipping_AllReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+        mConstants.SKIP_NOT_READY_JOBS = true;
         mTimeController.onConstantsUpdatedLocked();
 
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -201,7 +202,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DelayInOrder_WithSkipping_SomeNotReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+        mConstants.SKIP_NOT_READY_JOBS = true;
         mTimeController.onConstantsUpdatedLocked();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
@@ -235,7 +236,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DelayReverseOrder_NoSkipping() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
+        mConstants.SKIP_NOT_READY_JOBS = false;
         mTimeController.onConstantsUpdatedLocked();
 
         runTestMaybeStartTrackingJobLocked_DelayReverseOrder();
@@ -243,7 +244,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DelayReverseOrder_WithSkipping_AllReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+        mConstants.SKIP_NOT_READY_JOBS = true;
         mTimeController.onConstantsUpdatedLocked();
 
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -279,7 +280,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DelayReverseOrder_WithSkipping_SomeNotReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+        mConstants.SKIP_NOT_READY_JOBS = true;
         mTimeController.onConstantsUpdatedLocked();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
@@ -315,7 +316,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DeadlineInOrder_NoSkipping() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
+        mConstants.SKIP_NOT_READY_JOBS = false;
         mTimeController.onConstantsUpdatedLocked();
 
         runTestMaybeStartTrackingJobLocked_DeadlineInOrder();
@@ -323,7 +324,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DeadlineInOrder_WithSkipping_AllReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+        mConstants.SKIP_NOT_READY_JOBS = true;
         mTimeController.onConstantsUpdatedLocked();
 
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -357,7 +358,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DeadlineInOrder_WithSkipping_SomeNotReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+        mConstants.SKIP_NOT_READY_JOBS = true;
         mTimeController.onConstantsUpdatedLocked();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
@@ -391,7 +392,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_NoSkipping() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
+        mConstants.SKIP_NOT_READY_JOBS = false;
         mTimeController.onConstantsUpdatedLocked();
 
         runTestMaybeStartTrackingJobLocked_DeadlineReverseOrder();
@@ -399,7 +400,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_WithSkipping_AllReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+        mConstants.SKIP_NOT_READY_JOBS = true;
         mTimeController.onConstantsUpdatedLocked();
 
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
@@ -438,7 +439,7 @@
 
     @Test
     public void testMaybeStartTrackingJobLocked_DeadlineReverseOrder_WithSkipping_SomeNotReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
+        mConstants.SKIP_NOT_READY_JOBS = true;
         mTimeController.onConstantsUpdatedLocked();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
@@ -493,8 +494,8 @@
                 .wouldBeReadyWithConstraintLocked(eq(jobEarliest), anyInt());
 
         // Starting off with the skipping off, we should still set an alarm for the earlier job.
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = false;
+        mTimeController.recheckAlarmsLocked();
         InOrder inOrder = inOrder(mAlarmManager);
 
         mTimeController.maybeStartTrackingJobLocked(jobEarliest, null);
@@ -504,16 +505,16 @@
                         eq(TAG_DEADLINE), any(), any(), any());
 
         // Turn it on, use alarm for later job.
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = true;
+        mTimeController.recheckAlarmsLocked();
 
         inOrder.verify(mAlarmManager, times(1))
                 .set(anyInt(), eq(now + HOUR_IN_MILLIS), anyLong(), anyLong(), eq(TAG_DEADLINE),
                         any(), any(), any());
 
         // Back off, use alarm for earlier job.
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = false;
+        mTimeController.recheckAlarmsLocked();
 
         inOrder.verify(mAlarmManager, times(1))
                 .set(anyInt(), eq(now + 5 * MINUTE_IN_MILLIS), anyLong(), anyLong(),
@@ -522,16 +523,16 @@
 
     @Test
     public void testCheckExpiredDelaysAndResetAlarm_NoSkipping() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = false;
+        mTimeController.recheckAlarmsLocked();
 
         runTestCheckExpiredDelaysAndResetAlarm();
     }
 
     @Test
     public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_AllReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = true;
+        mTimeController.recheckAlarmsLocked();
 
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
@@ -589,8 +590,8 @@
 
     @Test
     public void testCheckExpiredDelaysAndResetAlarm_WithSkipping_SomeNotReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = true;
+        mTimeController.recheckAlarmsLocked();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testCheckExpiredDelaysAndResetAlarm",
@@ -639,16 +640,16 @@
 
     @Test
     public void testCheckExpiredDeadlinesAndResetAlarm_NoSkipping() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = false;
+        mTimeController.recheckAlarmsLocked();
 
         runTestCheckExpiredDeadlinesAndResetAlarm();
     }
 
     @Test
     public void testCheckExpiredDeadlinesAndResetAlarm_WithSkipping_AllReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = true;
+        mTimeController.recheckAlarmsLocked();
 
         doReturn(true).when(mTimeController).wouldBeReadyWithConstraintLocked(any(), anyInt());
 
@@ -706,8 +707,8 @@
 
     @Test
     public void testCheckExpiredDeadlinesAndResetAlarm_WithSkipping_SomeNotReady() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = true;
+        mTimeController.recheckAlarmsLocked();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testCheckExpiredDeadlinesAndResetAlarm",
@@ -756,8 +757,8 @@
 
     @Test
     public void testEvaluateStateLocked_SkippingOff() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = false;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = false;
+        mTimeController.recheckAlarmsLocked();
         JobStatus job = createJobStatus("testEvaluateStateLocked_SkippingOff",
                 createJob().setOverrideDeadline(HOUR_IN_MILLIS));
 
@@ -768,8 +769,8 @@
 
     @Test
     public void testEvaluateStateLocked_SkippingOn_Delay() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = true;
+        mTimeController.recheckAlarmsLocked();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_SkippingOn_Delay",
@@ -827,8 +828,8 @@
 
     @Test
     public void testEvaluateStateLocked_SkippingOn_Deadline() {
-        mConstants.TIME_CONTROLLER_SKIP_NOT_READY_JOBS = true;
-        mTimeController.onConstantsUpdatedLocked();
+        mConstants.SKIP_NOT_READY_JOBS = true;
+        mTimeController.recheckAlarmsLocked();
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
 
         JobStatus jobLatest = createJobStatus("testEvaluateStateLocked_SkippingOn_Deadline",