Merge "Keystore: Included KM_TAG_RSA_OAEP_MGF_DIGEST tag"
diff --git a/MULTIUSER_OWNERS b/MULTIUSER_OWNERS
index 9d92e0f..b8857ec 100644
--- a/MULTIUSER_OWNERS
+++ b/MULTIUSER_OWNERS
@@ -1,5 +1,9 @@
 # OWNERS of Multiuser related files
+annabauza@google.com
 bookatz@google.com
+nykkumar@google.com
 olilan@google.com
 omakoto@google.com
+tetianameronyk@google.com
+tyk@google.com
 yamasani@google.com
diff --git a/WEAR_OWNERS b/WEAR_OWNERS
new file mode 100644
index 0000000..4f3bc27
--- /dev/null
+++ b/WEAR_OWNERS
@@ -0,0 +1,6 @@
+yzj@google.com
+shreerag@google.com
+yeabkal@google.com
+adsule@google.com
+andriyn@google.com
+yfz@google.com
diff --git a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
index adcd571..b995b06 100644
--- a/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/libcore/regression/ExpensiveObjectsPerfTest.java
@@ -158,11 +158,10 @@
     }
 
     @Test
-    public void timeClonedSimpleDateFormat() {
-        SimpleDateFormat sdf = new SimpleDateFormat();
+    public void timeNewSimpleDateFormat() {
         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         while (state.keepRunning()) {
-            sdf.clone();
+            new SimpleDateFormat();
         }
     }
 
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 2eb86c1..31d4e3b 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -37,6 +37,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManagerInternal;
+import android.content.res.Resources;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener;
@@ -992,69 +993,69 @@
                 "pre_idle_factor_short";
         private static final String KEY_USE_WINDOW_ALARMS = "use_window_alarms";
 
-        private static final long DEFAULT_FLEX_TIME_SHORT =
+        private long mDefaultFlexTimeShort =
                 !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L;
-        private static final long DEFAULT_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT =
+        private long mDefaultLightIdleAfterInactiveTimeout =
                 !COMPRESS_TIME ? 4 * 60 * 1000L : 30 * 1000L;
-        private static final long DEFAULT_LIGHT_IDLE_TIMEOUT =
+        private long mDefaultLightIdleTimeout =
                 !COMPRESS_TIME ? 5 * 60 * 1000L : 15 * 1000L;
-        private static final float DEFAULT_LIGHT_IDLE_FACTOR = 2f;
-        private static final long DEFAULT_LIGHT_MAX_IDLE_TIMEOUT =
+        private float mDefaultLightIdleFactor = 2f;
+        private long mDefaultLightMaxIdleTimeout =
                 !COMPRESS_TIME ? 15 * 60 * 1000L : 60 * 1000L;
-        private static final long DEFAULT_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET =
+        private long mDefaultLightIdleMaintenanceMinBudget =
                 !COMPRESS_TIME ? 1 * 60 * 1000L : 15 * 1000L;
-        private static final long DEFAULT_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET =
+        private long mDefaultLightIdleMaintenanceMaxBudget =
                 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L;
-        private static final long DEFAULT_MIN_LIGHT_MAINTENANCE_TIME =
+        private long mDefaultMinLightMaintenanceTime =
                 !COMPRESS_TIME ? 5 * 1000L : 1 * 1000L;
-        private static final long DEFAULT_MIN_DEEP_MAINTENANCE_TIME =
+        private long mDefaultMinDeepMaintenanceTime =
                 !COMPRESS_TIME ? 30 * 1000L : 5 * 1000L;
-        private static final long DEFAULT_INACTIVE_TIMEOUT =
+        private long mDefaultInactiveTimeout =
                 (30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
         private static final long DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY =
                 (15 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
-        private static final long DEFAULT_SENSING_TIMEOUT =
+        private long mDefaultSensingTimeout =
                 !COMPRESS_TIME ? 4 * 60 * 1000L : 60 * 1000L;
-        private static final long DEFAULT_LOCATING_TIMEOUT =
+        private long mDefaultLocatingTimeout =
                 !COMPRESS_TIME ? 30 * 1000L : 15 * 1000L;
-        private static final float DEFAULT_LOCATION_ACCURACY = 20f;
-        private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT =
+        private float mDefaultLocationAccuracy = 20f;
+        private long mDefaultMotionInactiveTimeout =
                 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L;
-        private static final long DEFAULT_MOTION_INACTIVE_TIMEOUT_FLEX =
+        private long mDefaultMotionInactiveTimeoutFlex =
                 !COMPRESS_TIME ? 60 * 1000L : 5 * 1000L;
-        private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT =
+        private long mDefaultIdleAfterInactiveTimeout =
                 (30 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
         private static final long DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY =
                 (15 * 60 * 1000L) / (!COMPRESS_TIME ? 1 : 10);
-        private static final long DEFAULT_IDLE_PENDING_TIMEOUT =
+        private long mDefaultIdlePendingTimeout =
                 !COMPRESS_TIME ? 5 * 60 * 1000L : 30 * 1000L;
-        private static final long DEFAULT_MAX_IDLE_PENDING_TIMEOUT =
+        private long mDefaultMaxIdlePendingTimeout =
                 !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L;
-        private static final float DEFAULT_IDLE_PENDING_FACTOR = 2f;
-        private static final long DEFAULT_QUICK_DOZE_DELAY_TIMEOUT =
+        private float mDefaultIdlePendingFactor = 2f;
+        private long mDefaultQuickDozeDelayTimeout =
                 !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L;
-        private static final long DEFAULT_IDLE_TIMEOUT =
+        private long mDefaultIdleTimeout =
                 !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L;
-        private static final long DEFAULT_MAX_IDLE_TIMEOUT =
+        private long mDefaultMaxIdleTimeout =
                 !COMPRESS_TIME ? 6 * 60 * 60 * 1000L : 30 * 60 * 1000L;
-        private static final float DEFAULT_IDLE_FACTOR = 2f;
-        private static final long DEFAULT_MIN_TIME_TO_ALARM =
+        private float mDefaultIdleFactor = 2f;
+        private long mDefaultMinTimeToAlarm =
                 !COMPRESS_TIME ? 30 * 60 * 1000L : 6 * 60 * 1000L;
-        private static final long DEFAULT_MAX_TEMP_APP_ALLOWLIST_DURATION_MS = 5 * 60 * 1000L;
-        private static final long DEFAULT_MMS_TEMP_APP_ALLOWLIST_DURATION_MS = 60 * 1000L;
-        private static final long DEFAULT_SMS_TEMP_APP_ALLOWLIST_DURATION_MS = 20 * 1000L;
-        private static final long DEFAULT_NOTIFICATION_ALLOWLIST_DURATION_MS = 30 * 1000L;
-        private static final boolean DEFAULT_WAIT_FOR_UNLOCK = true;
-        private static final float DEFAULT_PRE_IDLE_FACTOR_LONG = 1.67f;
-        private static final float DEFAULT_PRE_IDLE_FACTOR_SHORT = .33f;
-        private static final boolean DEFAULT_USE_WINDOW_ALARMS = true;
+        private long mDefaultMaxTempAppAllowlistDurationMs = 5 * 60 * 1000L;
+        private long mDefaultMmsTempAppAllowlistDurationMs = 60 * 1000L;
+        private long mDefaultSmsTempAppAllowlistDurationMs = 20 * 1000L;
+        private long mDefaultNotificationAllowlistDurationMs = 30 * 1000L;
+        private boolean mDefaultWaitForUnlock = true;
+        private float mDefaultPreIdleFactorLong = 1.67f;
+        private float mDefaultPreIdleFactorShort = .33f;
+        private boolean mDefaultUseWindowAlarms = true;
 
         /**
          * A somewhat short alarm window size that we will tolerate for various alarm timings.
          *
          * @see #KEY_FLEX_TIME_SHORT
          */
-        public long FLEX_TIME_SHORT = DEFAULT_FLEX_TIME_SHORT;
+        public long FLEX_TIME_SHORT = mDefaultFlexTimeShort;
 
         /**
          * This is the time, after becoming inactive, that we go in to the first
@@ -1062,28 +1063,28 @@
          *
          * @see #KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
          */
-        public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = DEFAULT_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT;
+        public long LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mDefaultLightIdleAfterInactiveTimeout;
 
         /**
          * This is the initial time that we will run in light idle maintenance mode.
          *
          * @see #KEY_LIGHT_IDLE_TIMEOUT
          */
-        public long LIGHT_IDLE_TIMEOUT = DEFAULT_LIGHT_IDLE_TIMEOUT;
+        public long LIGHT_IDLE_TIMEOUT = mDefaultLightIdleTimeout;
 
         /**
          * Scaling factor to apply to the light idle mode time each time we complete a cycle.
          *
          * @see #KEY_LIGHT_IDLE_FACTOR
          */
-        public float LIGHT_IDLE_FACTOR = DEFAULT_LIGHT_IDLE_FACTOR;
+        public float LIGHT_IDLE_FACTOR = mDefaultLightIdleFactor;
 
         /**
          * This is the maximum time we will stay in light idle mode.
          *
          * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
          */
-        public long LIGHT_MAX_IDLE_TIMEOUT = DEFAULT_LIGHT_MAX_IDLE_TIMEOUT;
+        public long LIGHT_MAX_IDLE_TIMEOUT = mDefaultLightMaxIdleTimeout;
 
         /**
          * This is the minimum amount of time we want to make available for maintenance mode
@@ -1092,7 +1093,7 @@
          *
          * @see #KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET
          */
-        public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = DEFAULT_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET;
+        public long LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mDefaultLightIdleMaintenanceMinBudget;
 
         /**
          * This is the maximum amount of time we want to make available for maintenance mode
@@ -1103,7 +1104,7 @@
          *
          * @see #KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET
          */
-        public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = DEFAULT_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET;
+        public long LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mDefaultLightIdleMaintenanceMaxBudget;
 
         /**
          * This is the minimum amount of time that we will stay in maintenance mode after
@@ -1114,7 +1115,7 @@
          *
          * @see #KEY_MIN_LIGHT_MAINTENANCE_TIME
          */
-        public long MIN_LIGHT_MAINTENANCE_TIME = DEFAULT_MIN_LIGHT_MAINTENANCE_TIME;
+        public long MIN_LIGHT_MAINTENANCE_TIME = mDefaultMinLightMaintenanceTime;
 
         /**
          * This is the minimum amount of time that we will stay in maintenance mode after
@@ -1124,7 +1125,7 @@
          * mode immediately.
          * @see #KEY_MIN_DEEP_MAINTENANCE_TIME
          */
-        public long MIN_DEEP_MAINTENANCE_TIME = DEFAULT_MIN_DEEP_MAINTENANCE_TIME;
+        public long MIN_DEEP_MAINTENANCE_TIME = mDefaultMinDeepMaintenanceTime;
 
         /**
          * This is the time, after becoming inactive, at which we start looking at the
@@ -1133,7 +1134,7 @@
          * the motion sensor whenever the screen is off.
          * @see #KEY_INACTIVE_TIMEOUT
          */
-        public long INACTIVE_TIMEOUT = DEFAULT_INACTIVE_TIMEOUT;
+        public long INACTIVE_TIMEOUT = mDefaultInactiveTimeout;
 
         /**
          * If we don't receive a callback from AnyMotion in this amount of time +
@@ -1142,14 +1143,14 @@
          * will be ignored.
          * @see #KEY_SENSING_TIMEOUT
          */
-        public long SENSING_TIMEOUT = DEFAULT_SENSING_TIMEOUT;
+        public long SENSING_TIMEOUT = mDefaultSensingTimeout;
 
         /**
          * This is how long we will wait to try to get a good location fix before going in to
          * idle mode.
          * @see #KEY_LOCATING_TIMEOUT
          */
-        public long LOCATING_TIMEOUT = DEFAULT_LOCATING_TIMEOUT;
+        public long LOCATING_TIMEOUT = mDefaultLocatingTimeout;
 
         /**
          * The desired maximum accuracy (in meters) we consider the location to be good enough to go
@@ -1157,7 +1158,7 @@
          * {@link #LOCATING_TIMEOUT} expires.
          * @see #KEY_LOCATION_ACCURACY
          */
-        public float LOCATION_ACCURACY = DEFAULT_LOCATION_ACCURACY;
+        public float LOCATION_ACCURACY = mDefaultLocationAccuracy;
 
         /**
          * This is the time, after seeing motion, that we wait after becoming inactive from
@@ -1165,14 +1166,14 @@
          *
          * @see #KEY_MOTION_INACTIVE_TIMEOUT
          */
-        public long MOTION_INACTIVE_TIMEOUT = DEFAULT_MOTION_INACTIVE_TIMEOUT;
+        public long MOTION_INACTIVE_TIMEOUT = mDefaultMotionInactiveTimeout;
 
         /**
          * This is the alarm window size we will tolerate for motion detection timings.
          *
          * @see #KEY_MOTION_INACTIVE_TIMEOUT_FLEX
          */
-        public long MOTION_INACTIVE_TIMEOUT_FLEX = DEFAULT_MOTION_INACTIVE_TIMEOUT_FLEX;
+        public long MOTION_INACTIVE_TIMEOUT_FLEX = mDefaultMotionInactiveTimeoutFlex;
 
         /**
          * This is the time, after the inactive timeout elapses, that we will wait looking
@@ -1180,7 +1181,7 @@
          *
          * @see #KEY_IDLE_AFTER_INACTIVE_TIMEOUT
          */
-        public long IDLE_AFTER_INACTIVE_TIMEOUT = DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT;
+        public long IDLE_AFTER_INACTIVE_TIMEOUT = mDefaultIdleAfterInactiveTimeout;
 
         /**
          * This is the initial time, after being idle, that we will allow ourself to be back
@@ -1188,20 +1189,20 @@
          * idle.
          * @see #KEY_IDLE_PENDING_TIMEOUT
          */
-        public long IDLE_PENDING_TIMEOUT = DEFAULT_IDLE_PENDING_TIMEOUT;
+        public long IDLE_PENDING_TIMEOUT = mDefaultIdlePendingTimeout;
 
         /**
          * Maximum pending idle timeout (time spent running) we will be allowed to use.
          * @see #KEY_MAX_IDLE_PENDING_TIMEOUT
          */
-        public long MAX_IDLE_PENDING_TIMEOUT = DEFAULT_MAX_IDLE_PENDING_TIMEOUT;
+        public long MAX_IDLE_PENDING_TIMEOUT = mDefaultMaxIdlePendingTimeout;
 
         /**
          * Scaling factor to apply to current pending idle timeout each time we cycle through
          * that state.
          * @see #KEY_IDLE_PENDING_FACTOR
          */
-        public float IDLE_PENDING_FACTOR = DEFAULT_IDLE_PENDING_FACTOR;
+        public float IDLE_PENDING_FACTOR = mDefaultIdlePendingFactor;
 
         /**
          * This is amount of time we will wait from the point where we go into
@@ -1209,33 +1210,33 @@
          * and other current activity to finish.
          * @see #KEY_QUICK_DOZE_DELAY_TIMEOUT
          */
-        public long QUICK_DOZE_DELAY_TIMEOUT = DEFAULT_QUICK_DOZE_DELAY_TIMEOUT;
+        public long QUICK_DOZE_DELAY_TIMEOUT = mDefaultQuickDozeDelayTimeout;
 
         /**
          * This is the initial time that we want to sit in the idle state before waking up
          * again to return to pending idle and allowing normal work to run.
          * @see #KEY_IDLE_TIMEOUT
          */
-        public long IDLE_TIMEOUT = DEFAULT_IDLE_TIMEOUT;
+        public long IDLE_TIMEOUT = mDefaultIdleTimeout;
 
         /**
          * Maximum idle duration we will be allowed to use.
          * @see #KEY_MAX_IDLE_TIMEOUT
          */
-        public long MAX_IDLE_TIMEOUT = DEFAULT_MAX_IDLE_TIMEOUT;
+        public long MAX_IDLE_TIMEOUT = mDefaultMaxIdleTimeout;
 
         /**
          * Scaling factor to apply to current idle timeout each time we cycle through that state.
          * @see #KEY_IDLE_FACTOR
          */
-        public float IDLE_FACTOR = DEFAULT_IDLE_FACTOR;
+        public float IDLE_FACTOR = mDefaultIdleFactor;
 
         /**
          * This is the minimum time we will allow until the next upcoming alarm for us to
          * actually go in to idle mode.
          * @see #KEY_MIN_TIME_TO_ALARM
          */
-        public long MIN_TIME_TO_ALARM = DEFAULT_MIN_TIME_TO_ALARM;
+        public long MIN_TIME_TO_ALARM = mDefaultMinTimeToAlarm;
 
         /**
          * Max amount of time to temporarily whitelist an app when it receives a high priority
@@ -1243,48 +1244,49 @@
          *
          * @see #KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS
          */
-        public long MAX_TEMP_APP_ALLOWLIST_DURATION_MS = DEFAULT_MAX_TEMP_APP_ALLOWLIST_DURATION_MS;
+        public long MAX_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultMaxTempAppAllowlistDurationMs;
 
         /**
          * Amount of time we would like to whitelist an app that is receiving an MMS.
          * @see #KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS
          */
-        public long MMS_TEMP_APP_ALLOWLIST_DURATION_MS = DEFAULT_MMS_TEMP_APP_ALLOWLIST_DURATION_MS;
+        public long MMS_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultMmsTempAppAllowlistDurationMs;
 
         /**
          * Amount of time we would like to whitelist an app that is receiving an SMS.
          * @see #KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS
          */
-        public long SMS_TEMP_APP_ALLOWLIST_DURATION_MS = DEFAULT_SMS_TEMP_APP_ALLOWLIST_DURATION_MS;
+        public long SMS_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultSmsTempAppAllowlistDurationMs;
 
         /**
          * Amount of time we would like to whitelist an app that is handling a
          * {@link android.app.PendingIntent} triggered by a {@link android.app.Notification}.
          * @see #KEY_NOTIFICATION_ALLOWLIST_DURATION_MS
          */
-        public long NOTIFICATION_ALLOWLIST_DURATION_MS = DEFAULT_NOTIFICATION_ALLOWLIST_DURATION_MS;
+        public long NOTIFICATION_ALLOWLIST_DURATION_MS = mDefaultNotificationAllowlistDurationMs;
 
         /**
          * Pre idle time factor use to make idle delay longer
          */
-        public float PRE_IDLE_FACTOR_LONG = DEFAULT_PRE_IDLE_FACTOR_LONG;
+        public float PRE_IDLE_FACTOR_LONG = mDefaultPreIdleFactorLong;
 
         /**
          * Pre idle time factor use to make idle delay shorter
          */
-        public float PRE_IDLE_FACTOR_SHORT = DEFAULT_PRE_IDLE_FACTOR_SHORT;
+        public float PRE_IDLE_FACTOR_SHORT = mDefaultPreIdleFactorShort;
 
-        public boolean WAIT_FOR_UNLOCK = DEFAULT_WAIT_FOR_UNLOCK;
+        public boolean WAIT_FOR_UNLOCK = mDefaultWaitForUnlock;
 
         /**
          * Whether to use window alarms. True to use window alarms (call AlarmManager.setWindow()).
          * False to use the legacy inexact alarms (call AlarmManager.set()).
          */
-        public boolean USE_WINDOW_ALARMS = DEFAULT_USE_WINDOW_ALARMS;
+        public boolean USE_WINDOW_ALARMS = mDefaultUseWindowAlarms;
 
         private final boolean mSmallBatteryDevice;
 
         public Constants() {
+            initDefault();
             mSmallBatteryDevice = ActivityManager.isSmallBatteryDevice();
             if (mSmallBatteryDevice) {
                 INACTIVE_TIMEOUT = DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY;
@@ -1296,6 +1298,132 @@
             onPropertiesChanged(DeviceConfig.getProperties(DeviceConfig.NAMESPACE_DEVICE_IDLE));
         }
 
+        private void initDefault() {
+            final Resources res = getContext().getResources();
+
+            mDefaultFlexTimeShort = getTimeout(
+                    res.getInteger(com.android.internal.R.integer.device_idle_flex_time_short_ms),
+                    mDefaultFlexTimeShort);
+            mDefaultLightIdleAfterInactiveTimeout = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_light_after_inactive_to_ms),
+                    mDefaultLightIdleAfterInactiveTimeout);
+            mDefaultLightIdleTimeout = getTimeout(
+                    res.getInteger(com.android.internal.R.integer.device_idle_light_idle_to_ms),
+                    mDefaultLightIdleTimeout);
+            mDefaultLightIdleFactor = res.getFloat(
+                    com.android.internal.R.integer.device_idle_light_idle_factor);
+            mDefaultLightMaxIdleTimeout = getTimeout(
+                    res.getInteger(com.android.internal.R.integer.device_idle_light_max_idle_to_ms),
+                    mDefaultLightMaxIdleTimeout);
+            mDefaultLightIdleMaintenanceMinBudget = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_light_idle_maintenance_min_budget_ms
+                    ), mDefaultLightIdleMaintenanceMinBudget);
+            mDefaultLightIdleMaintenanceMaxBudget = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_light_idle_maintenance_max_budget_ms
+                    ), mDefaultLightIdleMaintenanceMaxBudget);
+            mDefaultMinLightMaintenanceTime = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_min_light_maintenance_time_ms),
+                    mDefaultMinLightMaintenanceTime);
+            mDefaultMinDeepMaintenanceTime = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_min_deep_maintenance_time_ms),
+                    mDefaultMinDeepMaintenanceTime);
+            mDefaultInactiveTimeout = getTimeout(
+                    res.getInteger(com.android.internal.R.integer.device_idle_inactive_to_ms),
+                    mDefaultInactiveTimeout);
+            mDefaultSensingTimeout = getTimeout(
+                    res.getInteger(com.android.internal.R.integer.device_idle_sensing_to_ms),
+                    mDefaultSensingTimeout);
+            mDefaultLocatingTimeout = getTimeout(
+                    res.getInteger(com.android.internal.R.integer.device_idle_locating_to_ms),
+                    mDefaultLocatingTimeout);
+            mDefaultLocationAccuracy = res.getFloat(
+                    com.android.internal.R.integer.device_idle_location_accuracy);
+            mDefaultMotionInactiveTimeout = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_motion_inactive_to_ms),
+                    mDefaultMotionInactiveTimeout);
+            mDefaultMotionInactiveTimeoutFlex = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_motion_inactive_to_flex_ms),
+                    mDefaultMotionInactiveTimeoutFlex);
+            mDefaultIdleAfterInactiveTimeout = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_idle_after_inactive_to_ms),
+                    mDefaultIdleAfterInactiveTimeout);
+            mDefaultIdlePendingTimeout = getTimeout(
+                    res.getInteger(com.android.internal.R.integer.device_idle_idle_pending_to_ms),
+                    mDefaultIdlePendingTimeout);
+            mDefaultMaxIdlePendingTimeout = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_max_idle_pending_to_ms),
+                    mDefaultMaxIdlePendingTimeout);
+            mDefaultIdlePendingFactor = res.getFloat(
+                    com.android.internal.R.integer.device_idle_idle_pending_factor);
+            mDefaultQuickDozeDelayTimeout = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_quick_doze_delay_to_ms),
+                    mDefaultQuickDozeDelayTimeout);
+            mDefaultIdleTimeout = getTimeout(
+                    res.getInteger(com.android.internal.R.integer.device_idle_idle_to_ms),
+                    mDefaultIdleTimeout);
+            mDefaultMaxIdleTimeout = getTimeout(
+                    res.getInteger(com.android.internal.R.integer.device_idle_max_idle_to_ms),
+                    mDefaultMaxIdleTimeout);
+            mDefaultIdleFactor = res.getFloat(
+                    com.android.internal.R.integer.device_idle_idle_factor);
+            mDefaultMinTimeToAlarm = getTimeout(res.getInteger(
+                    com.android.internal.R.integer.device_idle_min_time_to_alarm_ms),
+                    mDefaultMinTimeToAlarm);
+            mDefaultMaxTempAppAllowlistDurationMs = res.getInteger(
+                    com.android.internal.R.integer.device_idle_max_temp_app_allowlist_duration_ms);
+            mDefaultMmsTempAppAllowlistDurationMs = res.getInteger(
+                    com.android.internal.R.integer.device_idle_mms_temp_app_allowlist_duration_ms);
+            mDefaultSmsTempAppAllowlistDurationMs = res.getInteger(
+                    com.android.internal.R.integer.device_idle_sms_temp_app_allowlist_duration_ms);
+            mDefaultNotificationAllowlistDurationMs = res.getInteger(
+                    com.android.internal.R.integer.device_idle_notification_allowlist_duration_ms);
+            mDefaultWaitForUnlock = res.getBoolean(
+                    com.android.internal.R.bool.device_idle_wait_for_unlock);
+            mDefaultPreIdleFactorLong = res.getFloat(
+                    com.android.internal.R.integer.device_idle_pre_idle_factor_long);
+            mDefaultPreIdleFactorShort = res.getFloat(
+                    com.android.internal.R.integer.device_idle_pre_idle_factor_short);
+            mDefaultUseWindowAlarms = res.getBoolean(
+                    com.android.internal.R.bool.device_idle_use_window_alarms);
+
+            FLEX_TIME_SHORT = mDefaultFlexTimeShort;
+            LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = mDefaultLightIdleAfterInactiveTimeout;
+            LIGHT_IDLE_TIMEOUT = mDefaultLightIdleTimeout;
+            LIGHT_IDLE_FACTOR = mDefaultLightIdleFactor;
+            LIGHT_MAX_IDLE_TIMEOUT = mDefaultLightMaxIdleTimeout;
+            LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = mDefaultLightIdleMaintenanceMinBudget;
+            LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = mDefaultLightIdleMaintenanceMaxBudget;
+            MIN_LIGHT_MAINTENANCE_TIME = mDefaultMinLightMaintenanceTime;
+            MIN_DEEP_MAINTENANCE_TIME = mDefaultMinDeepMaintenanceTime;
+            INACTIVE_TIMEOUT = mDefaultInactiveTimeout;
+            SENSING_TIMEOUT = mDefaultSensingTimeout;
+            LOCATING_TIMEOUT = mDefaultLocatingTimeout;
+            LOCATION_ACCURACY = mDefaultLocationAccuracy;
+            MOTION_INACTIVE_TIMEOUT = mDefaultMotionInactiveTimeout;
+            MOTION_INACTIVE_TIMEOUT_FLEX = mDefaultMotionInactiveTimeoutFlex;
+            IDLE_AFTER_INACTIVE_TIMEOUT = mDefaultIdleAfterInactiveTimeout;
+            IDLE_PENDING_TIMEOUT = mDefaultIdlePendingTimeout;
+            MAX_IDLE_PENDING_TIMEOUT = mDefaultMaxIdlePendingTimeout;
+            IDLE_PENDING_FACTOR = mDefaultIdlePendingFactor;
+            QUICK_DOZE_DELAY_TIMEOUT = mDefaultQuickDozeDelayTimeout;
+            IDLE_TIMEOUT = mDefaultIdleTimeout;
+            MAX_IDLE_TIMEOUT = mDefaultMaxIdleTimeout;
+            IDLE_FACTOR = mDefaultIdleFactor;
+            MIN_TIME_TO_ALARM = mDefaultMinTimeToAlarm;
+            MAX_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultMaxTempAppAllowlistDurationMs;
+            MMS_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultMmsTempAppAllowlistDurationMs;
+            SMS_TEMP_APP_ALLOWLIST_DURATION_MS = mDefaultSmsTempAppAllowlistDurationMs;
+            NOTIFICATION_ALLOWLIST_DURATION_MS = mDefaultNotificationAllowlistDurationMs;
+            WAIT_FOR_UNLOCK = mDefaultWaitForUnlock;
+            PRE_IDLE_FACTOR_LONG = mDefaultPreIdleFactorLong;
+            PRE_IDLE_FACTOR_SHORT = mDefaultPreIdleFactorShort;
+            USE_WINDOW_ALARMS = mDefaultUseWindowAlarms;
+        }
+
+        private long getTimeout(long defTimeout, long compTimeout) {
+            return (!COMPRESS_TIME || defTimeout < compTimeout) ? defTimeout : compTimeout;
+        }
+
 
         @Override
         public void onPropertiesChanged(DeviceConfig.Properties properties) {
@@ -1307,147 +1435,147 @@
                     switch (name) {
                         case KEY_FLEX_TIME_SHORT:
                             FLEX_TIME_SHORT = properties.getLong(
-                                    KEY_FLEX_TIME_SHORT, DEFAULT_FLEX_TIME_SHORT);
+                                    KEY_FLEX_TIME_SHORT, mDefaultFlexTimeShort);
                             break;
                         case KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT:
                             LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
                                     KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT,
-                                    DEFAULT_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT);
+                                    mDefaultLightIdleAfterInactiveTimeout);
                             break;
                         case KEY_LIGHT_IDLE_TIMEOUT:
                             LIGHT_IDLE_TIMEOUT = properties.getLong(
-                                    KEY_LIGHT_IDLE_TIMEOUT, DEFAULT_LIGHT_IDLE_TIMEOUT);
+                                    KEY_LIGHT_IDLE_TIMEOUT, mDefaultLightIdleTimeout);
                             break;
                         case KEY_LIGHT_IDLE_FACTOR:
                             LIGHT_IDLE_FACTOR = Math.max(1, properties.getFloat(
-                                    KEY_LIGHT_IDLE_FACTOR, DEFAULT_LIGHT_IDLE_FACTOR));
+                                    KEY_LIGHT_IDLE_FACTOR, mDefaultLightIdleFactor));
                             break;
                         case KEY_LIGHT_MAX_IDLE_TIMEOUT:
                             LIGHT_MAX_IDLE_TIMEOUT = properties.getLong(
-                                    KEY_LIGHT_MAX_IDLE_TIMEOUT, DEFAULT_LIGHT_MAX_IDLE_TIMEOUT);
+                                    KEY_LIGHT_MAX_IDLE_TIMEOUT, mDefaultLightMaxIdleTimeout);
                             break;
                         case KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET:
                             LIGHT_IDLE_MAINTENANCE_MIN_BUDGET = properties.getLong(
                                     KEY_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET,
-                                    DEFAULT_LIGHT_IDLE_MAINTENANCE_MIN_BUDGET);
+                                    mDefaultLightIdleMaintenanceMinBudget);
                             break;
                         case KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET:
                             LIGHT_IDLE_MAINTENANCE_MAX_BUDGET = properties.getLong(
                                     KEY_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET,
-                                    DEFAULT_LIGHT_IDLE_MAINTENANCE_MAX_BUDGET);
+                                    mDefaultLightIdleMaintenanceMaxBudget);
                             break;
                         case KEY_MIN_LIGHT_MAINTENANCE_TIME:
                             MIN_LIGHT_MAINTENANCE_TIME = properties.getLong(
                                     KEY_MIN_LIGHT_MAINTENANCE_TIME,
-                                    DEFAULT_MIN_LIGHT_MAINTENANCE_TIME);
+                                    mDefaultMinLightMaintenanceTime);
                             break;
                         case KEY_MIN_DEEP_MAINTENANCE_TIME:
                             MIN_DEEP_MAINTENANCE_TIME = properties.getLong(
                                     KEY_MIN_DEEP_MAINTENANCE_TIME,
-                                    DEFAULT_MIN_DEEP_MAINTENANCE_TIME);
+                                    mDefaultMinDeepMaintenanceTime);
                             break;
                         case KEY_INACTIVE_TIMEOUT:
                             final long defaultInactiveTimeout = mSmallBatteryDevice
                                     ? DEFAULT_INACTIVE_TIMEOUT_SMALL_BATTERY
-                                    : DEFAULT_INACTIVE_TIMEOUT;
+                                    : mDefaultInactiveTimeout;
                             INACTIVE_TIMEOUT = properties.getLong(
                                     KEY_INACTIVE_TIMEOUT, defaultInactiveTimeout);
                             break;
                         case KEY_SENSING_TIMEOUT:
                             SENSING_TIMEOUT = properties.getLong(
-                                    KEY_SENSING_TIMEOUT, DEFAULT_SENSING_TIMEOUT);
+                                    KEY_SENSING_TIMEOUT, mDefaultSensingTimeout);
                             break;
                         case KEY_LOCATING_TIMEOUT:
                             LOCATING_TIMEOUT = properties.getLong(
-                                    KEY_LOCATING_TIMEOUT, DEFAULT_LOCATING_TIMEOUT);
+                                    KEY_LOCATING_TIMEOUT, mDefaultLocatingTimeout);
                             break;
                         case KEY_LOCATION_ACCURACY:
                             LOCATION_ACCURACY = properties.getFloat(
-                                    KEY_LOCATION_ACCURACY, DEFAULT_LOCATION_ACCURACY);
+                                    KEY_LOCATION_ACCURACY, mDefaultLocationAccuracy);
                             break;
                         case KEY_MOTION_INACTIVE_TIMEOUT:
                             MOTION_INACTIVE_TIMEOUT = properties.getLong(
-                                    KEY_MOTION_INACTIVE_TIMEOUT, DEFAULT_MOTION_INACTIVE_TIMEOUT);
+                                    KEY_MOTION_INACTIVE_TIMEOUT, mDefaultMotionInactiveTimeout);
                             break;
                         case KEY_MOTION_INACTIVE_TIMEOUT_FLEX:
                             MOTION_INACTIVE_TIMEOUT_FLEX = properties.getLong(
                                     KEY_MOTION_INACTIVE_TIMEOUT_FLEX,
-                                    DEFAULT_MOTION_INACTIVE_TIMEOUT_FLEX);
+                                    mDefaultMotionInactiveTimeoutFlex);
                             break;
                         case KEY_IDLE_AFTER_INACTIVE_TIMEOUT:
                             final long defaultIdleAfterInactiveTimeout = mSmallBatteryDevice
                                     ? DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT_SMALL_BATTERY
-                                    : DEFAULT_IDLE_AFTER_INACTIVE_TIMEOUT;
+                                    : mDefaultIdleAfterInactiveTimeout;
                             IDLE_AFTER_INACTIVE_TIMEOUT = properties.getLong(
                                     KEY_IDLE_AFTER_INACTIVE_TIMEOUT,
                                     defaultIdleAfterInactiveTimeout);
                             break;
                         case KEY_IDLE_PENDING_TIMEOUT:
                             IDLE_PENDING_TIMEOUT = properties.getLong(
-                                    KEY_IDLE_PENDING_TIMEOUT, DEFAULT_IDLE_PENDING_TIMEOUT);
+                                    KEY_IDLE_PENDING_TIMEOUT, mDefaultIdlePendingTimeout);
                             break;
                         case KEY_MAX_IDLE_PENDING_TIMEOUT:
                             MAX_IDLE_PENDING_TIMEOUT = properties.getLong(
-                                    KEY_MAX_IDLE_PENDING_TIMEOUT, DEFAULT_MAX_IDLE_PENDING_TIMEOUT);
+                                    KEY_MAX_IDLE_PENDING_TIMEOUT, mDefaultMaxIdlePendingTimeout);
                             break;
                         case KEY_IDLE_PENDING_FACTOR:
                             IDLE_PENDING_FACTOR = properties.getFloat(
-                                    KEY_IDLE_PENDING_FACTOR, DEFAULT_IDLE_PENDING_FACTOR);
+                                    KEY_IDLE_PENDING_FACTOR, mDefaultIdlePendingFactor);
                             break;
                         case KEY_QUICK_DOZE_DELAY_TIMEOUT:
                             QUICK_DOZE_DELAY_TIMEOUT = properties.getLong(
-                                    KEY_QUICK_DOZE_DELAY_TIMEOUT, DEFAULT_QUICK_DOZE_DELAY_TIMEOUT);
+                                    KEY_QUICK_DOZE_DELAY_TIMEOUT, mDefaultQuickDozeDelayTimeout);
                             break;
                         case KEY_IDLE_TIMEOUT:
                             IDLE_TIMEOUT = properties.getLong(
-                                    KEY_IDLE_TIMEOUT, DEFAULT_IDLE_TIMEOUT);
+                                    KEY_IDLE_TIMEOUT, mDefaultIdleTimeout);
                             break;
                         case KEY_MAX_IDLE_TIMEOUT:
                             MAX_IDLE_TIMEOUT = properties.getLong(
-                                    KEY_MAX_IDLE_TIMEOUT, DEFAULT_MAX_IDLE_TIMEOUT);
+                                    KEY_MAX_IDLE_TIMEOUT, mDefaultMaxIdleTimeout);
                             break;
                         case KEY_IDLE_FACTOR:
-                            IDLE_FACTOR = properties.getFloat(KEY_IDLE_FACTOR, DEFAULT_IDLE_FACTOR);
+                            IDLE_FACTOR = properties.getFloat(KEY_IDLE_FACTOR, mDefaultIdleFactor);
                             break;
                         case KEY_MIN_TIME_TO_ALARM:
                             MIN_TIME_TO_ALARM = properties.getLong(
-                                    KEY_MIN_TIME_TO_ALARM, DEFAULT_MIN_TIME_TO_ALARM);
+                                    KEY_MIN_TIME_TO_ALARM, mDefaultMinTimeToAlarm);
                             break;
                         case KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS:
                             MAX_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong(
                                     KEY_MAX_TEMP_APP_ALLOWLIST_DURATION_MS,
-                                    DEFAULT_MAX_TEMP_APP_ALLOWLIST_DURATION_MS);
+                                    mDefaultMaxTempAppAllowlistDurationMs);
                             break;
                         case KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS:
                             MMS_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong(
                                     KEY_MMS_TEMP_APP_ALLOWLIST_DURATION_MS,
-                                    DEFAULT_MMS_TEMP_APP_ALLOWLIST_DURATION_MS);
+                                    mDefaultMmsTempAppAllowlistDurationMs);
                             break;
                         case KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS:
                             SMS_TEMP_APP_ALLOWLIST_DURATION_MS = properties.getLong(
                                     KEY_SMS_TEMP_APP_ALLOWLIST_DURATION_MS,
-                                    DEFAULT_SMS_TEMP_APP_ALLOWLIST_DURATION_MS);
+                                    mDefaultSmsTempAppAllowlistDurationMs);
                             break;
                         case KEY_NOTIFICATION_ALLOWLIST_DURATION_MS:
                             NOTIFICATION_ALLOWLIST_DURATION_MS = properties.getLong(
                                     KEY_NOTIFICATION_ALLOWLIST_DURATION_MS,
-                                    DEFAULT_NOTIFICATION_ALLOWLIST_DURATION_MS);
+                                    mDefaultNotificationAllowlistDurationMs);
                             break;
                         case KEY_WAIT_FOR_UNLOCK:
                             WAIT_FOR_UNLOCK = properties.getBoolean(
-                                    KEY_WAIT_FOR_UNLOCK, DEFAULT_WAIT_FOR_UNLOCK);
+                                    KEY_WAIT_FOR_UNLOCK, mDefaultWaitForUnlock);
                             break;
                         case KEY_PRE_IDLE_FACTOR_LONG:
                             PRE_IDLE_FACTOR_LONG = properties.getFloat(
-                                    KEY_PRE_IDLE_FACTOR_LONG, DEFAULT_PRE_IDLE_FACTOR_LONG);
+                                    KEY_PRE_IDLE_FACTOR_LONG, mDefaultPreIdleFactorLong);
                             break;
                         case KEY_PRE_IDLE_FACTOR_SHORT:
                             PRE_IDLE_FACTOR_SHORT = properties.getFloat(
-                                    KEY_PRE_IDLE_FACTOR_SHORT, DEFAULT_PRE_IDLE_FACTOR_SHORT);
+                                    KEY_PRE_IDLE_FACTOR_SHORT, mDefaultPreIdleFactorShort);
                             break;
                         case KEY_USE_WINDOW_ALARMS:
                             USE_WINDOW_ALARMS = properties.getBoolean(
-                                    KEY_USE_WINDOW_ALARMS, DEFAULT_USE_WINDOW_ALARMS);
+                                    KEY_USE_WINDOW_ALARMS, mDefaultUseWindowAlarms);
                             break;
                         default:
                             Slog.e(TAG, "Unknown configuration key: " + name);
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.cpp b/cmds/hid/jni/com_android_commands_hid_Device.cpp
index 2cda57d..8b8d361 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.cpp
+++ b/cmds/hid/jni/com_android_commands_hid_Device.cpp
@@ -18,24 +18,22 @@
 
 #include "com_android_commands_hid_Device.h"
 
-#include <linux/uhid.h>
-
+#include <android-base/stringprintf.h>
+#include <android/looper.h>
 #include <fcntl.h>
 #include <inttypes.h>
-#include <unistd.h>
-#include <cstdio>
-#include <cstring>
-#include <memory>
-
-#include <android/looper.h>
 #include <jni.h>
+#include <linux/uhid.h>
 #include <log/log.h>
 #include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <unistd.h>
 
-#include <android-base/stringprintf.h>
+#include <cstdio>
+#include <cstring>
+#include <memory>
 
 // Log debug messages about the output.
 static constexpr bool DEBUG_OUTPUT = false;
@@ -109,15 +107,15 @@
 
 void DeviceCallback::onDeviceGetReport(uint32_t requestId, uint8_t reportId) {
     JNIEnv* env = getJNIEnv();
-    env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceGetReport,
-            requestId, reportId);
+    env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceGetReport, requestId,
+                        reportId);
     checkAndClearException(env, "onDeviceGetReport");
 }
 
-void DeviceCallback::onDeviceSetReport(uint8_t rType,
-                                    const std::vector<uint8_t>& data) {
+void DeviceCallback::onDeviceSetReport(uint32_t id, uint8_t rType,
+                                       const std::vector<uint8_t>& data) {
     JNIEnv* env = getJNIEnv();
-    env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceSetReport, rType,
+    env->CallVoidMethod(mCallbackObject, gDeviceCallbackClassInfo.onDeviceSetReport, id, rType,
                         toJbyteArray(env, data).get());
     checkAndClearException(env, "onDeviceSetReport");
 }
@@ -236,6 +234,14 @@
     writeEvent(mFd, ev, "UHID_GET_REPORT_REPLY");
 }
 
+void Device::sendSetReportReply(uint32_t id, bool success) const {
+    struct uhid_event ev = {};
+    ev.type = UHID_SET_REPORT_REPLY;
+    ev.u.set_report_reply.id = id;
+    ev.u.set_report_reply.err = success ? 0 : EIO;
+    writeEvent(mFd, ev, "UHID_SET_REPORT_REPLY");
+}
+
 int Device::handleEvents(int events) {
     if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
         ALOGE("uhid node was closed or an error occurred. events=0x%x", events);
@@ -249,7 +255,6 @@
         mDeviceCallback->onDeviceError();
         return 0;
     }
-
     switch (ev.type) {
         case UHID_OPEN: {
             mDeviceCallback->onDeviceOpen();
@@ -271,7 +276,7 @@
                 ALOGD("Received SET_REPORT: id=%" PRIu32 " rnum=%" PRIu8 " data=%s", set_report.id,
                       set_report.rnum, toString(data).c_str());
             }
-            mDeviceCallback->onDeviceSetReport(set_report.rtype, data);
+            mDeviceCallback->onDeviceSetReport(set_report.id, set_report.rtype, data);
             break;
         }
         case UHID_OUTPUT: {
@@ -347,6 +352,15 @@
     }
 }
 
+static void sendSetReportReply(JNIEnv*, jclass /* clazz */, jlong ptr, jint id, jboolean success) {
+    uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr);
+    if (d) {
+        d->sendSetReportReply(id, success);
+    } else {
+        ALOGE("Could not send set report reply, Device* is null!");
+    }
+}
+
 static void closeDevice(JNIEnv* /* env */, jclass /* clazz */, jlong ptr) {
     uhid::Device* d = reinterpret_cast<uhid::Device*>(ptr);
     if (d) {
@@ -362,6 +376,7 @@
         {"nativeSendReport", "(J[B)V", reinterpret_cast<void*>(sendReport)},
         {"nativeSendGetFeatureReportReply", "(JI[B)V",
          reinterpret_cast<void*>(sendGetFeatureReportReply)},
+        {"nativeSendSetReportReply", "(JIZ)V", reinterpret_cast<void*>(sendSetReportReply)},
         {"nativeCloseDevice", "(J)V", reinterpret_cast<void*>(closeDevice)},
 };
 
@@ -376,7 +391,7 @@
     uhid::gDeviceCallbackClassInfo.onDeviceGetReport =
             env->GetMethodID(clazz, "onDeviceGetReport", "(II)V");
     uhid::gDeviceCallbackClassInfo.onDeviceSetReport =
-            env->GetMethodID(clazz, "onDeviceSetReport", "(B[B)V");
+            env->GetMethodID(clazz, "onDeviceSetReport", "(IB[B)V");
     uhid::gDeviceCallbackClassInfo.onDeviceOutput =
             env->GetMethodID(clazz, "onDeviceOutput", "(B[B)V");
     uhid::gDeviceCallbackClassInfo.onDeviceError =
diff --git a/cmds/hid/jni/com_android_commands_hid_Device.h b/cmds/hid/jni/com_android_commands_hid_Device.h
index d10a9aa..9c6060d 100644
--- a/cmds/hid/jni/com_android_commands_hid_Device.h
+++ b/cmds/hid/jni/com_android_commands_hid_Device.h
@@ -14,12 +14,11 @@
  * limitations under the License.
  */
 
-#include <memory>
-#include <vector>
-
+#include <android-base/unique_fd.h>
 #include <jni.h>
 
-#include <android-base/unique_fd.h>
+#include <memory>
+#include <vector>
 
 namespace android {
 namespace uhid {
@@ -31,7 +30,7 @@
 
     void onDeviceOpen();
     void onDeviceGetReport(uint32_t requestId, uint8_t reportId);
-    void onDeviceSetReport(uint8_t rType, const std::vector<uint8_t>& data);
+    void onDeviceSetReport(uint32_t id, uint8_t rType, const std::vector<uint8_t>& data);
     void onDeviceOutput(uint8_t rType, const std::vector<uint8_t>& data);
     void onDeviceError();
 
@@ -50,9 +49,9 @@
     ~Device();
 
     void sendReport(const std::vector<uint8_t>& report) const;
+    void sendSetReportReply(uint32_t id, bool success) const;
     void sendGetFeatureReportReply(uint32_t id, const std::vector<uint8_t>& report) const;
     void close();
-
     int handleEvents(int events);
 
 private:
diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java
index 95b1e9a..0415037 100644
--- a/cmds/hid/src/com/android/commands/hid/Device.java
+++ b/cmds/hid/src/com/android/commands/hid/Device.java
@@ -42,7 +42,8 @@
     private static final int MSG_OPEN_DEVICE = 1;
     private static final int MSG_SEND_REPORT = 2;
     private static final int MSG_SEND_GET_FEATURE_REPORT_REPLY = 3;
-    private static final int MSG_CLOSE_DEVICE = 4;
+    private static final int MSG_SEND_SET_REPORT_REPLY = 4;
+    private static final int MSG_CLOSE_DEVICE = 5;
 
     // Sync with linux uhid_event_type::UHID_OUTPUT
     private static final byte UHID_EVENT_TYPE_UHID_OUTPUT = 6;
@@ -56,21 +57,45 @@
     private final Map<ByteBuffer, byte[]> mOutputs;
     private final OutputStream mOutputStream;
     private long mTimeToSend;
-
     private final Object mCond = new Object();
+    /**
+     * The report id of the report received in UHID_EVENT_TYPE_SET_REPORT.
+     * Used for SET_REPORT_REPLY.
+     * This field gets overridden each time SET_REPORT is received.
+     */
+    private int mResponseId;
 
     static {
         System.loadLibrary("hidcommand_jni");
     }
 
-    private static native long nativeOpenDevice(String name, int id, int vid, int pid, int bus,
-            byte[] descriptor, DeviceCallback callback);
+    private static native long nativeOpenDevice(
+            String name,
+            int id,
+            int vid,
+            int pid,
+            int bus,
+            byte[] descriptor,
+            DeviceCallback callback);
+
     private static native void nativeSendReport(long ptr, byte[] data);
+
     private static native void nativeSendGetFeatureReportReply(long ptr, int id, byte[] data);
+
+    private static native void nativeSendSetReportReply(long ptr, int id, boolean success);
+
     private static native void nativeCloseDevice(long ptr);
 
-    public Device(int id, String name, int vid, int pid, int bus, byte[] descriptor,
-            byte[] report, SparseArray<byte[]> featureReports, Map<ByteBuffer, byte[]> outputs) {
+    public Device(
+            int id,
+            String name,
+            int vid,
+            int pid,
+            int bus,
+            byte[] descriptor,
+            byte[] report,
+            SparseArray<byte[]> featureReports,
+            Map<ByteBuffer, byte[]> outputs) {
         mId = id;
         mThread = new HandlerThread("HidDeviceHandler");
         mThread.start();
@@ -100,6 +125,17 @@
         mHandler.sendMessageAtTime(msg, mTimeToSend);
     }
 
+    public void setGetReportResponse(byte[] report) {
+        mFeatureReports.put(report[0], report);
+    }
+
+    public void sendSetReportReply(boolean success) {
+        Message msg =
+                mHandler.obtainMessage(MSG_SEND_SET_REPORT_REPLY, mResponseId, success ? 1 : 0);
+
+        mHandler.sendMessageAtTime(msg, mTimeToSend);
+    }
+
     public void addDelay(int delay) {
         mTimeToSend = Math.max(SystemClock.uptimeMillis(), mTimeToSend) + delay;
     }
@@ -111,7 +147,8 @@
             synchronized (mCond) {
                 mCond.wait();
             }
-        } catch (InterruptedException ignore) {}
+        } catch (InterruptedException ignore) {
+        }
     }
 
     private class DeviceHandler extends Handler {
@@ -127,8 +164,15 @@
             switch (msg.what) {
                 case MSG_OPEN_DEVICE:
                     SomeArgs args = (SomeArgs) msg.obj;
-                    mPtr = nativeOpenDevice((String) args.arg1, args.argi1, args.argi2, args.argi3,
-                            args.argi4, (byte[]) args.arg2, new DeviceCallback());
+                    mPtr =
+                            nativeOpenDevice(
+                                    (String) args.arg1,
+                                    args.argi1,
+                                    args.argi2,
+                                    args.argi3,
+                                    args.argi4,
+                                    (byte[]) args.arg2,
+                                    new DeviceCallback());
                     pauseEvents();
                     break;
                 case MSG_SEND_REPORT:
@@ -145,6 +189,14 @@
                         Log.e(TAG, "Tried to send feature report reply to closed device.");
                     }
                     break;
+                case MSG_SEND_SET_REPORT_REPLY:
+                    if (mPtr != 0) {
+                        final boolean success = msg.arg2 == 1;
+                        nativeSendSetReportReply(mPtr, msg.arg1, success);
+                    } else {
+                        Log.e(TAG, "Tried to send set report reply to closed device.");
+                    }
+                    break;
                 case MSG_CLOSE_DEVICE:
                     if (mPtr != 0) {
                         nativeCloseDevice(mPtr);
@@ -173,14 +225,18 @@
     }
 
     private class DeviceCallback {
+
         public void onDeviceOpen() {
             mHandler.resumeEvents();
         }
 
         public void onDeviceGetReport(int requestId, int reportId) {
             if (mFeatureReports == null) {
-                Log.e(TAG, "Received GET_REPORT request for reportId=" + reportId
-                        + ", but 'feature_reports' section is not found");
+                Log.e(
+                        TAG,
+                        "Received GET_REPORT request for reportId="
+                                + reportId
+                                + ", but 'feature_reports' section is not found");
                 return;
             }
             byte[] report = mFeatureReports.get(reportId);
@@ -220,14 +276,15 @@
             } catch (IOException e) {
                 throw new RuntimeException(e);
             }
-
         }
 
         // native callback
-        public void onDeviceSetReport(byte rtype, byte[] data) {
+        public void onDeviceSetReport(int id, byte rType, byte[] data) {
+            // Used by sendSetReportReply()
+            mResponseId = id;
             // We don't need to reply for the SET_REPORT but just send it to HID output for test
             // verification.
-            sendReportOutput(UHID_EVENT_TYPE_SET_REPORT, rtype, data);
+            sendReportOutput(UHID_EVENT_TYPE_SET_REPORT, rType, data);
         }
 
         // native callback
@@ -239,7 +296,8 @@
             }
             byte[] response = mOutputs.get(ByteBuffer.wrap(data));
             if (response == null) {
-                Log.i(TAG,
+                Log.i(
+                        TAG,
                         "Requested response for output " + Arrays.toString(data) + " is not found");
                 return;
             }
diff --git a/cmds/hid/src/com/android/commands/hid/Event.java b/cmds/hid/src/com/android/commands/hid/Event.java
index d4bf1d8..3efb797 100644
--- a/cmds/hid/src/com/android/commands/hid/Event.java
+++ b/cmds/hid/src/com/android/commands/hid/Event.java
@@ -35,6 +35,8 @@
     public static final String COMMAND_REGISTER = "register";
     public static final String COMMAND_DELAY = "delay";
     public static final String COMMAND_REPORT = "report";
+    public static final String COMMAND_SET_GET_REPORT_RESPONSE = "set_get_report_response";
+    public static final String COMMAND_SEND_SET_REPORT_REPLY = "send_set_report_reply";
 
     // These constants come from "include/uapi/linux/input.h" in the kernel
     enum Bus {
@@ -62,6 +64,7 @@
     private SparseArray<byte[]> mFeatureReports;
     private Map<ByteBuffer, byte[]> mOutputs;
     private int mDuration;
+    private Boolean mReply;
 
     public int getId() {
         return mId;
@@ -107,6 +110,10 @@
         return mDuration;
     }
 
+    public Boolean getReply() {
+        return mReply;
+    }
+
     public String toString() {
         return "Event{id=" + mId
             + ", command=" + String.valueOf(mCommand)
@@ -119,6 +126,7 @@
             + ", feature_reports=" + mFeatureReports.toString()
             + ", outputs=" + mOutputs.toString()
             + ", duration=" + mDuration
+            + ", success=" + mReply.toString()
             + "}";
     }
 
@@ -173,6 +181,10 @@
             mEvent.mDuration = duration;
         }
 
+        public void setReply(boolean success) {
+            mEvent.mReply = success;
+        }
+
         public Event build() {
             if (mEvent.mId == -1) {
                 throw new IllegalStateException("No event id");
@@ -183,6 +195,16 @@
                 if (mEvent.mDescriptor == null) {
                     throw new IllegalStateException("Device registration is missing descriptor");
                 }
+            }
+            if (COMMAND_SET_GET_REPORT_RESPONSE.equals(mEvent.mCommand)) {
+                if (mEvent.mReport == null) {
+                    throw new IllegalStateException("Report command is missing response data");
+                }
+            }
+            if (COMMAND_SEND_SET_REPORT_REPLY.equals(mEvent.mCommand)) {
+                if (mEvent.mReply == null) {
+                    throw new IllegalStateException("Reply command is missing reply");
+                }
             } else if (COMMAND_DELAY.equals(mEvent.mCommand)) {
                 if (mEvent.mDuration <= 0) {
                     throw new IllegalStateException("Delay has missing or invalid duration");
@@ -246,6 +268,9 @@
                             case "duration":
                                 eb.setDuration(readInt());
                                 break;
+                            case "success":
+                                eb.setReply(readBool());
+                                break;
                             default:
                                 mReader.skipValue();
                         }
@@ -292,6 +317,11 @@
             return Integer.decode(val);
         }
 
+        private boolean readBool() throws IOException {
+            String val = mReader.nextString();
+            return Boolean.parseBoolean(val);
+        }
+
         private Bus readBus() throws IOException {
             String val = mReader.nextString();
             return Bus.valueOf(val.toUpperCase());
diff --git a/cmds/hid/src/com/android/commands/hid/Hid.java b/cmds/hid/src/com/android/commands/hid/Hid.java
index fac0ab2..2db791fe 100644
--- a/cmds/hid/src/com/android/commands/hid/Hid.java
+++ b/cmds/hid/src/com/android/commands/hid/Hid.java
@@ -93,6 +93,10 @@
                 d.addDelay(e.getDuration());
             } else if (Event.COMMAND_REPORT.equals(e.getCommand())) {
                 d.sendReport(e.getReport());
+            } else if (Event.COMMAND_SET_GET_REPORT_RESPONSE.equals(e.getCommand())) {
+                d.setGetReportResponse(e.getReport());
+            } else if (Event.COMMAND_SEND_SET_REPORT_REPLY.equals(e.getCommand())) {
+                d.sendSetReportReply(e.getReply());
             } else {
                 if (Event.COMMAND_REGISTER.equals(e.getCommand())) {
                     error("Device id=" + e.getId() + " is already registered. Ignoring event.");
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index ae8809d..bbcf138 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -7836,7 +7836,7 @@
                         Files.move(new File(oldPath).toPath(), new File(newPath).toPath(),
                                 StandardCopyOption.REPLACE_EXISTING);
                     } catch (IOException e2) {
-                        Log.e(TAG, "Rename recovery failed ", e);
+                        Log.e(TAG, "Rename recovery failed ", e2);
                         throw e;
                     }
                 } else {
diff --git a/core/java/android/ddm/OWNERS b/core/java/android/ddm/OWNERS
new file mode 100644
index 0000000..369025b
--- /dev/null
+++ b/core/java/android/ddm/OWNERS
@@ -0,0 +1 @@
+per-file DdmHandleViewDebug.java = michschn@google.com
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index 7379443..d03a87d 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -352,7 +352,7 @@
                 }
                 long currentNanos = elapsedRealtimeNanos();
                 long deltaMs = (currentNanos - time.getElapsedRealtimeNanos()) / 1000000L;
-                return time.getTime() + deltaMs;
+                return time.getUnixEpochTimeMillis() + deltaMs;
             }
         };
     }
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 0a6a405..2c0be87 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -541,7 +541,8 @@
         }
 
         public void postUpdateSlider(int volume, int lastAudibleVolume, boolean mute) {
-            obtainMessage(UPDATE_SLIDER, volume, lastAudibleVolume, new Boolean(mute)).sendToTarget();
+            obtainMessage(UPDATE_SLIDER, volume, lastAudibleVolume, Boolean.valueOf(mute))
+                    .sendToTarget();
         }
     }
 
diff --git a/core/java/android/security/keymaster/OWNERS b/core/java/android/security/keymaster/OWNERS
index 65129a4..c4d605c 100644
--- a/core/java/android/security/keymaster/OWNERS
+++ b/core/java/android/security/keymaster/OWNERS
@@ -1,5 +1,5 @@
 # Bug component: 189335
 
 swillden@google.com
-jdanis@google.com
+eranm@google.com
 jbires@google.com
diff --git a/core/java/android/text/format/DateFormat.java b/core/java/android/text/format/DateFormat.java
index 537dffc..d48d566 100755
--- a/core/java/android/text/format/DateFormat.java
+++ b/core/java/android/text/format/DateFormat.java
@@ -170,7 +170,7 @@
      * mean using 12-hour in some locales and, in this case, is duplicated as the 'a' field.
      */
     @ChangeId
-    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT)
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
     static final long DISALLOW_DUPLICATE_FIELD_IN_SKELETON = 170233598L;
 
     /**
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index ea5f0b2..b1e7d15 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -1001,24 +1001,16 @@
     }
 
     /**
-     * This will enable jdwp by default for all apps. It is OK to cache this property
-     * because we expect to reboot the system whenever this property changes
-     */
-    private static final boolean ENABLE_JDWP = SystemProperties.get(
-                          "persist.debuggable.dalvik.vm.jdwp.enabled").equals("1");
-
-    /**
      * Applies debugger system properties to the zygote arguments.
      *
-     * For eng builds all apps are debuggable. On userdebug and user builds
-     * if persist.debuggable.dalvik.vm.jdwp.enabled is 1 all apps are
-     * debuggable. Otherwise, the debugger state is specified via the
-     * "--enable-jdwp" flag in the spawn request.
+     * If "ro.debuggable" is "1", all apps are debuggable. Otherwise,
+     * the debugger state is specified via the "--enable-jdwp" flag
+     * in the spawn request.
      *
      * @param args non-null; zygote spawner args
      */
     static void applyDebuggerSystemProperty(ZygoteArguments args) {
-        if (Build.IS_ENG || ENABLE_JDWP) {
+        if (RoSystemProperties.DEBUGGABLE) {
             args.mRuntimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
         }
     }
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 14699e7..a068008 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -22,7 +22,7 @@
 # WindowManager
 per-file android_graphics_BLASTBufferQueue.cpp = file:/services/core/java/com/android/server/wm/OWNERS
 per-file android_view_Surface* = file:/services/core/java/com/android/server/wm/OWNERS
-per-file android_window_WindowInfosListener.cpp = file:/services/core/java/com/android/server/wm/OWNERS
+per-file android_window_* = file:/services/core/java/com/android/server/wm/OWNERS
 
 # Resources
 per-file android_content_res_* = file:/core/java/android/content/res/OWNERS
diff --git a/core/res/OWNERS b/core/res/OWNERS
index c54638a..22f40a1 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -36,8 +36,11 @@
 # Car
 per-file res/values/dimens_car.xml = file:/platform/packages/services/Car:/OWNERS
 
+# Device Idle
+per-file res/values/config_device_idle.xml = file:/apex/jobscheduler/OWNERS
+
 # Wear
-per-file res/*-watch/* = file:/platform/frameworks/opt/wear:/OWNERS
+per-file res/*-watch/* = file:/WEAR_OWNERS
 
 # PowerProfile
 per-file res/xml/power_profile.xml = file:/BATTERY_STATS_OWNERS
diff --git a/core/res/res/values/config_device_idle.xml b/core/res/res/values/config_device_idle.xml
new file mode 100644
index 0000000..8ed58f3
--- /dev/null
+++ b/core/res/res/values/config_device_idle.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<!-- These resources are around just to allow their values to be customized
+     for different hardware and product builds.  Do not translate.
+
+     NOTE: The naming convention is "config_camelCaseValue". Some legacy
+     entries do not follow the convention, but all new entries should. -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Default for DeviceIdleController.Constants.FLEX_TIME_SHORT -->
+    <integer name="device_idle_flex_time_short_ms">60000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT -->
+    <integer name="device_idle_light_after_inactive_to_ms">180000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_TIMEOUT -->
+    <integer name="device_idle_light_idle_to_ms">300000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_FACTOR -->
+    <item name="device_idle_light_idle_factor" format="float" type="integer">2.0</item>
+
+    <!-- Default for DeviceIdleController.Constants.LIGHT_MAX_IDLE_TIMEOUT -->
+    <integer name="device_idle_light_max_idle_to_ms">900000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_MAINTENANCE_MIN_BUDGET -->
+    <integer name="device_idle_light_idle_maintenance_min_budget_ms">60000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.LIGHT_IDLE_MAINTENANCE_MAX_BUDGET -->
+    <integer name="device_idle_light_idle_maintenance_max_budget_ms">300000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.MIN_LIGHT_MAINTENANCE_TIME -->
+    <integer name="device_idle_min_light_maintenance_time_ms">5000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.MIN_DEEP_MAINTENANCE_TIME -->
+    <integer name="device_idle_min_deep_maintenance_time_ms">30000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.INACTIVE_TIMEOUT -->
+    <integer name="device_idle_inactive_to_ms">1800000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.SENSING_TIMEOUT -->
+    <integer name="device_idle_sensing_to_ms">240000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.LOCATING_TIMEOUT -->
+    <integer name="device_idle_locating_to_ms">30000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.LOCATION_ACCURACY -->
+    <item name="device_idle_location_accuracy" format="float" type="integer">20.0</item>
+
+    <!-- Default for DeviceIdleController.Constants.MOTION_INACTIVE_TIMEOUT -->
+    <integer name="device_idle_motion_inactive_to_ms">600000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.MOTION_INACTIVE_TIMEOUT_FLEX -->
+    <integer name="device_idle_motion_inactive_to_flex_ms">60000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.IDLE_AFTER_INACTIVE_TIMEOUT -->
+    <integer name="device_idle_idle_after_inactive_to_ms">1800000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.IDLE_PENDING_TIMEOUT -->
+    <integer name="device_idle_idle_pending_to_ms">300000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.MAX_IDLE_PENDING_TIMEOUT -->
+    <integer name="device_idle_max_idle_pending_to_ms">600000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.IDLE_PENDING_FACTOR -->
+    <item name="device_idle_idle_pending_factor" format="float" type="integer">2.0</item>
+
+    <!-- Default for DeviceIdleController.Constants.QUICK_DOZE_DELAY_TIMEOUT -->
+    <integer name="device_idle_quick_doze_delay_to_ms">60000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.IDLE_TIMEOUT -->
+    <integer name="device_idle_idle_to_ms">3600000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.MAX_IDLE_TIMEOUT -->
+    <integer name="device_idle_max_idle_to_ms">21600000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.IDLE_FACTOR -->
+    <item name="device_idle_idle_factor" format="float" type="integer">2.0</item>
+
+    <!-- Default for DeviceIdleController.Constants.MIN_TIME_TO_ALARM -->
+    <integer name="device_idle_min_time_to_alarm_ms">3600000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.MAX_TEMP_APP_ALLOWLIST_DURATION_MS -->
+    <integer name="device_idle_max_temp_app_allowlist_duration_ms">300000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.MMS_TEMP_APP_ALLOWLIST_DURATION_MS -->
+    <integer name="device_idle_mms_temp_app_allowlist_duration_ms">60000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.SMS_TEMP_APP_ALLOWLIST_DURATION_MS -->
+    <integer name="device_idle_sms_temp_app_allowlist_duration_ms">20000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.NOTIFICATION_ALLOWLIST_DURATION_MS -->
+    <integer name="device_idle_notification_allowlist_duration_ms">30000</integer>
+
+    <!-- Default for DeviceIdleController.Constants.WAIT_FOR_UNLOCK -->
+    <bool name="device_idle_wait_for_unlock">true</bool>
+
+    <!-- Default for DeviceIdleController.Constants.PRE_IDLE_FACTOR_LONG -->
+    <item name="device_idle_pre_idle_factor_long" format="float" type="integer">1.67</item>
+
+    <!-- Default for DeviceIdleController.Constants.PRE_IDLE_FACTOR_SHORT -->
+    <item name="device_idle_pre_idle_factor_short" format="float" type="integer">0.33</item>
+
+    <!-- Default for DeviceIdleController.Constants.USE_WINDOW_ALARMS -->
+    <bool name="device_idle_use_window_alarms">true</bool>
+</resources>
+
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e2f29ef..dc09c4c 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4349,6 +4349,40 @@
 
   <java-symbol type="array" name="config_notificationMsgPkgsAllowedAsConvos" />
 
+  <!-- To config device idle -->
+  <java-symbol type="integer" name="device_idle_flex_time_short_ms" />
+  <java-symbol type="integer" name="device_idle_light_after_inactive_to_ms" />
+  <java-symbol type="integer" name="device_idle_light_idle_to_ms" />
+  <java-symbol type="integer" name="device_idle_light_idle_factor" />
+  <java-symbol type="integer" name="device_idle_light_max_idle_to_ms" />
+  <java-symbol type="integer" name="device_idle_light_idle_maintenance_min_budget_ms" />
+  <java-symbol type="integer" name="device_idle_light_idle_maintenance_max_budget_ms" />
+  <java-symbol type="integer" name="device_idle_min_light_maintenance_time_ms" />
+  <java-symbol type="integer" name="device_idle_min_deep_maintenance_time_ms" />
+  <java-symbol type="integer" name="device_idle_inactive_to_ms" />
+  <java-symbol type="integer" name="device_idle_sensing_to_ms" />
+  <java-symbol type="integer" name="device_idle_locating_to_ms" />
+  <java-symbol type="integer" name="device_idle_location_accuracy" />
+  <java-symbol type="integer" name="device_idle_motion_inactive_to_ms" />
+  <java-symbol type="integer" name="device_idle_motion_inactive_to_flex_ms" />
+  <java-symbol type="integer" name="device_idle_idle_after_inactive_to_ms" />
+  <java-symbol type="integer" name="device_idle_idle_pending_to_ms" />
+  <java-symbol type="integer" name="device_idle_max_idle_pending_to_ms" />
+  <java-symbol type="integer" name="device_idle_idle_pending_factor" />
+  <java-symbol type="integer" name="device_idle_quick_doze_delay_to_ms" />
+  <java-symbol type="integer" name="device_idle_idle_to_ms" />
+  <java-symbol type="integer" name="device_idle_max_idle_to_ms" />
+  <java-symbol type="integer" name="device_idle_idle_factor" />
+  <java-symbol type="integer" name="device_idle_min_time_to_alarm_ms" />
+  <java-symbol type="integer" name="device_idle_max_temp_app_allowlist_duration_ms" />
+  <java-symbol type="integer" name="device_idle_mms_temp_app_allowlist_duration_ms" />
+  <java-symbol type="integer" name="device_idle_sms_temp_app_allowlist_duration_ms" />
+  <java-symbol type="integer" name="device_idle_notification_allowlist_duration_ms" />
+  <java-symbol type="bool" name="device_idle_wait_for_unlock" />
+  <java-symbol type="integer" name="device_idle_pre_idle_factor_long" />
+  <java-symbol type="integer" name="device_idle_pre_idle_factor_short" />
+  <java-symbol type="bool" name="device_idle_use_window_alarms" />
+
   <!-- Binder heavy hitter watcher configs -->
   <java-symbol type="bool" name="config_defaultBinderHeavyHitterWatcherEnabled" />
   <java-symbol type="integer" name="config_defaultBinderHeavyHitterWatcherBatchSize" />
diff --git a/core/tests/coretests/src/android/ddm/OWNERS b/core/tests/coretests/src/android/ddm/OWNERS
new file mode 100644
index 0000000..c8be191
--- /dev/null
+++ b/core/tests/coretests/src/android/ddm/OWNERS
@@ -0,0 +1 @@
+michschn@google.com
diff --git a/location/java/android/location/LocationTime.java b/location/java/android/location/LocationTime.java
index e5535d1..2f03508 100644
--- a/location/java/android/location/LocationTime.java
+++ b/location/java/android/location/LocationTime.java
@@ -20,28 +20,32 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.time.Duration;
+import java.time.Instant;
+
 /**
- * Data class for passing location derived time.
+ * Data class for passing GNSS-derived time.
  * @hide
  */
 public final class LocationTime implements Parcelable {
 
-    private final long mTime;
+    private final long mUnixEpochTimeMillis;
     private final long mElapsedRealtimeNanos;
 
-    public LocationTime(long time, long elapsedRealtimeNanos) {
-        mTime = time;
+    public LocationTime(long unixEpochTimeMillis, long elapsedRealtimeNanos) {
+        mUnixEpochTimeMillis = unixEpochTimeMillis;
         mElapsedRealtimeNanos = elapsedRealtimeNanos;
     }
 
     /**
-     * The current time, according to the Gnss location provider. */
-    public long getTime() {
-        return mTime;
+     * The Unix epoch time in millis, according to the Gnss location provider.
+     */
+    public long getUnixEpochTimeMillis() {
+        return mUnixEpochTimeMillis;
     }
 
     /**
-     * The elapsed nanos since boot {@link #getTime} was computed at.
+     * The elapsed nanos since boot when {@link #getUnixEpochTimeMillis} was the current time.
      */
     public long getElapsedRealtimeNanos() {
         return mElapsedRealtimeNanos;
@@ -49,7 +53,7 @@
 
     @Override
     public void writeToParcel(Parcel out, int flags) {
-        out.writeLong(mTime);
+        out.writeLong(mUnixEpochTimeMillis);
         out.writeLong(mElapsedRealtimeNanos);
     }
 
@@ -58,8 +62,18 @@
         return 0;
     }
 
+    @Override
+    public String toString() {
+        return "LocationTime{"
+                + "mUnixEpochTimeMillis=" + Instant.ofEpochMilli(mUnixEpochTimeMillis)
+                + "(" + mUnixEpochTimeMillis + ")"
+                + ", mElapsedRealtimeNanos=" + Duration.ofNanos(mElapsedRealtimeNanos)
+                + "(" + mElapsedRealtimeNanos + ")"
+                + '}';
+    }
+
     public static final @NonNull Parcelable.Creator<LocationTime> CREATOR =
-            new Parcelable.Creator<LocationTime>() {
+            new Parcelable.Creator<>() {
                 public LocationTime createFromParcel(Parcel in) {
                     long time = in.readLong();
                     long elapsedRealtimeNanos = in.readLong();
diff --git a/media/jni/audioeffect/Android.bp b/media/jni/audioeffect/Android.bp
index 2ddfacf..8b5b726 100644
--- a/media/jni/audioeffect/Android.bp
+++ b/media/jni/audioeffect/Android.bp
@@ -28,7 +28,7 @@
         "libaudioclient",
         "libaudioutils",
         "libaudiofoundation",
-        "libbinder"
+        "libbinder",
     ],
 
     export_shared_lib_headers: [
@@ -42,6 +42,7 @@
         "-Werror",
         "-Wunused",
         "-Wunreachable-code",
+        "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
     ],
 
     // Workaround Clang LTO crash.
diff --git a/media/jni/audioeffect/Visualizer.cpp b/media/jni/audioeffect/Visualizer.cpp
index d0f1ec6..09c45ea 100644
--- a/media/jni/audioeffect/Visualizer.cpp
+++ b/media/jni/audioeffect/Visualizer.cpp
@@ -142,7 +142,8 @@
     mCaptureRate = rate;
 
     if (cbk != NULL) {
-        mCaptureThread = new CaptureThread(this, rate, ((flags & CAPTURE_CALL_JAVA) != 0));
+        mCaptureThread = sp<CaptureThread>::make(
+                sp<Visualizer>::fromExisting(this), rate, ((flags & CAPTURE_CALL_JAVA) != 0));
     }
     ALOGV("setCaptureCallBack() rate: %d thread %p flags 0x%08x",
             rate, mCaptureThread.get(), mCaptureFlags);
@@ -439,7 +440,7 @@
 
 //-------------------------------------------------------------------------
 
-Visualizer::CaptureThread::CaptureThread(Visualizer* receiver, uint32_t captureRate,
+Visualizer::CaptureThread::CaptureThread(const sp<Visualizer>& receiver, uint32_t captureRate,
         bool bCanCallJava)
     : Thread(bCanCallJava), mReceiver(receiver)
 {
diff --git a/media/jni/audioeffect/Visualizer.h b/media/jni/audioeffect/Visualizer.h
index 3d5d74a..b38c01f 100644
--- a/media/jni/audioeffect/Visualizer.h
+++ b/media/jni/audioeffect/Visualizer.h
@@ -157,7 +157,8 @@
     class CaptureThread : public Thread
     {
     public:
-        CaptureThread(Visualizer* visualizer, uint32_t captureRate, bool bCanCallJava = false);
+        CaptureThread(const sp<Visualizer>& visualizer,
+                uint32_t captureRate, bool bCanCallJava = false);
 
     private:
         friend class Visualizer;
diff --git a/media/jni/audioeffect/android_media_AudioEffect.cpp b/media/jni/audioeffect/android_media_AudioEffect.cpp
index 2fb85a7..63e48aa 100644
--- a/media/jni/audioeffect/android_media_AudioEffect.cpp
+++ b/media/jni/audioeffect/android_media_AudioEffect.cpp
@@ -205,15 +205,15 @@
     Mutex::Autolock l(sLock);
     AudioEffect* const ae =
             (AudioEffect*)env->GetLongField(thiz, fields.fidNativeAudioEffect);
-    return sp<AudioEffect>(ae);
+    return sp<AudioEffect>::fromExisting(ae);
 }
 
 static sp<AudioEffect> setAudioEffect(JNIEnv* env, jobject thiz,
                                     const sp<AudioEffect>& ae)
 {
     Mutex::Autolock l(sLock);
-    sp<AudioEffect> old =
-            (AudioEffect*)env->GetLongField(thiz, fields.fidNativeAudioEffect);
+    sp<AudioEffect> old = sp<AudioEffect>::fromExisting(
+            (AudioEffect*)env->GetLongField(thiz, fields.fidNativeAudioEffect));
     if (ae.get()) {
         ae->incStrong((void*)setAudioEffect);
     }
@@ -347,8 +347,8 @@
     // create the native AudioEffect object
     parcel = parcelForJavaObject(env, jAttributionSource);
     attributionSource.readFromParcel(parcel);
-    lpAudioEffect = new AudioEffect(attributionSource);
-    if (lpAudioEffect == 0) {
+    lpAudioEffect = sp<AudioEffect>::make(attributionSource);
+    if (lpAudioEffect == 0) {  // FIXME: I don't think this is actually possible.
         ALOGE("Error creating AudioEffect");
         goto setup_failure;
     }
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index 7b00f93..8cd6dfa 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -251,15 +251,15 @@
     Mutex::Autolock l(sLock);
     Visualizer* const v =
             (Visualizer*)env->GetLongField(thiz, fields.fidNativeVisualizer);
-    return sp<Visualizer>(v);
+    return sp<Visualizer>::fromExisting(v);
 }
 
 static sp<Visualizer> setVisualizer(JNIEnv* env, jobject thiz,
                                     const sp<Visualizer>& v)
 {
     Mutex::Autolock l(sLock);
-    sp<Visualizer> old =
-            (Visualizer*)env->GetLongField(thiz, fields.fidNativeVisualizer);
+    sp<Visualizer> old = sp<Visualizer>::fromExisting(
+            (Visualizer*)env->GetLongField(thiz, fields.fidNativeVisualizer));
     if (v.get()) {
         v->incStrong((void*)setVisualizer);
     }
diff --git a/packages/SettingsLib/search/Android.bp b/packages/SettingsLib/search/Android.bp
index 45746d9..cfff519 100644
--- a/packages/SettingsLib/search/Android.bp
+++ b/packages/SettingsLib/search/Android.bp
@@ -19,11 +19,11 @@
     name: "SettingsLib-annotation-processor",
     processor_class: "com.android.settingslib.search.IndexableProcessor",
     static_libs: [
-        "javapoet-prebuilt-jar",
+        "javapoet",
     ],
     srcs: [
         "processor-src/**/*.java",
-        "src/com/android/settingslib/search/SearchIndexable.java"
+        "src/com/android/settingslib/search/SearchIndexable.java",
     ],
     java_resource_dirs: ["resources"],
 }
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 431be88..676dc19 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -99,6 +99,7 @@
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.FileUtils;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.INetworkManagementService;
 import android.os.Looper;
@@ -2784,26 +2785,18 @@
             // When restricted to test networks, select any network with TRANSPORT_TEST. Since the
             // creator of the profile and the test network creator both have MANAGE_TEST_NETWORKS,
             // this is considered safe.
-            final NetworkRequest req;
 
             if (mProfile.isRestrictedToTestNetworks()) {
-                req = new NetworkRequest.Builder()
+                final NetworkRequest req = new NetworkRequest.Builder()
                         .clearCapabilities()
                         .addTransportType(NetworkCapabilities.TRANSPORT_TEST)
                         .addCapability(NET_CAPABILITY_NOT_VPN)
                         .build();
+                mConnectivityManager.requestNetwork(req, mNetworkCallback);
             } else {
-                // Basically, the request here is referring to the default request which is defined
-                // in ConnectivityService. Ideally, ConnectivityManager should provide an new API
-                // which can provide the status of physical network even though there is a virtual
-                // network. b/147280869 is used for tracking the new API.
-                // TODO: Use the new API to register default physical network.
-                req = new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build();
+                mConnectivityManager.registerSystemDefaultNetworkCallback(mNetworkCallback,
+                        new Handler(mLooper));
             }
-
-            mConnectivityManager.requestNetwork(req, mNetworkCallback);
         }
 
         private boolean isActiveNetwork(@Nullable Network network) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 8ecc607..5544669 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -1009,7 +1009,9 @@
                 }
                 opti++;
 
-                if ("-h".equals(opt)) {
+                if ("-a".equals(opt)) {
+                    // dumpsys will pass in -a; silently ignore it
+                } else if ("-h".equals(opt)) {
                     pw.println("dump [-h] [--verbose] [--user USER_ID] [[FIELD] PACKAGE]");
                     pw.println("  Print debugging information about the overlay manager.");
                     pw.println("  With optional parameter PACKAGE, limit output to the specified");
diff --git a/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java b/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
index 129810c..6949191 100644
--- a/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/GnssTimeUpdateService.java
@@ -18,21 +18,26 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.app.AlarmManager;
 import android.app.timedetector.GnssTimeSuggestion;
 import android.app.timedetector.TimeDetector;
 import android.content.Context;
-import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
 import android.location.LocationManagerInternal;
 import android.location.LocationRequest;
 import android.location.LocationTime;
 import android.os.Binder;
+import android.os.Handler;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
 import android.os.SystemClock;
 import android.os.TimestampedValue;
+import android.util.LocalLog;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.DumpUtils;
 import com.android.server.FgThread;
@@ -42,6 +47,8 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.time.Duration;
+import java.util.Objects;
+import java.util.concurrent.Executor;
 
 /**
  * Monitors the GNSS time.
@@ -66,7 +73,15 @@
 
         @Override
         public void onStart() {
-            mService = new GnssTimeUpdateService(getContext());
+            Context context = getContext().createAttributionContext(ATTRIBUTION_TAG);
+            AlarmManager alarmManager = context.getSystemService(AlarmManager.class);
+            LocationManager locationManager = context.getSystemService(LocationManager.class);
+            LocationManagerInternal locationManagerInternal =
+                    LocalServices.getService(LocationManagerInternal.class);
+            TimeDetector timeDetector = context.getSystemService(TimeDetector.class);
+
+            mService = new GnssTimeUpdateService(context, alarmManager, locationManager,
+                    locationManagerInternal, timeDetector);
             publishBinderService("gnss_time_update_service", mService);
         }
 
@@ -79,7 +94,7 @@
                 // Instead of polling GNSS time periodically, passive location updates are enabled.
                 // Once an update is received, the gnss time will be queried and suggested to
                 // TimeDetectorService.
-                mService.requestGnssTimeUpdates();
+                mService.startGnssListeningInternal();
             }
         }
     }
@@ -87,107 +102,170 @@
     private static final Duration GNSS_TIME_UPDATE_ALARM_INTERVAL = Duration.ofHours(4);
     private static final String ATTRIBUTION_TAG = "GnssTimeUpdateService";
 
+    /**
+     * A log that records the decisions to fetch a GNSS time update.
+     * This is logged in bug reports to assist with debugging issues with GNSS time suggestions.
+     */
+    private final LocalLog mLocalLog = new LocalLog(10, false /* useLocalTimestamps */);
+    /** The executor used for async operations */
+    private final Executor mExecutor = FgThread.getExecutor();
+    /** The handler used for async operations */
+    private final Handler mHandler = FgThread.getHandler();
+
     private final Context mContext;
     private final TimeDetector mTimeDetector;
     private final AlarmManager mAlarmManager;
     private final LocationManager mLocationManager;
     private final LocationManagerInternal mLocationManagerInternal;
 
-    @Nullable private AlarmManager.OnAlarmListener mAlarmListener;
-    @Nullable private LocationListener mLocationListener;
-    @Nullable private TimestampedValue<Long> mLastSuggestedGnssTime;
+
+    private final Object mLock = new Object();
+    @GuardedBy("mLock") @Nullable private AlarmManager.OnAlarmListener mAlarmListener;
+    @GuardedBy("mLock") @Nullable private LocationListener mLocationListener;
+
+    @Nullable private volatile TimestampedValue<Long> mLastSuggestedGnssTime;
 
     @VisibleForTesting
-    GnssTimeUpdateService(@NonNull Context context) {
-        mContext = context.createAttributionContext(ATTRIBUTION_TAG);
-        mTimeDetector = mContext.getSystemService(TimeDetector.class);
-        mLocationManager = mContext.getSystemService(LocationManager.class);
-        mAlarmManager = mContext.getSystemService(AlarmManager.class);
-        mLocationManagerInternal = LocalServices.getService(LocationManagerInternal.class);
+    GnssTimeUpdateService(@NonNull Context context, @NonNull AlarmManager alarmManager,
+            @NonNull LocationManager locationManager,
+            @NonNull LocationManagerInternal locationManagerInternal,
+            @NonNull TimeDetector timeDetector) {
+        mContext = Objects.requireNonNull(context);
+        mAlarmManager = Objects.requireNonNull(alarmManager);
+        mLocationManager = Objects.requireNonNull(locationManager);
+        mLocationManagerInternal = Objects.requireNonNull(locationManagerInternal);
+        mTimeDetector = Objects.requireNonNull(timeDetector);
     }
 
     /**
-     * Request passive location updates. Such a request will not trigger any active locations or
-     * power usage itself.
+     * Used by {@link com.android.server.timedetector.GnssTimeUpdateServiceShellCommand} to force
+     * the service into GNSS listening mode.
+     */
+    @RequiresPermission(android.Manifest.permission.SET_TIME)
+    boolean startGnssListening() {
+        mContext.enforceCallingPermission(
+                android.Manifest.permission.SET_TIME, "Start GNSS listening");
+        mLocalLog.log("startGnssListening() called");
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return startGnssListeningInternal();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    /**
+     * Starts listening for passive location updates. Such a request will not trigger any active
+     * locations or power usage itself. Returns {@code true} if the service is listening after the
+     * method returns and {@code false} otherwise. At present this method only returns {@code false}
+     * if there is no GPS provider on the device.
+     *
+     * <p>If the service is already listening for locations this is a no-op. If the device is in a
+     * "sleeping" state between listening periods then it will return to listening.
      */
     @VisibleForTesting
-    void requestGnssTimeUpdates() {
-        if (D) {
-            Log.d(TAG, "requestGnssTimeUpdates()");
+    boolean startGnssListeningInternal() {
+        if (!mLocationManager.hasProvider(LocationManager.GPS_PROVIDER)) {
+            logError("GPS provider does not exist on this device");
+            return false;
         }
 
-        if (!mLocationManager.hasProvider(LocationManager.GPS_PROVIDER)) {
-            Log.e(TAG, "GPS provider does not exist on this device");
-            return;
+        synchronized (mLock) {
+            if (mLocationListener != null) {
+                logDebug("Already listening for GNSS updates");
+                return true;
+            }
+
+            // If startGnssListening() is called during manual tests to jump back into location
+            // listening then there will usually be an alarm set.
+            if (mAlarmListener != null) {
+                mAlarmManager.cancel(mAlarmListener);
+                mAlarmListener = null;
+            }
+
+            startGnssListeningLocked();
+            return true;
         }
+    }
+
+    @GuardedBy("mLock")
+    private void startGnssListeningLocked() {
+        logDebug("startGnssListeningLocked()");
 
         // Location Listener triggers onLocationChanged() when GNSS data is available, so
         // that the getGnssTimeMillis() function doesn't need to be continuously polled.
-        mLocationListener = new LocationListener() {
-            @Override
-            public void onLocationChanged(Location location) {
-                if (D) {
-                    Log.d(TAG, "onLocationChanged()");
-                }
-
-                // getGnssTimeMillis() can return null when the Master Location Switch for the
-                // foreground user is disabled.
-                LocationTime locationTime = mLocationManagerInternal.getGnssTimeMillis();
-                if (locationTime != null) {
-                    suggestGnssTime(locationTime);
-                } else {
-                    if (D) {
-                        Log.d(TAG, "getGnssTimeMillis() returned null");
-                    }
-                }
-
-                mLocationManager.removeUpdates(mLocationListener);
-                mLocationListener = null;
-
-                mAlarmListener = new AlarmManager.OnAlarmListener() {
-                    @Override
-                    public void onAlarm() {
-                        if (D) {
-                            Log.d(TAG, "onAlarm()");
-                        }
-                        mAlarmListener = null;
-                        requestGnssTimeUpdates();
-                    }
-                };
-
-                // Set next alarm to re-enable location updates.
-                long next = SystemClock.elapsedRealtime()
-                        + GNSS_TIME_UPDATE_ALARM_INTERVAL.toMillis();
-                mAlarmManager.set(
-                        AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                        next,
-                        TAG,
-                        mAlarmListener,
-                        FgThread.getHandler());
-            }
-        };
-
+        mLocationListener = location -> handleLocationAvailable();
         mLocationManager.requestLocationUpdates(
                 LocationManager.GPS_PROVIDER,
                 new LocationRequest.Builder(LocationRequest.PASSIVE_INTERVAL)
                         .setMinUpdateIntervalMillis(0)
                         .build(),
-                FgThread.getExecutor(),
+                mExecutor,
                 mLocationListener);
     }
 
+    private void handleLocationAvailable() {
+        logDebug("handleLocationAvailable()");
+
+        // getGnssTimeMillis() can return null when the Master Location Switch for the
+        // foreground user is disabled.
+        LocationTime locationTime = mLocationManagerInternal.getGnssTimeMillis();
+        if (locationTime != null) {
+            String msg = "Passive location time received: " + locationTime;
+            logDebug(msg);
+            mLocalLog.log(msg);
+            suggestGnssTime(locationTime);
+        } else {
+            logDebug("getGnssTimeMillis() returned null");
+        }
+
+        synchronized (mLock) {
+            if (mLocationListener == null) {
+                logWarning("mLocationListener unexpectedly null");
+            } else {
+                mLocationManager.removeUpdates(mLocationListener);
+                mLocationListener = null;
+            }
+
+            if (mAlarmListener != null) {
+                logWarning("mAlarmListener was unexpectedly non-null");
+                mAlarmManager.cancel(mAlarmListener);
+            }
+
+            // Set next alarm to re-enable location updates.
+            long next = SystemClock.elapsedRealtime()
+                    + GNSS_TIME_UPDATE_ALARM_INTERVAL.toMillis();
+            mAlarmListener = this::handleAlarmFired;
+            mAlarmManager.set(
+                    AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                    next,
+                    TAG,
+                    mAlarmListener,
+                    mHandler);
+        }
+    }
+
+    private void handleAlarmFired() {
+        logDebug("handleAlarmFired()");
+
+        synchronized (mLock) {
+            mAlarmListener = null;
+            startGnssListeningLocked();
+        }
+    }
+
     /**
      * Convert LocationTime to TimestampedValue. Then suggest TimestampedValue to Time Detector.
      */
     private void suggestGnssTime(LocationTime locationTime) {
-        if (D) {
-            Log.d(TAG, "suggestGnssTime()");
-        }
-        long gnssTime = locationTime.getTime();
+        logDebug("suggestGnssTime()");
+
+        long gnssUnixEpochTimeMillis = locationTime.getUnixEpochTimeMillis();
         long elapsedRealtimeMs = locationTime.getElapsedRealtimeNanos() / 1_000_000L;
 
-        TimestampedValue<Long> timeSignal = new TimestampedValue<>(
-                elapsedRealtimeMs, gnssTime);
+        TimestampedValue<Long> timeSignal =
+                new TimestampedValue<>(elapsedRealtimeMs, gnssUnixEpochTimeMillis);
         mLastSuggestedGnssTime = timeSignal;
 
         GnssTimeSuggestion timeSuggestion = new GnssTimeSuggestion(timeSignal);
@@ -198,11 +276,38 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
         pw.println("mLastSuggestedGnssTime: " + mLastSuggestedGnssTime);
-        pw.print("state: ");
-        if (mLocationListener != null) {
-            pw.println("time updates enabled");
-        } else {
-            pw.println("alarm enabled");
+        synchronized (mLock) {
+            pw.print("state: ");
+            if (mLocationListener != null) {
+                pw.println("time updates enabled");
+            } else {
+                pw.println("alarm enabled");
+            }
+        }
+        pw.println("Log:");
+        mLocalLog.dump(pw);
+    }
+
+    @Override
+    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
+        new GnssTimeUpdateServiceShellCommand(this).exec(
+                this, in, out, err, args, callback, resultReceiver);
+    }
+
+    private void logError(String msg) {
+        Log.e(TAG, msg);
+        mLocalLog.log(msg);
+    }
+
+    private void logWarning(String msg) {
+        Log.w(TAG, msg);
+        mLocalLog.log(msg);
+    }
+
+    private void logDebug(String msg) {
+        if (D) {
+            Log.d(TAG, msg);
         }
     }
 }
diff --git a/services/core/java/com/android/server/timedetector/GnssTimeUpdateServiceShellCommand.java b/services/core/java/com/android/server/timedetector/GnssTimeUpdateServiceShellCommand.java
new file mode 100644
index 0000000..e757578
--- /dev/null
+++ b/services/core/java/com/android/server/timedetector/GnssTimeUpdateServiceShellCommand.java
@@ -0,0 +1,77 @@
+/*
+ * 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.timedetector;
+
+import android.annotation.NonNull;
+import android.os.ShellCommand;
+
+import java.io.PrintWriter;
+import java.util.Objects;
+
+/** Implements the shell command interface for {@link GnssTimeUpdateService}. */
+class GnssTimeUpdateServiceShellCommand extends ShellCommand {
+
+    /**
+     * The name of the service.
+     */
+    private static final String SHELL_COMMAND_SERVICE_NAME = "gnss_time_update_service";
+
+    /**
+     * A shell command that forces the service in to GNSS listening mode if it isn't already.
+     */
+    private static final String SHELL_COMMAND_START_GNSS_LISTENING = "start_gnss_listening";
+
+    @NonNull
+    private final GnssTimeUpdateService mGnssTimeUpdateService;
+
+    GnssTimeUpdateServiceShellCommand(GnssTimeUpdateService gnssTimeUpdateService) {
+        mGnssTimeUpdateService = Objects.requireNonNull(gnssTimeUpdateService);
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        if (cmd == null) {
+            return handleDefaultCommands(cmd);
+        }
+
+        switch (cmd) {
+            case SHELL_COMMAND_START_GNSS_LISTENING:
+                return runStartGnssListening();
+            default: {
+                return handleDefaultCommands(cmd);
+            }
+        }
+    }
+
+    private int runStartGnssListening() {
+        boolean success = mGnssTimeUpdateService.startGnssListening();
+        getOutPrintWriter().println(success);
+        return 0;
+    }
+
+    @Override
+    public void onHelp() {
+        final PrintWriter pw = getOutPrintWriter();
+        pw.printf("Network Time Update Service (%s) commands:\n", SHELL_COMMAND_SERVICE_NAME);
+        pw.printf("  help\n");
+        pw.printf("    Print this help text.\n");
+        pw.printf("  %s\n", SHELL_COMMAND_START_GNSS_LISTENING);
+        pw.printf("    Forces the service in to GNSS listening mode (if it isn't already).\n");
+        pw.printf("    Prints true if the service is listening after this command.\n");
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 30b5083..c5f21eb 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -322,7 +322,7 @@
         final int callingPid = Binder.getCallingPid();
         // Validate and resolve ClipDescription data before clearing the calling identity
         validateAndResolveDragMimeTypeExtras(data, callingUid, callingPid, mPackageName);
-        validateDragFlags(flags, callingUid);
+        validateDragFlags(flags);
         final long ident = Binder.clearCallingIdentity();
         try {
             return mDragDropController.performDrag(mPid, mUid, window, flags, surface, touchSource,
@@ -347,11 +347,7 @@
      * Validates the given drag flags.
      */
     @VisibleForTesting
-    void validateDragFlags(int flags, int callingUid) {
-        if (callingUid == Process.SYSTEM_UID) {
-            throw new IllegalStateException("Need to validate before calling identify is cleared");
-        }
-
+    void validateDragFlags(int flags) {
         if ((flags & View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION) != 0) {
             if (!mCanStartTasksFromRecents) {
                 throw new SecurityException("Requires START_TASKS_FROM_RECENTS permission");
@@ -365,9 +361,6 @@
     @VisibleForTesting
     void validateAndResolveDragMimeTypeExtras(ClipData data, int callingUid, int callingPid,
             String callingPackage) {
-        if (callingUid == Process.SYSTEM_UID) {
-            throw new IllegalStateException("Need to validate before calling identify is cleared");
-        }
         final ClipDescription desc = data != null ? data.getDescription() : null;
         if (desc == null) {
             return;
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 3c68662..f05b1d4 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -218,6 +218,9 @@
             BackgroundThread.get().getThreadHandler().post(
                     () -> {
                         try {
+                            if (sSelfService.mIProfcollect == null) {
+                                return;
+                            }
                             sSelfService.mIProfcollect.process();
                         } catch (RemoteException e) {
                             Log.e(LOG_TAG, "Failed to process profiles in background: "
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
index aad5cd6..030c58f 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
@@ -16,16 +16,18 @@
 
 package com.android.server.timedetector;
 
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyLong;
-import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
+import android.app.AlarmManager.OnAlarmListener;
 import android.app.timedetector.GnssTimeSuggestion;
 import android.app.timedetector.TimeDetector;
 import android.content.Context;
@@ -39,9 +41,6 @@
 
 import androidx.test.runner.AndroidJUnit4;
 
-import com.android.server.LocalServices;
-
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -59,7 +58,7 @@
     @Mock private TimeDetector mMockTimeDetector;
     @Mock private AlarmManager mMockAlarmManager;
     @Mock private LocationManager mMockLocationManager;
-    @Mock private LocationManagerInternal mLocationManagerInternal;
+    @Mock private LocationManagerInternal mMockLocationManagerInternal;
 
     private GnssTimeUpdateService mGnssTimeUpdateService;
 
@@ -67,36 +66,11 @@
     public void setUp() {
         MockitoAnnotations.initMocks(this);
 
-        when(mMockContext.createAttributionContext(anyString()))
-                .thenReturn(mMockContext);
+        installGpsProviderInMockLocationManager();
 
-        when(mMockContext.getSystemServiceName(TimeDetector.class))
-                .thenReturn((TimeDetector.class).getSimpleName());
-        when(mMockContext.getSystemService(TimeDetector.class))
-                .thenReturn(mMockTimeDetector);
-
-        when(mMockContext.getSystemServiceName(LocationManager.class))
-                .thenReturn((LocationManager.class).getSimpleName());
-        when(mMockContext.getSystemService(LocationManager.class))
-                .thenReturn(mMockLocationManager);
-
-        when(mMockContext.getSystemServiceName(AlarmManager.class))
-                .thenReturn((AlarmManager.class).getSimpleName());
-        when(mMockContext.getSystemService(AlarmManager.class))
-                .thenReturn(mMockAlarmManager);
-
-        when(mMockLocationManager.hasProvider(LocationManager.GPS_PROVIDER))
-                .thenReturn(true);
-
-        LocalServices.addService(LocationManagerInternal.class, mLocationManagerInternal);
-
-        mGnssTimeUpdateService =
-                new GnssTimeUpdateService(mMockContext);
-    }
-
-    @After
-    public void tearDown() {
-        LocalServices.removeServiceForTest(LocationManagerInternal.class);
+        mGnssTimeUpdateService = new GnssTimeUpdateService(
+                mMockContext, mMockAlarmManager, mMockLocationManager, mMockLocationManagerInternal,
+                mMockTimeDetector);
     }
 
     @Test
@@ -105,11 +79,11 @@
                 ELAPSED_REALTIME_MS, GNSS_TIME);
         GnssTimeSuggestion timeSuggestion = new GnssTimeSuggestion(timeSignal);
         LocationTime locationTime = new LocationTime(GNSS_TIME, ELAPSED_REALTIME_NS);
-        doReturn(locationTime).when(mLocationManagerInternal).getGnssTimeMillis();
+        doReturn(locationTime).when(mMockLocationManagerInternal).getGnssTimeMillis();
 
-        mGnssTimeUpdateService.requestGnssTimeUpdates();
+        assertTrue(mGnssTimeUpdateService.startGnssListeningInternal());
 
-        ArgumentCaptor<LocationListener> argumentCaptor =
+        ArgumentCaptor<LocationListener> locationListenerCaptor =
                 ArgumentCaptor.forClass(LocationListener.class);
         verify(mMockLocationManager).requestLocationUpdates(
                 eq(LocationManager.GPS_PROVIDER),
@@ -117,8 +91,8 @@
                     .setMinUpdateIntervalMillis(0)
                     .build()),
                 any(),
-                argumentCaptor.capture());
-        LocationListener locationListener = argumentCaptor.getValue();
+                locationListenerCaptor.capture());
+        LocationListener locationListener = locationListenerCaptor.getValue();
         Location location = new Location(LocationManager.GPS_PROVIDER);
 
         locationListener.onLocationChanged(location);
@@ -135,11 +109,11 @@
 
     @Test
     public void testLocationListenerOnLocationChanged_nullLocationTime_doesNotSuggestGnssTime() {
-        doReturn(null).when(mLocationManagerInternal).getGnssTimeMillis();
+        doReturn(null).when(mMockLocationManagerInternal).getGnssTimeMillis();
 
-        mGnssTimeUpdateService.requestGnssTimeUpdates();
+        assertTrue(mGnssTimeUpdateService.startGnssListeningInternal());
 
-        ArgumentCaptor<LocationListener> argumentCaptor =
+        ArgumentCaptor<LocationListener> locationListenerCaptor =
                 ArgumentCaptor.forClass(LocationListener.class);
         verify(mMockLocationManager).requestLocationUpdates(
                 eq(LocationManager.GPS_PROVIDER),
@@ -147,14 +121,14 @@
                     .setMinUpdateIntervalMillis(0)
                     .build()),
                 any(),
-                argumentCaptor.capture());
-        LocationListener locationListener = argumentCaptor.getValue();
+                locationListenerCaptor.capture());
+        LocationListener locationListener = locationListenerCaptor.getValue();
         Location location = new Location(LocationManager.GPS_PROVIDER);
 
         locationListener.onLocationChanged(location);
 
         verify(mMockLocationManager).removeUpdates(locationListener);
-        verify(mMockTimeDetector, never()).suggestGnssTime(any());
+        verifyZeroInteractions(mMockTimeDetector);
         verify(mMockAlarmManager).set(
                 eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
                 anyLong(),
@@ -162,4 +136,90 @@
                 any(),
                 any());
     }
+
+    @Test
+    public void testLocationListeningRestartsAfterSleep() {
+        ArgumentCaptor<LocationListener> locationListenerCaptor =
+                ArgumentCaptor.forClass(LocationListener.class);
+        ArgumentCaptor<OnAlarmListener> alarmListenerCaptor =
+                ArgumentCaptor.forClass(OnAlarmListener.class);
+
+        advanceServiceToSleepingState(locationListenerCaptor, alarmListenerCaptor);
+
+        // Simulate the alarm manager's wake-up call.
+        OnAlarmListener wakeUpListener = alarmListenerCaptor.getValue();
+        wakeUpListener.onAlarm();
+
+        // Verify the service returned to location listening.
+        verify(mMockLocationManager).requestLocationUpdates(any(), any(), any(), any());
+        verifyZeroInteractions(mMockAlarmManager, mMockTimeDetector);
+    }
+
+    // Tests what happens when a call is made to startGnssListeningInternal() when service is
+    // sleeping. This can happen when the start_gnss_listening shell command is used.
+    @Test
+    public void testStartGnssListeningInternalCalledWhenSleeping() {
+        ArgumentCaptor<LocationListener> locationListenerCaptor =
+                ArgumentCaptor.forClass(LocationListener.class);
+        ArgumentCaptor<OnAlarmListener> alarmListenerCaptor =
+                ArgumentCaptor.forClass(OnAlarmListener.class);
+
+        advanceServiceToSleepingState(locationListenerCaptor, alarmListenerCaptor);
+
+        // Call startGnssListeningInternal(), as can happen if the start_gnss_listening shell
+        // command is used.
+        assertTrue(mGnssTimeUpdateService.startGnssListeningInternal());
+
+        // Verify the alarm manager is told to stopped sleeping and the location manager is
+        // listening again.
+        verify(mMockAlarmManager).cancel(alarmListenerCaptor.getValue());
+        verify(mMockLocationManager).requestLocationUpdates(any(), any(), any(), any());
+        verifyZeroInteractions(mMockTimeDetector);
+    }
+
+    private void advanceServiceToSleepingState(
+            ArgumentCaptor<LocationListener> locationListenerCaptor,
+            ArgumentCaptor<OnAlarmListener> alarmListenerCaptor) {
+        TimestampedValue<Long> timeSignal = new TimestampedValue<>(
+                ELAPSED_REALTIME_MS, GNSS_TIME);
+        GnssTimeSuggestion timeSuggestion = new GnssTimeSuggestion(timeSignal);
+        LocationTime locationTime = new LocationTime(GNSS_TIME, ELAPSED_REALTIME_NS);
+        doReturn(locationTime).when(mMockLocationManagerInternal).getGnssTimeMillis();
+
+        assertTrue(mGnssTimeUpdateService.startGnssListeningInternal());
+
+        verify(mMockLocationManager).requestLocationUpdates(
+                any(), any(), any(), locationListenerCaptor.capture());
+        LocationListener locationListener = locationListenerCaptor.getValue();
+        Location location = new Location(LocationManager.GPS_PROVIDER);
+        verifyZeroInteractions(mMockAlarmManager, mMockTimeDetector);
+
+        locationListener.onLocationChanged(location);
+
+        verify(mMockLocationManager).removeUpdates(locationListener);
+        verify(mMockTimeDetector).suggestGnssTime(timeSuggestion);
+
+        // Verify the service is now "sleeping", i.e. waiting for a period before listening for
+        // GNSS locations again.
+        verify(mMockAlarmManager).set(
+                eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
+                anyLong(),
+                any(),
+                alarmListenerCaptor.capture(),
+                any());
+
+        // Reset mocks making it easier to verify the calls that follow.
+        reset(mMockAlarmManager, mMockTimeDetector, mMockLocationManager,
+                mMockLocationManagerInternal);
+        installGpsProviderInMockLocationManager();
+    }
+
+    /**
+     * Configures the mock response to ensure {@code
+     * locationManager.hasProvider(LocationManager.GPS_PROVIDER) == true }
+     */
+    private void installGpsProviderInMockLocationManager() {
+        when(mMockLocationManager.hasProvider(LocationManager.GPS_PROVIDER))
+                .thenReturn(true);
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
index 28fc352..4526d18 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DragDropControllerTests.java
@@ -467,8 +467,7 @@
             public void onAnimatorScaleChanged(float scale) {}
         });
         try {
-            session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION,
-                    TEST_UID);
+            session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION);
             fail("Expected failure without permission");
         } catch (SecurityException e) {
             // Expected failure
@@ -484,8 +483,7 @@
             public void onAnimatorScaleChanged(float scale) {}
         });
         try {
-            session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION,
-                    TEST_UID);
+            session.validateDragFlags(View.DRAG_FLAG_REQUEST_SURFACE_FOR_RETURN_ANIMATION);
             // Expected pass
         } catch (SecurityException e) {
             fail("Expected no failure with permission");
diff --git a/tests/TouchLatency/OWNERS b/tests/TouchLatency/OWNERS
new file mode 100644
index 0000000..2b7de25
--- /dev/null
+++ b/tests/TouchLatency/OWNERS
@@ -0,0 +1,2 @@
+include platform/frameworks/base:/graphics/java/android/graphics/OWNERS
+include platform/frameworks/native:/services/surfaceflinger/OWNERS
\ No newline at end of file
diff --git a/tools/codegen/BUILD.bazel b/tools/codegen/BUILD.bazel
new file mode 100644
index 0000000..c14046d
--- /dev/null
+++ b/tools/codegen/BUILD.bazel
@@ -0,0 +1,21 @@
+# TODO(b/245731902): auto-generate these with bp2build.
+load("@rules_kotlin//kotlin:jvm_library.bzl", "kt_jvm_library")
+
+java_binary(
+    name = "codegen_cli",
+    main_class = "com.android.codegen.MainKt",
+    runtime_deps = [
+        ":codegen_cli_kt_lib",
+    ],
+)
+
+kt_jvm_library(
+    name = "codegen_cli_kt_lib",
+    srcs = glob(["src/**/*.kt"]),
+    deps = ["//external/javaparser"],
+)
+
+kt_jvm_library(
+    name = "codegen-version-info",
+    srcs = glob(["src/**/SharedConstants.kt"]),
+)