Merge "Don't depend on String8 cast to C string" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 9f48bf4..55f5436 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -18,8 +18,11 @@
 
     // Add java_aconfig_libraries to here to add them to the core framework
     srcs: [
+        ":android.os.flags-aconfig-java{.generated_srcjars}",
+        ":android.security.flags-aconfig-java{.generated_srcjars}",
         ":com.android.hardware.camera2-aconfig-java{.generated_srcjars}",
         ":com.android.window.flags.window-aconfig-java{.generated_srcjars}",
+        ":com.android.hardware.input-aconfig-java{.generated_srcjars}",
         ":com.android.text.flags-aconfig-java{.generated_srcjars}",
     ],
     // Add aconfig-annotations-lib as a dependency for the optimization
@@ -60,6 +63,19 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
+// Input
+aconfig_declarations {
+    name: "com.android.hardware.input.input-aconfig",
+    package: "com.android.hardware.input",
+    srcs: ["core/java/android/hardware/input/*.aconfig"],
+}
+
+java_aconfig_library {
+    name: "com.android.hardware.input-aconfig-java",
+    aconfig_declarations: "com.android.hardware.input.input-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 // Text
 aconfig_declarations {
     name: "com.android.text.flags-aconfig",
@@ -72,3 +88,37 @@
     aconfig_declarations: "com.android.text.flags-aconfig",
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
+
+// OS
+aconfig_declarations {
+    name: "android.os.flags-aconfig",
+    package: "android.os",
+    srcs: ["core/java/android/os/*.aconfig"],
+}
+
+java_aconfig_library {
+    name: "android.os.flags-aconfig-java",
+    aconfig_declarations: "android.os.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
+// Security
+aconfig_declarations {
+    name: "android.security.flags-aconfig",
+    package: "android.security",
+    srcs: ["core/java/android/security/*.aconfig"],
+}
+
+java_aconfig_library {
+    name: "android.security.flags-aconfig-java",
+    aconfig_declarations: "android.security.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
+java_aconfig_library {
+    name: "android.security.flags-aconfig-java-host",
+    aconfig_declarations: "android.security.flags-aconfig",
+    host_supported: true,
+    test: true,
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
diff --git a/OWNERS b/OWNERS
index 6c25324..4e5c7d8 100644
--- a/OWNERS
+++ b/OWNERS
@@ -28,7 +28,7 @@
 # Support bulk translation updates
 per-file */res*/values*/*.xml = byi@google.com, delphij@google.com
 
-per-file **.bp,**.mk = hansson@google.com, joeo@google.com
+per-file **.bp,**.mk = hansson@google.com, joeo@google.com, lamontjones@google.com
 per-file TestProtoLibraries.bp = file:platform/platform_testing:/libraries/health/OWNERS
 per-file TestProtoLibraries.bp = file:platform/tools/tradefederation:/OWNERS
 
diff --git a/cmds/idmap2/libidmap2/CommandLineOptions.cpp b/cmds/idmap2/libidmap2/CommandLineOptions.cpp
index 8129d99..b1edc18 100644
--- a/cmds/idmap2/libidmap2/CommandLineOptions.cpp
+++ b/cmds/idmap2/libidmap2/CommandLineOptions.cpp
@@ -20,6 +20,7 @@
 #include <cassert>
 #include <iomanip>
 #include <iostream>
+#include <iterator>
 #include <memory>
 #include <set>
 #include <sstream>
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 5d7d7ba..da6a6d4 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -9,6 +9,11 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
+aidl_library {
+    name: "HardwareBuffer_aidl",
+    hdrs: ["android/hardware/HardwareBuffer.aidl"],
+}
+
 filegroup {
     name: "framework-core-sources",
     srcs: [
diff --git a/core/java/android/app/trust/ITrustListener.aidl b/core/java/android/app/trust/ITrustListener.aidl
index e4ac0119..8d44784 100644
--- a/core/java/android/app/trust/ITrustListener.aidl
+++ b/core/java/android/app/trust/ITrustListener.aidl
@@ -24,6 +24,7 @@
  * {@hide}
  */
 oneway interface ITrustListener {
+    void onEnabledTrustAgentsChanged(int userId);
     void onTrustChanged(boolean enabled, boolean newlyUnlocked, int userId, int flags,
         in List<String> trustGrantedMessages);
     void onTrustManagedChanged(boolean managed, int userId);
diff --git a/core/java/android/app/trust/TrustManager.java b/core/java/android/app/trust/TrustManager.java
index 62f755d..3552ce0 100644
--- a/core/java/android/app/trust/TrustManager.java
+++ b/core/java/android/app/trust/TrustManager.java
@@ -43,6 +43,7 @@
     private static final int MSG_TRUST_CHANGED = 1;
     private static final int MSG_TRUST_MANAGED_CHANGED = 2;
     private static final int MSG_TRUST_ERROR = 3;
+    private static final int MSG_ENABLED_TRUST_AGENTS_CHANGED = 4;
 
     private static final String TAG = "TrustManager";
     private static final String DATA_FLAGS = "initiatedByUser";
@@ -187,6 +188,13 @@
                 }
 
                 @Override
+                public void onEnabledTrustAgentsChanged(int userId) {
+                    final Message m = mHandler.obtainMessage(MSG_ENABLED_TRUST_AGENTS_CHANGED,
+                            userId, 0, trustListener);
+                    m.sendToTarget();
+                }
+
+                @Override
                 public void onTrustManagedChanged(boolean managed, int userId) {
                     mHandler.obtainMessage(MSG_TRUST_MANAGED_CHANGED, (managed ? 1 : 0), userId,
                             trustListener).sendToTarget();
@@ -283,6 +291,10 @@
                 case MSG_TRUST_ERROR:
                     final CharSequence message = msg.peekData().getCharSequence(DATA_MESSAGE);
                     ((TrustListener) msg.obj).onTrustError(message);
+                    break;
+                case MSG_ENABLED_TRUST_AGENTS_CHANGED:
+                    ((TrustListener) msg.obj).onEnabledTrustAgentsChanged(msg.arg1);
+                    break;
             }
         }
     };
@@ -316,5 +328,10 @@
          * @param message A message that should be displayed on the UI.
          */
         void onTrustError(CharSequence message);
+
+        /**
+         * Reports that the enabled trust agents for the specified user has changed.
+         */
+        void onEnabledTrustAgentsChanged(int userId);
     }
 }
diff --git a/core/java/android/hardware/input/input_framework.aconfig b/core/java/android/hardware/input/input_framework.aconfig
new file mode 100644
index 0000000..ebfe66f5
--- /dev/null
+++ b/core/java/android/hardware/input/input_framework.aconfig
@@ -0,0 +1,19 @@
+package: "com.android.hardware.input"
+
+# Project link: https://gantry.corp.google.com/projects/android_platform_input_native/changes
+
+flag {
+    namespace: "input_native"
+    name: "keyboard_layout_preview_flag"
+    description: "Controls whether a preview will be shown in Settings when selecting a physical keyboard layout"
+    bug: "293579375"
+}
+
+
+flag {
+    namespace: "input_native"
+    name: "keyboard_a11y_sticky_keys_flag"
+    description: "Controls if the sticky keys accessibility feature for physical keyboard is available to the user"
+    bug: "294546335"
+}
+
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
new file mode 100644
index 0000000..851aa6d
--- /dev/null
+++ b/core/java/android/os/flags.aconfig
@@ -0,0 +1,8 @@
+package: "android.os"
+
+flag {
+    name: "disallow_cellular_null_ciphers_restriction"
+    namespace: "cellular_security"
+    description: "Guards a new UserManager user restriction that admins can use to require cellular encryption on their managed devices."
+    bug: "276752881"
+}
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
new file mode 100644
index 0000000..b6c2b83
--- /dev/null
+++ b/core/java/android/security/flags.aconfig
@@ -0,0 +1,15 @@
+package: "android.security"
+
+flag {
+    name: "fsverity_api"
+    namespace: "hardware_backed_security"
+    description: "Feature flag for fs-verity API"
+    bug: "285185747"
+}
+
+flag {
+    name: "fix_unlocked_device_required_keys"
+    namespace: "hardware_backed_security"
+    description: "Fix bugs in behavior of UnlockedDeviceRequired keystore keys"
+    bug: "296464083"
+}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6182253..11e43dd 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2434,6 +2434,7 @@
      * @see #getId()
      */
     @IdRes
+    @ViewDebug.ExportedProperty(resolveId = true)
     int mID = NO_ID;
 
     /** The ID of this view for autofill purposes.
@@ -4240,6 +4241,71 @@
      * This view's request for the visibility of the status bar.
      * @hide
      */
+    @ViewDebug.ExportedProperty(flagMapping = {
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LOW_PROFILE,
+                    equals = SYSTEM_UI_FLAG_LOW_PROFILE,
+                    name = "LOW_PROFILE"),
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
+                    equals = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
+                    name = "HIDE_NAVIGATION"),
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_FULLSCREEN,
+                    equals = SYSTEM_UI_FLAG_FULLSCREEN,
+                    name = "FULLSCREEN"),
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LAYOUT_STABLE,
+                    equals = SYSTEM_UI_FLAG_LAYOUT_STABLE,
+                    name = "LAYOUT_STABLE"),
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,
+                    equals = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,
+                    name = "LAYOUT_HIDE_NAVIGATION"),
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,
+                    equals = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,
+                    name = "LAYOUT_FULLSCREEN"),
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_IMMERSIVE,
+                    equals = SYSTEM_UI_FLAG_IMMERSIVE,
+                    name = "IMMERSIVE"),
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_IMMERSIVE_STICKY,
+                    equals = SYSTEM_UI_FLAG_IMMERSIVE_STICKY,
+                    name = "IMMERSIVE_STICKY"),
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,
+                    equals = SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,
+                    name = "LIGHT_STATUS_BAR"),
+            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+                    equals = SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+                    name = "LIGHT_NAVIGATION_BAR"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_EXPAND,
+                    equals = STATUS_BAR_DISABLE_EXPAND,
+                    name = "STATUS_BAR_DISABLE_EXPAND"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_NOTIFICATION_ICONS,
+                    equals = STATUS_BAR_DISABLE_NOTIFICATION_ICONS,
+                    name = "STATUS_BAR_DISABLE_NOTIFICATION_ICONS"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_NOTIFICATION_ALERTS,
+                    equals = STATUS_BAR_DISABLE_NOTIFICATION_ALERTS,
+                    name = "STATUS_BAR_DISABLE_NOTIFICATION_ALERTS"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_NOTIFICATION_TICKER,
+                    equals = STATUS_BAR_DISABLE_NOTIFICATION_TICKER,
+                    name = "STATUS_BAR_DISABLE_NOTIFICATION_TICKER"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_SYSTEM_INFO,
+                    equals = STATUS_BAR_DISABLE_SYSTEM_INFO,
+                    name = "STATUS_BAR_DISABLE_SYSTEM_INFO"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_HOME,
+                    equals = STATUS_BAR_DISABLE_HOME,
+                    name = "STATUS_BAR_DISABLE_HOME"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_BACK,
+                    equals = STATUS_BAR_DISABLE_BACK,
+                    name = "STATUS_BAR_DISABLE_BACK"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_CLOCK,
+                    equals = STATUS_BAR_DISABLE_CLOCK,
+                    name = "STATUS_BAR_DISABLE_CLOCK"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_RECENT,
+                    equals = STATUS_BAR_DISABLE_RECENT,
+                    name = "STATUS_BAR_DISABLE_RECENT"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_SEARCH,
+                    equals = STATUS_BAR_DISABLE_SEARCH,
+                    name = "STATUS_BAR_DISABLE_SEARCH"),
+            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_ONGOING_CALL_CHIP,
+                    equals = STATUS_BAR_DISABLE_ONGOING_CALL_CHIP,
+                    name = "STATUS_BAR_DISABLE_ONGOING_CALL_CHIP")
+    }, formatToHexString = true)
     @SystemUiVisibility
     int mSystemUiVisibility;
 
@@ -4358,6 +4424,7 @@
      * to the left edge of this view.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "layout")
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     protected int mLeft;
     /**
@@ -4365,6 +4432,7 @@
      * to the right edge of this view.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "layout")
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     protected int mRight;
     /**
@@ -4372,6 +4440,7 @@
      * to the top edge of this view.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "layout")
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     protected int mTop;
     /**
@@ -4379,6 +4448,7 @@
      * to the bottom edge of this view.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "layout")
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     protected int mBottom;
 
@@ -4389,6 +4459,7 @@
      * accessing these directly.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "scrolling")
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     protected int mScrollX;
     /**
@@ -4398,6 +4469,7 @@
      * accessing these directly.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "scrolling")
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     protected int mScrollY;
 
@@ -4406,6 +4478,7 @@
      * pixels between the left edge of this view and the left edge of its content.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "padding")
     @UnsupportedAppUsage
     protected int mPaddingLeft = 0;
     /**
@@ -4413,6 +4486,7 @@
      * pixels between the right edge of this view and the right edge of its content.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "padding")
     @UnsupportedAppUsage
     protected int mPaddingRight = 0;
     /**
@@ -4420,6 +4494,7 @@
      * pixels between the top edge of this view and the top edge of its content.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "padding")
     @UnsupportedAppUsage
     protected int mPaddingTop;
     /**
@@ -4427,6 +4502,7 @@
      * pixels between the bottom edge of this view and the bottom edge of its content.
      * {@hide}
      */
+    @ViewDebug.ExportedProperty(category = "padding")
     @UnsupportedAppUsage
     protected int mPaddingBottom;
 
@@ -17121,7 +17197,6 @@
      * @return The left edge of the displayed part of your view, in pixels.
      */
     @InspectableProperty
-    @ViewDebug.ExportedProperty(category = "scrolling")
     public final int getScrollX() {
         return mScrollX;
     }
@@ -17134,7 +17209,6 @@
      * @return The top edge of the displayed part of your view, in pixels.
      */
     @InspectableProperty
-    @ViewDebug.ExportedProperty(category = "scrolling")
     public final int getScrollY() {
         return mScrollY;
     }
@@ -17925,7 +17999,6 @@
      * @return The top of this view, in pixels.
      */
     @ViewDebug.CapturedViewProperty
-    @ViewDebug.ExportedProperty(category = "layout")
     public final int getTop() {
         return mTop;
     }
@@ -17985,7 +18058,6 @@
      * @return The bottom of this view, in pixels.
      */
     @ViewDebug.CapturedViewProperty
-    @ViewDebug.ExportedProperty(category = "layout")
     public final int getBottom() {
         return mBottom;
     }
@@ -18051,7 +18123,6 @@
      * @return The left edge of this view, in pixels.
      */
     @ViewDebug.CapturedViewProperty
-    @ViewDebug.ExportedProperty(category = "layout")
     public final int getLeft() {
         return mLeft;
     }
@@ -18111,7 +18182,6 @@
      * @return The right edge of this view, in pixels.
      */
     @ViewDebug.CapturedViewProperty
-    @ViewDebug.ExportedProperty(category = "layout")
     public final int getRight() {
         return mRight;
     }
@@ -25320,7 +25390,6 @@
      * @return the top padding in pixels
      */
     @InspectableProperty
-    @ViewDebug.ExportedProperty(category = "padding")
     public int getPaddingTop() {
         return mPaddingTop;
     }
@@ -25333,7 +25402,6 @@
      * @return the bottom padding in pixels
      */
     @InspectableProperty
-    @ViewDebug.ExportedProperty(category = "padding")
     public int getPaddingBottom() {
         return mPaddingBottom;
     }
@@ -25346,7 +25414,6 @@
      * @return the left padding in pixels
      */
     @InspectableProperty
-    @ViewDebug.ExportedProperty(category = "padding")
     public int getPaddingLeft() {
         if (!isPaddingResolved()) {
             resolvePadding();
@@ -25377,7 +25444,6 @@
      * @return the right padding in pixels
      */
     @InspectableProperty
-    @ViewDebug.ExportedProperty(category = "padding")
     public int getPaddingRight() {
         if (!isPaddingResolved()) {
             resolvePadding();
@@ -26063,7 +26129,6 @@
      */
     @IdRes
     @ViewDebug.CapturedViewProperty
-    @ViewDebug.ExportedProperty(resolveId = true)
     @InspectableProperty
     public int getId() {
         return mID;
@@ -27026,71 +27091,6 @@
      * @deprecated SystemUiVisibility flags are deprecated. Use {@link WindowInsetsController}
      * instead.
      */
-    @ViewDebug.ExportedProperty(flagMapping = {
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LOW_PROFILE,
-                    equals = SYSTEM_UI_FLAG_LOW_PROFILE,
-                    name = "LOW_PROFILE"),
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
-                    equals = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
-                    name = "HIDE_NAVIGATION"),
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_FULLSCREEN,
-                    equals = SYSTEM_UI_FLAG_FULLSCREEN,
-                    name = "FULLSCREEN"),
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LAYOUT_STABLE,
-                    equals = SYSTEM_UI_FLAG_LAYOUT_STABLE,
-                    name = "LAYOUT_STABLE"),
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,
-                    equals = SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION,
-                    name = "LAYOUT_HIDE_NAVIGATION"),
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,
-                    equals = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN,
-                    name = "LAYOUT_FULLSCREEN"),
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_IMMERSIVE,
-                    equals = SYSTEM_UI_FLAG_IMMERSIVE,
-                    name = "IMMERSIVE"),
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_IMMERSIVE_STICKY,
-                    equals = SYSTEM_UI_FLAG_IMMERSIVE_STICKY,
-                    name = "IMMERSIVE_STICKY"),
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,
-                    equals = SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,
-                    name = "LIGHT_STATUS_BAR"),
-            @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
-                    equals = SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
-                    name = "LIGHT_NAVIGATION_BAR"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_EXPAND,
-                    equals = STATUS_BAR_DISABLE_EXPAND,
-                    name = "STATUS_BAR_DISABLE_EXPAND"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_NOTIFICATION_ICONS,
-                    equals = STATUS_BAR_DISABLE_NOTIFICATION_ICONS,
-                    name = "STATUS_BAR_DISABLE_NOTIFICATION_ICONS"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_NOTIFICATION_ALERTS,
-                    equals = STATUS_BAR_DISABLE_NOTIFICATION_ALERTS,
-                    name = "STATUS_BAR_DISABLE_NOTIFICATION_ALERTS"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_NOTIFICATION_TICKER,
-                    equals = STATUS_BAR_DISABLE_NOTIFICATION_TICKER,
-                    name = "STATUS_BAR_DISABLE_NOTIFICATION_TICKER"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_SYSTEM_INFO,
-                    equals = STATUS_BAR_DISABLE_SYSTEM_INFO,
-                    name = "STATUS_BAR_DISABLE_SYSTEM_INFO"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_HOME,
-                    equals = STATUS_BAR_DISABLE_HOME,
-                    name = "STATUS_BAR_DISABLE_HOME"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_BACK,
-                    equals = STATUS_BAR_DISABLE_BACK,
-                    name = "STATUS_BAR_DISABLE_BACK"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_CLOCK,
-                    equals = STATUS_BAR_DISABLE_CLOCK,
-                    name = "STATUS_BAR_DISABLE_CLOCK"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_RECENT,
-                    equals = STATUS_BAR_DISABLE_RECENT,
-                    name = "STATUS_BAR_DISABLE_RECENT"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_SEARCH,
-                    equals = STATUS_BAR_DISABLE_SEARCH,
-                    name = "STATUS_BAR_DISABLE_SEARCH"),
-            @ViewDebug.FlagToString(mask = STATUS_BAR_DISABLE_ONGOING_CALL_CHIP,
-                    equals = STATUS_BAR_DISABLE_ONGOING_CALL_CHIP,
-                    name = "STATUS_BAR_DISABLE_ONGOING_CALL_CHIP")
-    }, formatToHexString = true)
     @Deprecated
     public int getSystemUiVisibility() {
         return mSystemUiVisibility;
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 5bc48c5..c9d9926 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -19,6 +19,9 @@
 import android.annotation.NonNull;
 import android.os.FileUtils;
 import android.util.Log;
+import android.util.Pair;
+
+import libcore.io.IoUtils;
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
@@ -28,12 +31,12 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Comparator;
 import java.util.Objects;
+import java.util.TreeSet;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
-import libcore.io.IoUtils;
-
 /**
  * Utility that rotates files over time, similar to {@code logrotate}. There is
  * a single "active" file, which is periodically rotated into historical files,
@@ -302,17 +305,24 @@
     public void readMatching(Reader reader, long matchStartMillis, long matchEndMillis)
             throws IOException {
         final FileInfo info = new FileInfo(mPrefix);
+        final TreeSet<Pair<Long, String>> readSet = new TreeSet<>(
+                Comparator.comparingLong(o -> o.first));
         for (String name : mBasePath.list()) {
             if (!info.parse(name)) continue;
 
-            // read file when it overlaps
+            // Add file to set when it overlaps.
             if (info.startMillis <= matchEndMillis && matchStartMillis <= info.endMillis) {
-                if (LOGD) Log.d(TAG, "reading matching " + name);
-
-                final File file = new File(mBasePath, name);
-                readFile(file, reader);
+                readSet.add(new Pair(info.startMillis, name));
             }
         }
+
+        // Read files in ascending order of start timestamp.
+        for (Pair<Long, String> pair : readSet) {
+            final String name = pair.second;
+            if (LOGD) Log.d(TAG, "reading matching " + name);
+            final File file = new File(mBasePath, name);
+            readFile(file, reader);
+        }
     }
 
     /**
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index bbaea0a..418000f 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1806,15 +1806,10 @@
     if (!is_system_server && getuid() == 0) {
         const int rc = createProcessGroup(uid, getpid());
         if (rc != 0) {
-            if (rc == -ESRCH) {
-                // If process is dead, treat this as a non-fatal error
-                ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
-            } else {
-                fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing "
-                                                    "CONFIG_CGROUP_CPUACCT?")
-                                     : CREATE_ERROR("createProcessGroup(%d, %d) failed: %s", uid,
-                                                    /* pid= */ 0, strerror(-rc)));
-            }
+            fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing "
+                                                "CONFIG_CGROUP_CPUACCT?")
+                                 : CREATE_ERROR("createProcessGroup(%d, %d) failed: %s", uid,
+                                                /* pid= */ 0, strerror(-rc)));
         }
     }
 
diff --git a/core/tests/coretests/src/android/hardware/input/InputFlagsTest.java b/core/tests/coretests/src/android/hardware/input/InputFlagsTest.java
new file mode 100644
index 0000000..5aeab42
--- /dev/null
+++ b/core/tests/coretests/src/android/hardware/input/InputFlagsTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 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 android.hardware.input;
+
+import static com.android.hardware.input.Flags.keyboardA11yStickyKeysFlag;
+import static com.android.hardware.input.Flags.keyboardLayoutPreviewFlag;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link com.android.hardware.input.Flags}
+ *
+ * Build/Install/Run:
+ *  atest FrameworksCoreTests:InputFlagsTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class InputFlagsTest {
+
+    /**
+     * Test that the flags work
+     */
+    @Test
+    public void testFlags() {
+        // No crash when accessing the flag.
+        keyboardLayoutPreviewFlag();
+        keyboardA11yStickyKeysFlag();
+    }
+}
+
diff --git a/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java
index 95272132..73e47e1 100644
--- a/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/FileRotatorTest.java
@@ -366,6 +366,16 @@
         assertReadAll(rotate, "bar");
     }
 
+    public void testReadSorted() throws Exception {
+        write("rotator.1024-2048", "2");
+        write("rotator.2048-4096", "3");
+        write("rotator.512-1024", "1");
+
+        final FileRotator rotate = new FileRotator(
+                mBasePath, PREFIX, SECOND_IN_MILLIS, SECOND_IN_MILLIS);
+        assertReadAll(rotate, "1", "2", "3");
+    }
+
     public void testFileSystemInaccessible() throws Exception {
         File inaccessibleDir = null;
         String dirPath = getContext().getFilesDir() + File.separator + "inaccessible";
@@ -422,16 +432,7 @@
         }
 
         public void assertRead(String... expected) {
-            assertEquals(expected.length, mActual.size());
-
-            final ArrayList<String> actualCopy = new ArrayList<String>(mActual);
-            for (String value : expected) {
-                if (!actualCopy.remove(value)) {
-                    final String expectedString = Arrays.toString(expected);
-                    final String actualString = Arrays.toString(mActual.toArray());
-                    fail("expected: " + expectedString + " but was: " + actualString);
-                }
-            }
+            assertEquals(Arrays.asList(expected), mActual);
         }
     }
 }
diff --git a/data/keyboards/qwerty.idc b/data/keyboards/qwerty.idc
deleted file mode 100644
index 375d785..0000000
--- a/data/keyboards/qwerty.idc
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2010 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.
-
-#
-# Emulator keyboard configuration file #1.
-#
-
-touch.deviceType = touchScreen
-touch.orientationAware = 1
-
-keyboard.layout = qwerty
-keyboard.characterMap = qwerty
-keyboard.orientationAware = 1
-keyboard.builtIn = 1
-
-cursor.mode = navigation
-cursor.orientationAware = 1
diff --git a/data/keyboards/qwerty.kcm b/data/keyboards/qwerty.kcm
deleted file mode 100644
index f3e1524..0000000
--- a/data/keyboards/qwerty.kcm
+++ /dev/null
@@ -1,508 +0,0 @@
-# Copyright (C) 2010 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.
-
-#
-# Emulator keyboard character map #1.
-#
-# This file is no longer used as the platform's default keyboard character map.
-# Refer to Generic.kcm and Virtual.kcm instead.
-#
-
-type ALPHA
-
-key A {
-    label:                              'A'
-    number:                             '2'
-    base:                               'a'
-    shift, capslock:                    'A'
-    alt:                                '#'
-    shift+alt, capslock+alt:            none
-}
-
-key B {
-    label:                              'B'
-    number:                             '2'
-    base:                               'b'
-    shift, capslock:                    'B'
-    alt:                                '<'
-    shift+alt, capslock+alt:            none
-}
-
-key C {
-    label:                              'C'
-    number:                             '2'
-    base:                               'c'
-    shift, capslock:                    'C'
-    alt:                                '9'
-    shift+alt, capslock+alt:            '\u00e7'
-}
-
-key D {
-    label:                              'D'
-    number:                             '3'
-    base:                               'd'
-    shift, capslock:                    'D'
-    alt:                                '5'
-    shift+alt, capslock+alt:            none
-}
-
-key E {
-    label:                              'E'
-    number:                             '3'
-    base:                               'e'
-    shift, capslock:                    'E'
-    alt:                                '2'
-    shift+alt, capslock+alt:            '\u0301'
-}
-
-key F {
-    label:                              'F'
-    number:                             '3'
-    base:                               'f'
-    shift, capslock:                    'F'
-    alt:                                '6'
-    shift+alt, capslock+alt:            '\u00a5'
-}
-
-key G {
-    label:                              'G'
-    number:                             '4'
-    base:                               'g'
-    shift, capslock:                    'G'
-    alt:                                '-'
-    shift+alt, capslock+alt:            '_'
-}
-
-key H {
-    label:                              'H'
-    number:                             '4'
-    base:                               'h'
-    shift, capslock:                    'H'
-    alt:                                '['
-    shift+alt, capslock+alt:            '{'
-}
-
-key I {
-    label:                              'I'
-    number:                             '4'
-    base:                               'i'
-    shift, capslock:                    'I'
-    alt:                                '$'
-    shift+alt, capslock+alt:            '\u0302'
-}
-
-key J {
-    label:                              'J'
-    number:                             '5'
-    base:                               'j'
-    shift, capslock:                    'J'
-    alt:                                ']'
-    shift+alt, capslock+alt:            '}'
-}
-
-key K {
-    label:                              'K'
-    number:                             '5'
-    base:                               'k'
-    shift, capslock:                    'K'
-    alt:                                '"'
-    shift+alt, capslock+alt:            '~'
-}
-
-key L {
-    label:                              'L'
-    number:                             '5'
-    base:                               'l'
-    shift, capslock:                    'L'
-    alt:                                '\''
-    shift+alt, capslock+alt:            '`'
-}
-
-key M {
-    label:                              'M'
-    number:                             '6'
-    base:                               'm'
-    shift, capslock:                    'M'
-    alt:                                '!'
-    shift+alt, capslock+alt:            none
-}
-
-key N {
-    label:                              'N'
-    number:                             '6'
-    base:                               'n'
-    shift, capslock:                    'N'
-    alt:                                '>'
-    shift+alt, capslock+alt:            '\u0303'
-}
-
-key O {
-    label:                              'O'
-    number:                             '6'
-    base:                               'o'
-    shift, capslock:                    'O'
-    alt:                                '('
-    shift+alt, capslock+alt:            none
-}
-
-key P {
-    label:                              'P'
-    number:                             '7'
-    base:                               'p'
-    shift, capslock:                    'P'
-    alt:                                ')'
-    shift+alt, capslock+alt:            none
-}
-
-key Q {
-    label:                              'Q'
-    number:                             '7'
-    base:                               'q'
-    shift, capslock:                    'Q'
-    alt:                                '*'
-    shift+alt, capslock+alt:            '\u0300'
-}
-
-key R {
-    label:                              'R'
-    number:                             '7'
-    base:                               'r'
-    shift, capslock:                    'R'
-    alt:                                '3'
-    shift+alt, capslock+alt:            '\u20ac'
-}
-
-key S {
-    label:                              'S'
-    number:                             '7'
-    base:                               's'
-    shift, capslock:                    'S'
-    alt:                                '4'
-    shift+alt, capslock+alt:            '\u00df'
-}
-
-key T {
-    label:                              'T'
-    number:                             '8'
-    base:                               't'
-    shift, capslock:                    'T'
-    alt:                                '+'
-    shift+alt, capslock+alt:            '\u00a3'
-}
-
-key U {
-    label:                              'U'
-    number:                             '8'
-    base:                               'u'
-    shift, capslock:                    'U'
-    alt:                                '&'
-    shift+alt, capslock+alt:            '\u0308'
-}
-
-key V {
-    label:                              'V'
-    number:                             '8'
-    base:                               'v'
-    shift, capslock:                    'V'
-    alt:                                '='
-    shift+alt, capslock+alt:            '^'
-}
-
-key W {
-    label:                              'W'
-    number:                             '9'
-    base:                               'w'
-    shift, capslock:                    'W'
-    alt:                                '1'
-    shift+alt, capslock+alt:            none
-}
-
-key X {
-    label:                              'X'
-    number:                             '9'
-    base:                               'x'
-    shift, capslock:                    'X'
-    alt:                                '8'
-    shift+alt, capslock+alt:            '\uef00'
-}
-
-key Y {
-    label:                              'Y'
-    number:                             '9'
-    base:                               'y'
-    shift, capslock:                    'Y'
-    alt:                                '%'
-    shift+alt, capslock+alt:            '\u00a1'
-}
-
-key Z {
-    label:                              'Z'
-    number:                             '9'
-    base:                               'z'
-    shift, capslock:                    'Z'
-    alt:                                '7'
-    shift+alt, capslock+alt:            none
-}
-
-key COMMA {
-    label:                              ','
-    number:                             ','
-    base:                               ','
-    shift:                              ';'
-    alt:                                ';'
-    shift+alt:                          '|'
-}
-
-key PERIOD {
-    label:                              '.'
-    number:                             '.'
-    base:                               '.'
-    shift:                              ':'
-    alt:                                ':'
-    shift+alt:                          '\u2026'
-}
-
-key AT {
-    label:                              '@'
-    number:                             '0'
-    base:                               '@'
-    shift:                              '0'
-    alt:                                '0'
-    shift+alt:                          '\u2022'
-}
-
-key SLASH {
-    label:                              '/'
-    number:                             '/'
-    base:                               '/'
-    shift:                              '?'
-    alt:                                '?'
-    shift+alt:                          '\\'
-}
-
-key SPACE {
-    label:                              ' '
-    number:                             ' '
-    base:                               ' '
-    shift:                              ' '
-    alt:                                '\uef01'
-    shift+alt:                          '\uef01'
-}
-
-key ENTER {
-    label:                              '\n'
-    number:                             '\n'
-    base:                               '\n'
-    shift:                              '\n'
-    alt:                                '\n'
-    shift+alt:                          '\n'
-}
-
-key TAB {
-    label:                              '\t'
-    number:                             '\t'
-    base:                               '\t'
-    shift:                              '\t'
-    alt:                                '\t'
-    shift+alt:                          '\t'
-}
-
-key 0 {
-    label:                              '0'
-    number:                             '0'
-    base:                               '0'
-    shift:                              ')'
-    alt:                                ')'
-    shift+alt:                          ')'
-}
-
-key 1 {
-    label:                              '1'
-    number:                             '1'
-    base:                               '1'
-    shift:                              '!'
-    alt:                                '!'
-    shift+alt:                          '!'
-}
-
-key 2 {
-    label:                              '2'
-    number:                             '2'
-    base:                               '2'
-    shift:                              '@'
-    alt:                                '@'
-    shift+alt:                          '@'
-}
-
-key 3 {
-    label:                              '3'
-    number:                             '3'
-    base:                               '3'
-    shift:                              '#'
-    alt:                                '#'
-    shift+alt:                          '#'
-}
-
-key 4 {
-    label:                              '4'
-    number:                             '4'
-    base:                               '4'
-    shift:                              '$'
-    alt:                                '$'
-    shift+alt:                          '$'
-}
-
-key 5 {
-    label:                              '5'
-    number:                             '5'
-    base:                               '5'
-    shift:                              '%'
-    alt:                                '%'
-    shift+alt:                          '%'
-}
-
-key 6 {
-    label:                              '6'
-    number:                             '6'
-    base:                               '6'
-    shift:                              '^'
-    alt:                                '^'
-    shift+alt:                          '^'
-}
-
-key 7 {
-    label:                              '7'
-    number:                             '7'
-    base:                               '7'
-    shift:                              '&'
-    alt:                                '&'
-    shift+alt:                          '&'
-}
-
-key 8 {
-    label:                              '8'
-    number:                             '8'
-    base:                               '8'
-    shift:                              '*'
-    alt:                                '*'
-    shift+alt:                          '*'
-}
-
-key 9 {
-    label:                              '9'
-    number:                             '9'
-    base:                               '9'
-    shift:                              '('
-    alt:                                '('
-    shift+alt:                          '('
-}
-
-key GRAVE {
-    label:                              '`'
-    number:                             '`'
-    base:                               '`'
-    shift:                              '~'
-    alt:                                '`'
-    shift+alt:                          '~'
-}
-
-key MINUS {
-    label:                              '-'
-    number:                             '-'
-    base:                               '-'
-    shift:                              '_'
-    alt:                                '-'
-    shift+alt:                          '_'
-}
-
-key EQUALS {
-    label:                              '='
-    number:                             '='
-    base:                               '='
-    shift:                              '+'
-    alt:                                '='
-    shift+alt:                          '+'
-}
-
-key LEFT_BRACKET {
-    label:                              '['
-    number:                             '['
-    base:                               '['
-    shift:                              '{'
-    alt:                                '['
-    shift+alt:                          '{'
-}
-
-key RIGHT_BRACKET {
-    label:                              ']'
-    number:                             ']'
-    base:                               ']'
-    shift:                              '}'
-    alt:                                ']'
-    shift+alt:                          '}'
-}
-
-key BACKSLASH {
-    label:                              '\\'
-    number:                             '\\'
-    base:                               '\\'
-    shift:                              '|'
-    alt:                                '\\'
-    shift+alt:                          '|'
-}
-
-key SEMICOLON {
-    label:                              ';'
-    number:                             ';'
-    base:                               ';'
-    shift:                              ':'
-    alt:                                ';'
-    shift+alt:                          ':'
-}
-
-key APOSTROPHE {
-    label:                              '\''
-    number:                             '\''
-    base:                               '\''
-    shift:                              '"'
-    alt:                                '\''
-    shift+alt:                          '"'
-}
-
-key STAR {
-    label:                              '*'
-    number:                             '*'
-    base:                               '*'
-    shift:                              '*'
-    alt:                                '*'
-    shift+alt:                          '*'
-}
-
-key POUND {
-    label:                              '#'
-    number:                             '#'
-    base:                               '#'
-    shift:                              '#'
-    alt:                                '#'
-    shift+alt:                          '#'
-}
-
-key PLUS {
-    label:                              '+'
-    number:                             '+'
-    base:                               '+'
-    shift:                              '+'
-    alt:                                '+'
-    shift+alt:                          '+'
-}
diff --git a/data/keyboards/qwerty.kl b/data/keyboards/qwerty.kl
deleted file mode 100644
index 2fd99ab..0000000
--- a/data/keyboards/qwerty.kl
+++ /dev/null
@@ -1,131 +0,0 @@
-# Copyright (C) 2010 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.
-
-#
-# Emulator keyboard layout #1.
-#
-# This file is no longer used as the platform's default keyboard layout.
-# Refer to Generic.kl instead.
-#
-
-key 399   GRAVE
-key 2     1
-key 3     2
-key 4     3
-key 5     4
-key 6     5
-key 7     6
-key 8     7
-key 9     8
-key 10    9
-key 11    0
-key 158   BACK
-key 230   SOFT_RIGHT
-key 60    SOFT_LEFT
-key 107   ENDCALL
-key 62    ENDCALL
-key 229   MENU
-key 139   MENU
-key 59    MENU
-key 127   SEARCH
-key 217   SEARCH
-key 228   POUND
-key 227   STAR
-key 231   CALL
-key 61    CALL
-key 232   DPAD_CENTER
-key 108   DPAD_DOWN
-key 103   DPAD_UP
-key 102   HOME
-key 105   DPAD_LEFT
-key 106   DPAD_RIGHT
-key 115   VOLUME_UP
-key 114   VOLUME_DOWN
-key 116   POWER
-key 212   CAMERA
-
-key 16    Q
-key 17    W
-key 18    E
-key 19    R
-key 20    T
-key 21    Y
-key 22    U
-key 23    I
-key 24    O
-key 25    P
-key 26    LEFT_BRACKET
-key 27    RIGHT_BRACKET
-key 43    BACKSLASH
-
-key 30    A
-key 31    S
-key 32    D
-key 33    F
-key 34    G
-key 35    H
-key 36    J
-key 37    K
-key 38    L
-key 39    SEMICOLON
-key 40    APOSTROPHE
-key 14    DEL
-
-key 44    Z
-key 45    X
-key 46    C
-key 47    V
-key 48    B
-key 49    N
-key 50    M
-key 51    COMMA
-key 52    PERIOD
-key 53    SLASH
-key 28    ENTER
-
-key 56    ALT_LEFT
-key 100   ALT_RIGHT
-key 42    SHIFT_LEFT
-key 54    SHIFT_RIGHT
-key 15    TAB
-key 57    SPACE
-key 150   EXPLORER
-key 155   ENVELOPE
-
-key 12    MINUS
-key 13    EQUALS
-key 215   AT
-
-# On an AT keyboard: ESC, F10
-key 1     BACK
-key 68    MENU
-
-# App switch = Overview key
-key 580   APP_SWITCH
-
-# Media control keys
-key 160   MEDIA_CLOSE
-key 161   MEDIA_EJECT
-key 163   MEDIA_NEXT
-key 164   MEDIA_PLAY_PAUSE
-key 165   MEDIA_PREVIOUS
-key 166   MEDIA_STOP
-key 167   MEDIA_RECORD
-key 168   MEDIA_REWIND
-
-key 142   SLEEP
-key 581   STEM_PRIMARY
-key 582   STEM_1
-key 583   STEM_2
-key 584   STEM_3
diff --git a/data/keyboards/qwerty2.idc b/data/keyboards/qwerty2.idc
deleted file mode 100644
index 369205e..0000000
--- a/data/keyboards/qwerty2.idc
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2010 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.
-
-#
-# Emulator keyboard configuration file #2.
-#
-
-touch.deviceType = touchScreen
-touch.orientationAware = 1
-
-keyboard.layout = qwerty
-keyboard.characterMap = qwerty2
-keyboard.orientationAware = 1
-keyboard.builtIn = 1
-
-cursor.mode = navigation
-cursor.orientationAware = 1
diff --git a/data/keyboards/qwerty2.kcm b/data/keyboards/qwerty2.kcm
deleted file mode 100644
index b981d83..0000000
--- a/data/keyboards/qwerty2.kcm
+++ /dev/null
@@ -1,505 +0,0 @@
-# Copyright (C) 2010 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.
-
-#
-# Emulator keyboard character map #2.
-#
-
-type ALPHA
-
-key A {
-    label:                              'A'
-    number:                             '2'
-    base:                               'a'
-    shift, capslock:                    'A'
-    alt:                                '\u00e1'
-    shift+alt, capslock+alt:            '\u00c1'
-}
-
-key B {
-    label:                              'B'
-    number:                             '2'
-    base:                               'b'
-    shift, capslock:                    'B'
-    alt:                                'b'
-    shift+alt, capslock+alt:            'B'
-}
-
-key C {
-    label:                              'C'
-    number:                             '2'
-    base:                               'c'
-    shift, capslock:                    'C'
-    alt:                                '\u00a9'
-    shift+alt, capslock+alt:            '\u00a2'
-}
-
-key D {
-    label:                              'D'
-    number:                             '3'
-    base:                               'd'
-    shift, capslock:                    'D'
-    alt:                                '\u00f0'
-    shift+alt, capslock+alt:            '\u00d0'
-}
-
-key E {
-    label:                              'E'
-    number:                             '3'
-    base:                               'e'
-    shift, capslock:                    'E'
-    alt:                                '\u00e9'
-    shift+alt, capslock+alt:            '\u00c9'
-}
-
-key F {
-    label:                              'F'
-    number:                             '3'
-    base:                               'f'
-    shift, capslock:                    'F'
-    alt:                                '['
-    shift+alt, capslock+alt:            '['
-}
-
-key G {
-    label:                              'G'
-    number:                             '4'
-    base:                               'g'
-    shift, capslock:                    'G'
-    alt:                                ']'
-    shift+alt, capslock+alt:            ']'
-}
-
-key H {
-    label:                              'H'
-    number:                             '4'
-    base:                               'h'
-    shift, capslock:                    'H'
-    alt:                                '<'
-    shift+alt, capslock+alt:            '<'
-}
-
-key I {
-    label:                              'I'
-    number:                             '4'
-    base:                               'i'
-    shift, capslock:                    'I'
-    alt:                                '\u00ed'
-    shift+alt, capslock+alt:            '\u00cd'
-}
-
-key J {
-    label:                              'J'
-    number:                             '5'
-    base:                               'j'
-    shift, capslock:                    'J'
-    alt:                                '>'
-    shift+alt, capslock+alt:            '>'
-}
-
-key K {
-    label:                              'K'
-    number:                             '5'
-    base:                               'k'
-    shift, capslock:                    'K'
-    alt:                                ';'
-    shift+alt, capslock+alt:            '~'
-}
-
-key L {
-    label:                              'L'
-    number:                             '5'
-    base:                               'l'
-    shift, capslock:                    'L'
-    alt:                                '\u00f8'
-    shift+alt, capslock+alt:            '\u00d8'
-}
-
-key M {
-    label:                              'M'
-    number:                             '6'
-    base:                               'm'
-    shift, capslock:                    'M'
-    alt:                                '\u00b5'
-    shift+alt, capslock+alt:            none
-}
-
-key N {
-    label:                              'N'
-    number:                             '6'
-    base:                               'n'
-    shift, capslock:                    'N'
-    alt:                                '\u00f1'
-    shift+alt, capslock+alt:            '\u00d1'
-}
-
-key O {
-    label:                              'O'
-    number:                             '6'
-    base:                               'o'
-    shift, capslock:                    'O'
-    alt:                                '\u00f3'
-    shift+alt, capslock+alt:            '\u00d3'
-}
-
-key P {
-    label:                              'P'
-    number:                             '7'
-    base:                               'p'
-    shift, capslock:                    'P'
-    alt:                                '\u00f6'
-    shift+alt, capslock+alt:            '\u00d6'
-}
-
-key Q {
-    label:                              'Q'
-    number:                             '7'
-    base:                               'q'
-    shift, capslock:                    'Q'
-    alt:                                '\u00e4'
-    shift+alt, capslock+alt:            '\u00c4'
-}
-
-key R {
-    label:                              'R'
-    number:                             '7'
-    base:                               'r'
-    shift, capslock:                    'R'
-    alt:                                '\u00ae'
-    shift+alt, capslock+alt:            'R'
-}
-
-key S {
-    label:                              'S'
-    number:                             '7'
-    base:                               's'
-    shift, capslock:                    'S'
-    alt:                                '\u00df'
-    shift+alt, capslock+alt:            '\u00a7'
-}
-
-key T {
-    label:                              'T'
-    number:                             '8'
-    base:                               't'
-    shift, capslock:                    'T'
-    alt:                                '\u00fe'
-    shift+alt, capslock+alt:            '\u00de'
-}
-
-key U {
-    label:                              'U'
-    number:                             '8'
-    base:                               'u'
-    shift, capslock:                    'U'
-    alt:                                '\u00fa'
-    shift+alt, capslock+alt:            '\u00da'
-}
-
-key V {
-    label:                              'V'
-    number:                             '8'
-    base:                               'v'
-    shift, capslock:                    'V'
-    alt:                                'v'
-    shift+alt, capslock+alt:            'V'
-}
-
-key W {
-    label:                              'W'
-    number:                             '9'
-    base:                               'w'
-    shift, capslock:                    'W'
-    alt:                                '\u00e5'
-    shift+alt, capslock+alt:            '\u00c5'
-}
-
-key X {
-    label:                              'X'
-    number:                             '9'
-    base:                               'x'
-    shift, capslock:                    'X'
-    alt:                                'x'
-    shift+alt, capslock+alt:            '\uef00'
-}
-
-key Y {
-    label:                              'Y'
-    number:                             '9'
-    base:                               'y'
-    shift, capslock:                    'Y'
-    alt:                                '\u00fc'
-    shift+alt, capslock+alt:            '\u00dc'
-}
-
-key Z {
-    label:                              'Z'
-    number:                             '9'
-    base:                               'z'
-    shift, capslock:                    'Z'
-    alt:                                '\u00e6'
-    shift+alt, capslock+alt:            '\u00c6'
-}
-
-key COMMA {
-    label:                              ','
-    number:                             ','
-    base:                               ','
-    shift:                              '<'
-    alt:                                '\u00e7'
-    shift+alt:                          '\u00c7'
-}
-
-key PERIOD {
-    label:                              '.'
-    number:                             '.'
-    base:                               '.'
-    shift:                              '>'
-    alt:                                '.'
-    shift+alt:                          '\u2026'
-}
-
-key AT {
-    label:                              '@'
-    number:                             '@'
-    base:                               '@'
-    shift:                              '@'
-    alt:                                '@'
-    shift+alt:                          '\u2022'
-}
-
-key SLASH {
-    label:                              '/'
-    number:                             '/'
-    base:                               '/'
-    shift:                              '?'
-    alt:                                '\u00bf'
-    shift+alt:                          '?'
-}
-
-key SPACE {
-    label:                              ' '
-    number:                             ' '
-    base:                               ' '
-    shift:                              ' '
-    alt:                                '\uef01'
-    shift+alt:                          '\uef01'
-}
-
-key ENTER {
-    label:                              '\n'
-    number:                             '\n'
-    base:                               '\n'
-    shift:                              '\n'
-    alt:                                '\n'
-    shift+alt:                          '\n'
-}
-
-key TAB {
-    label:                              '\t'
-    number:                             '\t'
-    base:                               '\t'
-    shift:                              '\t'
-    alt:                                '\t'
-    shift+alt:                          '\t'
-}
-
-key 0 {
-    label:                              '0'
-    number:                             '0'
-    base:                               '0'
-    shift:                              ')'
-    alt:                                '\u02bc'
-    shift+alt:                          ')'
-}
-
-key 1 {
-    label:                              '1'
-    number:                             '1'
-    base:                               '1'
-    shift:                              '!'
-    alt:                                '\u00a1'
-    shift+alt:                          '\u00b9'
-}
-
-key 2 {
-    label:                              '2'
-    number:                             '2'
-    base:                               '2'
-    shift:                              '@'
-    alt:                                '\u00b2'
-    shift+alt:                          '@'
-}
-
-key 3 {
-    label:                              '3'
-    number:                             '3'
-    base:                               '3'
-    shift:                              '#'
-    alt:                                '\u00b3'
-    shift+alt:                          '#'
-}
-
-key 4 {
-    label:                              '4'
-    number:                             '4'
-    base:                               '4'
-    shift:                              '$'
-    alt:                                '\u00a4'
-    shift+alt:                          '\u00a3'
-}
-
-key 5 {
-    label:                              '5'
-    number:                             '5'
-    base:                               '5'
-    shift:                              '%'
-    alt:                                '\u20ac'
-    shift+alt:                          '%'
-}
-
-key 6 {
-    label:                              '6'
-    number:                             '6'
-    base:                               '6'
-    shift:                              '^'
-    alt:                                '\u00bc'
-    shift+alt:                          '\u0302'
-}
-
-key 7 {
-    label:                              '7'
-    number:                             '7'
-    base:                               '7'
-    shift:                              '&'
-    alt:                                '\u00bd'
-    shift+alt:                          '&'
-}
-
-key 8 {
-    label:                              '8'
-    number:                             '8'
-    base:                               '8'
-    shift:                              '*'
-    alt:                                '\u00be'
-    shift+alt:                          '*'
-}
-
-key 9 {
-    label:                              '9'
-    number:                             '9'
-    base:                               '9'
-    shift:                              '('
-    alt:                                '\u02bb'
-    shift+alt:                          '('
-}
-
-key GRAVE {
-    label:                              '`'
-    number:                             '`'
-    base:                               '`'
-    shift:                              '~'
-    alt:                                '\u0300'
-    shift+alt:                          '\u0303'
-}
-
-key MINUS {
-    label:                              '-'
-    number:                             '-'
-    base:                               '-'
-    shift:                              '_'
-    alt:                                '\u00a5'
-    shift+alt:                          '_'
-}
-
-key EQUALS {
-    label:                              '='
-    number:                             '='
-    base:                               '='
-    shift:                              '+'
-    alt:                                '\u00d7'
-    shift+alt:                          '\u00f7'
-}
-
-key LEFT_BRACKET {
-    label:                              '['
-    number:                             '['
-    base:                               '['
-    shift:                              '{'
-    alt:                                '\u00ab'
-    shift+alt:                          '{'
-}
-
-key RIGHT_BRACKET {
-    label:                              ']'
-    number:                             ']'
-    base:                               ']'
-    shift:                              '}'
-    alt:                                '\u00bb'
-    shift+alt:                          '}'
-}
-
-key BACKSLASH {
-    label:                              '\\'
-    number:                             '\\'
-    base:                               '\\'
-    shift:                              '|'
-    alt:                                '\u00ac'
-    shift+alt:                          '\u00a6'
-}
-
-key SEMICOLON {
-    label:                              ';'
-    number:                             ';'
-    base:                               ';'
-    shift:                              ':'
-    alt:                                '\u00b6'
-    shift+alt:                          '\u00b0'
-}
-
-key APOSTROPHE {
-    label:                              '\''
-    number:                             '\''
-    base:                               '\''
-    shift:                              '"'
-    alt:                                '\u0301'
-    shift+alt:                          '\u0308'
-}
-
-key STAR {
-    label:                              '*'
-    number:                             '*'
-    base:                               '*'
-    shift:                              '*'
-    alt:                                '*'
-    shift+alt:                          '*'
-}
-
-key POUND {
-    label:                              '#'
-    number:                             '#'
-    base:                               '#'
-    shift:                              '#'
-    alt:                                '#'
-    shift+alt:                          '#'
-}
-
-key PLUS {
-    label:                              '+'
-    number:                             '+'
-    base:                               '+'
-    shift:                              '+'
-    alt:                                '+'
-    shift+alt:                          '+'
-}
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index dc2185ea..daed277 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -99,6 +99,13 @@
   StringPoolRef entry_string_ref;
 };
 
+struct Theme::Entry {
+  uint32_t attr_res_id;
+  ApkAssetsCookie cookie;
+  uint32_t type_spec_flags;
+  Res_value value;
+};
+
 AssetManager2::AssetManager2() {
   memset(&configuration_, 0, sizeof(configuration_));
 }
@@ -1411,13 +1418,6 @@
 
 Theme::~Theme() = default;
 
-struct Theme::Entry {
-  uint32_t attr_res_id;
-  ApkAssetsCookie cookie;
-  uint32_t type_spec_flags;
-  Res_value value;
-};
-
 namespace {
 struct ThemeEntryKeyComparer {
   bool operator() (const Theme::Entry& entry, uint32_t attr_res_id) const noexcept {
diff --git a/packages/CredentialManager/horologist/OWNERS b/packages/CredentialManager/horologist/OWNERS
new file mode 100644
index 0000000..b679328
--- /dev/null
+++ b/packages/CredentialManager/horologist/OWNERS
@@ -0,0 +1,4 @@
+include /core/java/android/credentials/OWNERS
+
+shuanghao@google.com
+gustavopagani@google.com
diff --git a/packages/CredentialManager/shared/OWNERS b/packages/CredentialManager/shared/OWNERS
new file mode 100644
index 0000000..b679328
--- /dev/null
+++ b/packages/CredentialManager/shared/OWNERS
@@ -0,0 +1,4 @@
+include /core/java/android/credentials/OWNERS
+
+shuanghao@google.com
+gustavopagani@google.com
diff --git a/packages/CredentialManager/wear/OWNERS b/packages/CredentialManager/wear/OWNERS
new file mode 100644
index 0000000..b679328
--- /dev/null
+++ b/packages/CredentialManager/wear/OWNERS
@@ -0,0 +1,4 @@
+include /core/java/android/credentials/OWNERS
+
+shuanghao@google.com
+gustavopagani@google.com
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 0cd8b45..5b2409a 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -6,6 +6,7 @@
 
 aaliomer@google.com
 aaronjli@google.com
+achalke@google.com
 acul@google.com
 adamcohen@google.com
 aioana@google.com
@@ -72,6 +73,7 @@
 patmanning@google.com
 peanutbutter@google.com
 peskal@google.com
+petrcermak@google.com
 pinyaoting@google.com
 pixel@google.com
 pomini@google.com
@@ -83,14 +85,17 @@
 shanh@google.com
 snoeberger@google.com
 steell@google.com
+stevenckng@google.com
 stwu@google.com
 syeonlee@google.com
 sunnygoyal@google.com
 thiruram@google.com
+tkachenkoi@google.com
 tracyzhou@google.com
 tsuji@google.com
 twickham@google.com
 vadimt@google.com
+vanjan@google.com
 victortulias@google.com
 winsonc@google.com
 wleshner@google.com
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a08f540..6507488 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -549,6 +549,18 @@
         dispatchErrorMessage(message);
     }
 
+    @Override
+    public void onEnabledTrustAgentsChanged(int userId) {
+        Assert.isMainThread();
+
+        for (int i = 0; i < mCallbacks.size(); i++) {
+            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+            if (cb != null) {
+                cb.onEnabledTrustAgentsChanged(userId);
+            }
+        }
+    }
+
     private void handleSimSubscriptionInfoChanged() {
         Assert.isMainThread();
         mLogger.v("onSubscriptionInfoChanged()");
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index feff216..7394005 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -322,4 +322,9 @@
      * Called when keyguard is going away or not going away.
      */
     public void onKeyguardGoingAway() { }
+
+    /**
+     * Called when the enabled trust agents associated with the specified user.
+     */
+    public void onEnabledTrustAgentsChanged(int userId) { }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
index d90f328..e912053 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/data/repository/TrustRepository.kt
@@ -75,6 +75,8 @@
                         override fun onTrustError(message: CharSequence?) = Unit
 
                         override fun onTrustManagedChanged(enabled: Boolean, userId: Int) = Unit
+
+                        override fun onEnabledTrustAgentsChanged(userId: Int) = Unit
                     }
                 trustManager.registerTrustListener(callback)
                 logger.trustListenerRegistered()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index f1269f2..f4cf4ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -452,5 +452,10 @@
         public void onBiometricsCleared() {
             update(false /* alwaysUpdate */);
         }
+
+        @Override
+        public void onEnabledTrustAgentsChanged(int userId) {
+            update(false /* updateAlways */);
+        }
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index b1051af..417eb40 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -144,6 +144,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
+import java.util.Random;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -722,6 +723,18 @@
     }
 
     @Test
+    public void testOnEnabledTrustAgentsChangedCallback() {
+        final Random random = new Random();
+        final int userId = random.nextInt();
+        final KeyguardUpdateMonitorCallback callback = mock(KeyguardUpdateMonitorCallback.class);
+
+        mKeyguardUpdateMonitor.registerCallback(callback);
+        mKeyguardUpdateMonitor.onEnabledTrustAgentsChanged(userId);
+
+        verify(callback).onEnabledTrustAgentsChanged(eq(userId));
+    }
+
+    @Test
     public void trustAgentHasTrust_fingerprintLockout() {
         // GIVEN user has trust
         mKeyguardUpdateMonitor.onTrustChanged(true, true, getCurrentUser(), 0, null);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
index 8f363ef..d787ada 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardStateControllerTest.java
@@ -31,18 +31,23 @@
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 
+import dagger.Lazy;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import dagger.Lazy;
+import java.util.Random;
+
 
 @SmallTest
 @TestableLooper.RunWithLooper
@@ -169,4 +174,19 @@
         verify(callback).onKeyguardDismissAmountChanged();
     }
 
+    @Test
+    public void testOnEnabledTrustAgentsChangedCallback() {
+        final Random random = new Random();
+        final ArgumentCaptor<KeyguardUpdateMonitorCallback> updateCallbackCaptor =
+                ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
+
+        verify(mKeyguardUpdateMonitor).registerCallback(updateCallbackCaptor.capture());
+        final KeyguardStateController.Callback stateCallback =
+                mock(KeyguardStateController.Callback.class);
+        mKeyguardStateController.addCallback(stateCallback);
+
+        when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
+        updateCallbackCaptor.getValue().onEnabledTrustAgentsChanged(random.nextInt());
+        verify(stateCallback).onUnlockedChanged();
+    }
 }
diff --git a/services/backup/backuplib/java/com/android/server/backup/TransportManager.java b/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
index 930f49e..ff5f509f 100644
--- a/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
+++ b/services/backup/backuplib/java/com/android/server/backup/TransportManager.java
@@ -706,6 +706,9 @@
         try {
             String transportName = transport.name();
             String transportDirName = transport.transportDirName();
+            if (transportName == null || transportDirName == null) {
+                return BackupManager.ERROR_TRANSPORT_INVALID;
+            }
             registerTransport(transportComponent, transport);
             // If registerTransport() hasn't thrown...
             Slog.d(TAG, "Transport " + transportString + " registered");
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
index 846c2d9..a53d096 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
@@ -433,6 +433,11 @@
     }
 
     @Override
+    public void onEnabledTrustAgentsChanged(int userId) {
+
+    }
+
+    @Override
     @NonNull
     public List<FingerprintSensorPropertiesInternal> getSensorProperties() {
         final List<FingerprintSensorPropertiesInternal> properties = new ArrayList<>();
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index bfccd58..53fbe8f 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1741,6 +1741,7 @@
                 .setBypassableVpn(bypassable)
                 .setVpnRequiresValidation(mConfig.requiresInternetValidation)
                 .setLocalRoutesExcludedForVpn(mConfig.excludeLocalRoutes)
+                .setLegacyExtraInfo("VPN:" + mPackage)
                 .build();
 
         capsBuilder.setOwnerUid(mOwnerUID);
diff --git a/services/core/java/com/android/server/security/OWNERS b/services/core/java/com/android/server/security/OWNERS
index f408d7c..fa4bf22 100644
--- a/services/core/java/com/android/server/security/OWNERS
+++ b/services/core/java/com/android/server/security/OWNERS
@@ -4,3 +4,4 @@
 
 per-file *AttestationVerification* = file:/core/java/android/security/attestationverification/OWNERS
 per-file FileIntegrity*.java = victorhsieh@google.com
+per-file KeyChainSystemService.java = file:platform/packages/apps/KeyChain:/OWNERS
diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
index 86eb36c93..23cb91d 100644
--- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java
+++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java
@@ -49,6 +49,7 @@
 import android.util.Slog;
 
 import com.android.internal.infra.AndroidFuture;
+import com.android.server.utils.Slogf;
 
 import java.util.Collections;
 import java.util.List;
@@ -318,8 +319,8 @@
                 int flags,
                 AndroidFuture resultCallback) {
             if (DEBUG) {
-                Slog.d(TAG, "enableTrust(" + message + ", durationMs = " + durationMs
-                        + ", flags = " + flags + ")");
+                Slogf.d(TAG, "grantTrust(message=\"%s\", durationMs=%d, flags=0x%x)",
+                        message, durationMs, flags);
             }
 
             Message msg = mHandler.obtainMessage(
@@ -336,30 +337,32 @@
 
         @Override
         public void lockUser() {
+            if (DEBUG) Slog.d(TAG, "lockUser()");
             mHandler.sendEmptyMessage(MSG_LOCK_USER);
         }
 
         @Override
         public void setManagingTrust(boolean managingTrust) {
-            if (DEBUG) Slog.d(TAG, "managingTrust()");
+            if (DEBUG) Slogf.d(TAG, "setManagingTrust(%s)", managingTrust);
             mHandler.obtainMessage(MSG_MANAGING_TRUST, managingTrust ? 1 : 0, 0).sendToTarget();
         }
 
         @Override
         public void onConfigureCompleted(boolean result, IBinder token) {
-            if (DEBUG) Slog.d(TAG, "onSetTrustAgentFeaturesEnabledCompleted(result=" + result);
+            if (DEBUG) Slogf.d(TAG, "onConfigureCompleted(result=%s)", result);
             mHandler.obtainMessage(MSG_SET_TRUST_AGENT_FEATURES_COMPLETED,
                     result ? 1 : 0, 0, token).sendToTarget();
         }
 
         @Override
         public void addEscrowToken(byte[] token, int userId) {
+            // 'token' is secret; never log it.
+            if (DEBUG) Slogf.d(TAG, "addEscrowToken(userId=%d)", userId);
+
             if (mContext.getResources()
                     .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
-                throw  new SecurityException("Escrow token API is not allowed.");
+                throw new SecurityException("Escrow token API is not allowed.");
             }
-
-            if (DEBUG) Slog.d(TAG, "adding escrow token for user " + userId);
             Message msg = mHandler.obtainMessage(MSG_ADD_ESCROW_TOKEN);
             msg.getData().putByteArray(DATA_ESCROW_TOKEN, token);
             msg.getData().putInt(DATA_USER_ID, userId);
@@ -368,12 +371,12 @@
 
         @Override
         public void isEscrowTokenActive(long handle, int userId) {
+            if (DEBUG) Slogf.d(TAG, "isEscrowTokenActive(handle=%016x, userId=%d)", handle, userId);
+
             if (mContext.getResources()
                     .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
                 throw new SecurityException("Escrow token API is not allowed.");
             }
-
-            if (DEBUG) Slog.d(TAG, "checking the state of escrow token on user " + userId);
             Message msg = mHandler.obtainMessage(MSG_ESCROW_TOKEN_STATE);
             msg.getData().putLong(DATA_HANDLE, handle);
             msg.getData().putInt(DATA_USER_ID, userId);
@@ -382,12 +385,12 @@
 
         @Override
         public void removeEscrowToken(long handle, int userId) {
+            if (DEBUG) Slogf.d(TAG, "removeEscrowToken(handle=%016x, userId=%d)", handle, userId);
+
             if (mContext.getResources()
                     .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
                 throw new SecurityException("Escrow token API is not allowed.");
             }
-
-            if (DEBUG) Slog.d(TAG, "removing escrow token on user " + userId);
             Message msg = mHandler.obtainMessage(MSG_REMOVE_ESCROW_TOKEN);
             msg.getData().putLong(DATA_HANDLE, handle);
             msg.getData().putInt(DATA_USER_ID, userId);
@@ -396,12 +399,13 @@
 
         @Override
         public void unlockUserWithToken(long handle, byte[] token, int userId) {
+            // 'token' is secret; never log it.
+            if (DEBUG) Slogf.d(TAG, "unlockUserWithToken(handle=%016x, userId=%d)", handle, userId);
+
             if (mContext.getResources()
                     .getBoolean(com.android.internal.R.bool.config_allowEscrowTokenForTrustAgent)) {
                 throw new SecurityException("Escrow token API is not allowed.");
             }
-
-            if (DEBUG) Slog.d(TAG, "unlocking user " + userId);
             Message msg = mHandler.obtainMessage(MSG_UNLOCK_USER);
             msg.getData().putInt(DATA_USER_ID, userId);
             msg.getData().putLong(DATA_HANDLE, handle);
@@ -411,7 +415,7 @@
 
         @Override
         public void showKeyguardErrorMessage(CharSequence message) {
-            if (DEBUG) Slog.d(TAG, "Showing keyguard error message: " + message);
+            if (DEBUG) Slogf.d(TAG, "showKeyguardErrorMessage(\"%s\")", message);
             Message msg = mHandler.obtainMessage(MSG_SHOW_KEYGUARD_ERROR_MESSAGE);
             msg.getData().putCharSequence(DATA_MESSAGE, message);
             msg.sendToTarget();
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 04cd7f7..e3abf0c 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -53,6 +53,7 @@
 import android.os.DeadObjectException;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
@@ -150,6 +151,8 @@
     private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
     private final Receiver mReceiver = new Receiver();
 
+    private final Handler mHandler;
+
     /* package */ final TrustArchive mArchive = new TrustArchive();
     private final Context mContext;
     private final LockPatternUtils mLockPatternUtils;
@@ -158,10 +161,26 @@
     private VirtualDeviceManagerInternal mVirtualDeviceManager;
 
     private enum TrustState {
-        UNTRUSTED, // the phone is not unlocked by any trustagents
-        TRUSTABLE, // the phone is in a semi-locked state that can be unlocked if
-        // FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE is passed and a trustagent is trusted
-        TRUSTED // the phone is unlocked
+        // UNTRUSTED means that TrustManagerService is currently *not* giving permission for the
+        // user's Keyguard to be dismissed, and grants of trust by trust agents are remembered in
+        // the corresponding TrustAgentWrapper but are not recognized until the device is unlocked
+        // for the user.  I.e., if the device is locked and the state is UNTRUSTED, it cannot be
+        // unlocked by a trust agent.  Automotive devices are an exception; grants of trust are
+        // always recognized on them.
+        UNTRUSTED,
+
+        // TRUSTABLE is the same as UNTRUSTED except that new grants of trust using
+        // FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE are recognized for moving to TRUSTED.  I.e., if
+        // the device is locked and the state is TRUSTABLE, it can be unlocked by a trust agent,
+        // provided that the trust agent chooses to use Active Unlock.  The TRUSTABLE state is only
+        // possible as a result of a downgrade from TRUSTED, after a trust agent used
+        // FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE in its most recent grant.
+        TRUSTABLE,
+
+        // TRUSTED means that TrustManagerService is currently giving permission for the user's
+        // Keyguard to be dismissed.  This implies that the device is unlocked for the user (where
+        // the case of Keyguard showing but dismissible just with swipe counts as "unlocked").
+        TRUSTED
     };
 
     @GuardedBy("mUserTrustState")
@@ -224,13 +243,40 @@
     private boolean mTrustAgentsCanRun = false;
     private int mCurrentUser = UserHandle.USER_SYSTEM;
 
+    /**
+     * A class for providing dependencies to {@link TrustManagerService} in both production and test
+     * cases.
+     */
+    protected static class Injector {
+        private final LockPatternUtils mLockPatternUtils;
+        private final Looper mLooper;
+
+        public Injector(LockPatternUtils lockPatternUtils, Looper looper) {
+            mLockPatternUtils = lockPatternUtils;
+            mLooper = looper;
+        }
+
+        LockPatternUtils getLockPatternUtils() {
+            return mLockPatternUtils;
+        }
+
+        Looper getLooper() {
+            return mLooper;
+        }
+    }
+
     public TrustManagerService(Context context) {
+        this(context, new Injector(new LockPatternUtils(context), Looper.myLooper()));
+    }
+
+    protected TrustManagerService(Context context, Injector injector) {
         super(context);
         mContext = context;
+        mHandler = createHandler(injector.getLooper());
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
-        mLockPatternUtils = new LockPatternUtils(context);
-        mStrongAuthTracker = new StrongAuthTracker(context);
+        mLockPatternUtils = injector.getLockPatternUtils();
+        mStrongAuthTracker = new StrongAuthTracker(context, injector.getLooper());
         mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
         mSettingsObserver = new SettingsObserver(mHandler);
     }
@@ -814,6 +860,12 @@
         }
     }
 
+    private TrustState getUserTrustStateInner(int userId) {
+        synchronized (mUserTrustState) {
+            return mUserTrustState.get(userId, TrustState.UNTRUSTED);
+        }
+    }
+
     boolean isDeviceLockedInner(int userId) {
         synchronized (mDeviceLockedForUser) {
             return mDeviceLockedForUser.get(userId, true);
@@ -864,7 +916,12 @@
                 continue;
             }
 
-            boolean trusted = aggregateIsTrusted(id);
+            final boolean trusted;
+            if (android.security.Flags.fixUnlockedDeviceRequiredKeys()) {
+                trusted = getUserTrustStateInner(id) == TrustState.TRUSTED;
+            } else {
+                trusted = aggregateIsTrusted(id);
+            }
             boolean showingKeyguard = true;
             boolean biometricAuthenticated = false;
             boolean currentUserIsUnlocked = false;
@@ -1365,6 +1422,23 @@
         }
     }
 
+    private void dispatchOnEnabledTrustAgentsChanged(int userId) {
+        if (DEBUG) {
+            Log.i(TAG, "onEnabledTrustAgentsChanged(" + userId + ")");
+        }
+        for (int i = 0; i < mTrustListeners.size(); i++) {
+            try {
+                mTrustListeners.get(i).onEnabledTrustAgentsChanged(userId);
+            } catch (DeadObjectException e) {
+                Slog.d(TAG, "Removing dead TrustListener.");
+                mTrustListeners.remove(i);
+                i--;
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Exception while notifying TrustListener.", e);
+            }
+        }
+    }
+
     private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
         if (DEBUG) {
             Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
@@ -1468,9 +1542,7 @@
         @Override
         public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
             enforceReportPermission();
-            // coalesce refresh messages.
-            mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
-            mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
+            mHandler.obtainMessage(MSG_ENABLED_AGENTS_CHANGED, userId, 0).sendToTarget();
         }
 
         @Override
@@ -1628,7 +1700,7 @@
             if (isCurrent) {
                 fout.print(" (current)");
             }
-            fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
+            fout.print(": trustState=" + getUserTrustStateInner(user.id));
             fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
             fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
             fout.print(", strongAuthRequired=" + dumpHex(
@@ -1781,88 +1853,91 @@
         }
     }
 
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_REGISTER_LISTENER:
-                    addListener((ITrustListener) msg.obj);
-                    break;
-                case MSG_UNREGISTER_LISTENER:
-                    removeListener((ITrustListener) msg.obj);
-                    break;
-                case MSG_DISPATCH_UNLOCK_ATTEMPT:
-                    dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
-                    break;
-                case MSG_USER_REQUESTED_UNLOCK:
-                    dispatchUserRequestedUnlock(msg.arg1, msg.arg2 != 0);
-                    break;
-                case MSG_USER_MAY_REQUEST_UNLOCK:
-                    dispatchUserMayRequestUnlock(msg.arg1);
-                    break;
-                case MSG_DISPATCH_UNLOCK_LOCKOUT:
-                    dispatchUnlockLockout(msg.arg1, msg.arg2);
-                    break;
-                case MSG_ENABLED_AGENTS_CHANGED:
-                    refreshAgentList(UserHandle.USER_ALL);
-                    // This is also called when the security mode of a user changes.
-                    refreshDeviceLockedForUser(UserHandle.USER_ALL);
-                    break;
-                case MSG_KEYGUARD_SHOWING_CHANGED:
-                    dispatchTrustableDowngrade();
-                    refreshDeviceLockedForUser(mCurrentUser);
-                    break;
-                case MSG_START_USER:
-                case MSG_CLEANUP_USER:
-                case MSG_UNLOCK_USER:
-                    refreshAgentList(msg.arg1);
-                    break;
-                case MSG_SWITCH_USER:
-                    mCurrentUser = msg.arg1;
-                    mSettingsObserver.updateContentObserver();
-                    refreshDeviceLockedForUser(UserHandle.USER_ALL);
-                    break;
-                case MSG_STOP_USER:
-                    setDeviceLockedForUser(msg.arg1, true);
-                    break;
-                case MSG_FLUSH_TRUST_USUALLY_MANAGED:
-                    SparseBooleanArray usuallyManaged;
-                    synchronized (mTrustUsuallyManagedForUser) {
-                        usuallyManaged = mTrustUsuallyManagedForUser.clone();
-                    }
-
-                    for (int i = 0; i < usuallyManaged.size(); i++) {
-                        int userId = usuallyManaged.keyAt(i);
-                        boolean value = usuallyManaged.valueAt(i);
-                        if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
-                            mLockPatternUtils.setTrustUsuallyManaged(value, userId);
+    private Handler createHandler(Looper looper) {
+        return new Handler(looper) {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_REGISTER_LISTENER:
+                        addListener((ITrustListener) msg.obj);
+                        break;
+                    case MSG_UNREGISTER_LISTENER:
+                        removeListener((ITrustListener) msg.obj);
+                        break;
+                    case MSG_DISPATCH_UNLOCK_ATTEMPT:
+                        dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
+                        break;
+                    case MSG_USER_REQUESTED_UNLOCK:
+                        dispatchUserRequestedUnlock(msg.arg1, msg.arg2 != 0);
+                        break;
+                    case MSG_USER_MAY_REQUEST_UNLOCK:
+                        dispatchUserMayRequestUnlock(msg.arg1);
+                        break;
+                    case MSG_DISPATCH_UNLOCK_LOCKOUT:
+                        dispatchUnlockLockout(msg.arg1, msg.arg2);
+                        break;
+                    case MSG_ENABLED_AGENTS_CHANGED:
+                        refreshAgentList(UserHandle.USER_ALL);
+                        // This is also called when the security mode of a user changes.
+                        refreshDeviceLockedForUser(UserHandle.USER_ALL);
+                        dispatchOnEnabledTrustAgentsChanged(msg.arg1);
+                        break;
+                    case MSG_KEYGUARD_SHOWING_CHANGED:
+                        dispatchTrustableDowngrade();
+                        refreshDeviceLockedForUser(mCurrentUser);
+                        break;
+                    case MSG_START_USER:
+                    case MSG_CLEANUP_USER:
+                    case MSG_UNLOCK_USER:
+                        refreshAgentList(msg.arg1);
+                        break;
+                    case MSG_SWITCH_USER:
+                        mCurrentUser = msg.arg1;
+                        mSettingsObserver.updateContentObserver();
+                        refreshDeviceLockedForUser(UserHandle.USER_ALL);
+                        break;
+                    case MSG_STOP_USER:
+                        setDeviceLockedForUser(msg.arg1, true);
+                        break;
+                    case MSG_FLUSH_TRUST_USUALLY_MANAGED:
+                        SparseBooleanArray usuallyManaged;
+                        synchronized (mTrustUsuallyManagedForUser) {
+                            usuallyManaged = mTrustUsuallyManagedForUser.clone();
                         }
-                    }
-                    break;
-                case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
-                    if (msg.arg2 == 1) {
-                        updateTrust(msg.arg1, 0 /* flags */, true /* isFromUnlock */, null);
-                    }
-                    final int unlockedUser = msg.getData().getInt(
-                            REFRESH_DEVICE_LOCKED_EXCEPT_USER, UserHandle.USER_NULL);
-                    refreshDeviceLockedForUser(msg.arg1, unlockedUser);
-                    break;
-                case MSG_SCHEDULE_TRUST_TIMEOUT:
-                    boolean shouldOverride = msg.arg1 == 1 ? true : false;
-                    TimeoutType timeoutType =
-                            msg.arg2 == 1 ? TimeoutType.TRUSTABLE : TimeoutType.TRUSTED;
-                    handleScheduleTrustTimeout(shouldOverride, timeoutType);
-                    break;
-                case MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH:
-                    TrustableTimeoutAlarmListener trustableAlarm =
-                            mTrustableTimeoutAlarmListenerForUser.get(msg.arg1);
-                    if (trustableAlarm != null && trustableAlarm.isQueued()) {
-                        refreshTrustableTimers(msg.arg1);
-                    }
-                    break;
+
+                        for (int i = 0; i < usuallyManaged.size(); i++) {
+                            int userId = usuallyManaged.keyAt(i);
+                            boolean value = usuallyManaged.valueAt(i);
+                            if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
+                                mLockPatternUtils.setTrustUsuallyManaged(value, userId);
+                            }
+                        }
+                        break;
+                    case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
+                        if (msg.arg2 == 1) {
+                            updateTrust(msg.arg1, 0 /* flags */, true /* isFromUnlock */, null);
+                        }
+                        final int unlockedUser = msg.getData().getInt(
+                                REFRESH_DEVICE_LOCKED_EXCEPT_USER, UserHandle.USER_NULL);
+                        refreshDeviceLockedForUser(msg.arg1, unlockedUser);
+                        break;
+                    case MSG_SCHEDULE_TRUST_TIMEOUT:
+                        boolean shouldOverride = msg.arg1 == 1 ? true : false;
+                        TimeoutType timeoutType =
+                                msg.arg2 == 1 ? TimeoutType.TRUSTABLE : TimeoutType.TRUSTED;
+                        handleScheduleTrustTimeout(shouldOverride, timeoutType);
+                        break;
+                    case MSG_REFRESH_TRUSTABLE_TIMERS_AFTER_AUTH:
+                        TrustableTimeoutAlarmListener trustableAlarm =
+                                mTrustableTimeoutAlarmListenerForUser.get(msg.arg1);
+                        if (trustableAlarm != null && trustableAlarm.isQueued()) {
+                            refreshTrustableTimers(msg.arg1);
+                        }
+                        break;
+                }
             }
-        }
-    };
+        };
+    }
 
     private final PackageMonitor mPackageMonitor = new PackageMonitor() {
         @Override
@@ -1960,8 +2035,8 @@
 
         SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
 
-        public StrongAuthTracker(Context context) {
-            super(context);
+        StrongAuthTracker(Context context, Looper looper) {
+            super(context, looper);
         }
 
         @Override
diff --git a/services/tests/mockingservicestests/src/com/android/server/trust/OWNERS b/services/tests/mockingservicestests/src/com/android/server/trust/OWNERS
new file mode 100644
index 0000000..e2c6ce1
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/trust/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/trust/OWNERS
diff --git a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
index 33870f1..9851bc1 100644
--- a/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/trust/TrustManagerServiceTest.java
@@ -16,15 +16,26 @@
 
 package com.android.server.trust;
 
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.argThat;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.ArgumentMatchers.anyBoolean;
+
+import android.Manifest;
 import android.annotation.Nullable;
+import android.app.trust.ITrustListener;
+import android.app.trust.ITrustManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -36,11 +47,16 @@
 import android.content.pm.ServiceInfo;
 import android.net.Uri;
 import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.os.test.TestLooper;
 import android.provider.Settings;
 import android.service.trust.TrustAgentService;
 import android.testing.TestableContext;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
 
 import androidx.test.core.app.ApplicationProvider;
 
@@ -55,13 +71,16 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatcher;
 import org.mockito.Mock;
+import org.mockito.MockitoSession;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Random;
 
 public class TrustManagerServiceTest {
 
@@ -255,6 +274,43 @@
                 systemTrustAgent1);
     }
 
+    @Test
+    public void reportEnabledTrustAgentsChangedInformsListener() throws RemoteException {
+        final LockPatternUtils utils = mock(LockPatternUtils.class);
+        final TrustManagerService service = new TrustManagerService(mMockContext,
+                new TrustManagerService.Injector(utils, mLooper.getLooper()));
+        final ITrustListener trustListener = mock(ITrustListener.class);
+        final IWindowManager windowManager = mock(IWindowManager.class);
+        final int userId = new Random().nextInt();
+
+        mMockContext.getTestablePermissions().setPermission(Manifest.permission.TRUST_LISTENER,
+                PERMISSION_GRANTED);
+
+        when(utils.getKnownTrustAgents(anyInt())).thenReturn(new ArrayList<>());
+
+        MockitoSession mockSession = mockitoSession()
+                .initMocks(this)
+                .mockStatic(ServiceManager.class)
+                .mockStatic(WindowManagerGlobal.class)
+                .startMocking();
+
+        doReturn(windowManager).when(() -> {
+            WindowManagerGlobal.getWindowManagerService();
+        });
+
+        service.onStart();
+        ArgumentCaptor<IBinder> binderArgumentCaptor = ArgumentCaptor.forClass(IBinder.class);
+        verify(() -> ServiceManager.addService(eq(Context.TRUST_SERVICE),
+                binderArgumentCaptor.capture(), anyBoolean(), anyInt()));
+        ITrustManager manager = ITrustManager.Stub.asInterface(binderArgumentCaptor.getValue());
+        manager.registerTrustListener(trustListener);
+        mLooper.dispatchAll();
+        manager.reportEnabledTrustAgentsChanged(userId);
+        mLooper.dispatchAll();
+        verify(trustListener).onEnabledTrustAgentsChanged(eq(userId));
+        mockSession.finishMocking();
+    }
+
     private void addTrustAgent(ComponentName agentComponentName, boolean isSystemApp) {
         ApplicationInfo applicationInfo = new ApplicationInfo();
         if (isSystemApp) {
diff --git a/tests/TrustTests/Android.bp b/tests/TrustTests/Android.bp
index a1b888a..c216bce 100644
--- a/tests/TrustTests/Android.bp
+++ b/tests/TrustTests/Android.bp
@@ -25,6 +25,7 @@
         "androidx.test.rules",
         "androidx.test.ext.junit",
         "androidx.test.uiautomator_uiautomator",
+        "flag-junit",
         "mockito-target-minus-junit4",
         "servicestests-utils",
         "truth-prebuilt",
diff --git a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
index f864fed..1dfd5c0 100644
--- a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
+++ b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
@@ -16,6 +16,10 @@
 
 package android.trust.test
 
+import android.content.pm.PackageManager
+import android.platform.test.annotations.RequiresFlagsDisabled
+import android.platform.test.annotations.RequiresFlagsEnabled
+import android.platform.test.flag.junit.DeviceFlagsValueProvider
 import android.service.trust.GrantTrustResult
 import android.trust.BaseTrustAgentService
 import android.trust.TrustTestActivity
@@ -27,6 +31,7 @@
 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
 import androidx.test.uiautomator.UiDevice
 import com.android.server.testutils.mock
+import org.junit.Assume.assumeFalse
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -45,6 +50,7 @@
     private val activityScenarioRule = ActivityScenarioRule(TrustTestActivity::class.java)
     private val lockStateTrackingRule = LockStateTrackingRule()
     private val trustAgentRule = TrustAgentRule<GrantAndRevokeTrustAgent>()
+    private val packageManager = getInstrumentation().getTargetContext().getPackageManager()
 
     @get:Rule
     val rule: RuleChain = RuleChain
@@ -52,6 +58,7 @@
         .around(ScreenLockRule())
         .around(lockStateTrackingRule)
         .around(trustAgentRule)
+        .around(DeviceFlagsValueProvider.createCheckFlagsRule())
 
     @Before
     fun manageTrust() {
@@ -72,7 +79,7 @@
         trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 10000, 0) {}
         uiDevice.sleep()
 
-        lockStateTrackingRule.assertUnlocked()
+        lockStateTrackingRule.assertUnlockedAndTrusted()
     }
 
     @Test
@@ -86,6 +93,51 @@
     }
 
     @Test
+    @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS)
+    fun grantCannotActivelyUnlockDevice() {
+        // On automotive, trust agents can actively unlock the device.
+        assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE))
+
+        // Lock the device.
+        uiDevice.sleep()
+        lockStateTrackingRule.assertLocked()
+
+        // Grant trust.
+        trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 10000, 0) {}
+
+        // The grant should not have unlocked the device.  Wait a bit so that
+        // TrustManagerService probably will have finished processing the grant.
+        await()
+        lockStateTrackingRule.assertLocked()
+
+        // Turn the screen on and off to cause TrustManagerService to refresh
+        // its deviceLocked state.  Then verify the state is still locked.  This
+        // part failed before the fix for b/296464083.
+        uiDevice.wakeUp()
+        uiDevice.sleep()
+        await()
+        lockStateTrackingRule.assertLocked()
+    }
+
+    @Test
+    @RequiresFlagsDisabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS)
+    fun grantCouldCauseWrongDeviceLockedStateDueToBug() {
+        // On automotive, trust agents can actively unlock the device.
+        assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE))
+
+        // Verify that b/296464083 exists.  That is, when the device is locked
+        // and a trust agent grants trust, the deviceLocked state incorrectly
+        // becomes false even though the device correctly remains locked.
+        uiDevice.sleep()
+        lockStateTrackingRule.assertLocked()
+        trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 10000, 0) {}
+        uiDevice.wakeUp()
+        uiDevice.sleep()
+        await()
+        lockStateTrackingRule.assertUnlockedButNotReally()
+    }
+
+    @Test
     fun grantDoesNotCallBack() {
         val callback = mock<(GrantTrustResult) -> Unit>()
         trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, 0, callback)
diff --git a/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt b/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt
index ae72247..96362b8 100644
--- a/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt
+++ b/tests/TrustTests/src/android/trust/test/TemporaryAndRenewableTrustTest.kt
@@ -102,7 +102,7 @@
         trustAgentRule.agent.grantTrust(
             GRANT_MESSAGE, 0, FLAG_GRANT_TRUST_TEMPORARY_AND_RENEWABLE) {}
 
-        lockStateTrackingRule.assertUnlocked()
+        lockStateTrackingRule.assertUnlockedAndTrusted()
     }
 
     @Test
@@ -125,7 +125,7 @@
             Log.i(TAG, "Callback received; status=${it.status}")
             result = it
         }
-        lockStateTrackingRule.assertUnlocked()
+        lockStateTrackingRule.assertUnlockedAndTrusted()
 
         wait("callback triggered") { result?.status == STATUS_UNLOCKED_BY_GRANT }
     }
diff --git a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
index 1930a1c..fe47fde 100644
--- a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
+++ b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt
@@ -16,6 +16,7 @@
 
 package android.trust.test.lib
 
+import android.app.KeyguardManager
 import android.app.trust.TrustManager
 import android.app.trust.TrustManager.TrustListener
 import android.content.Context
@@ -27,18 +28,23 @@
 import org.junit.runners.model.Statement
 
 /**
- * Rule for tracking the lock state of the device based on events emitted to [TrustListener].
+ * Rule for tracking the trusted state of the device based on events emitted to
+ * [TrustListener].  Provides helper methods for verifying that the trusted
+ * state has a particular value and is consistent with (a) the keyguard "locked"
+ * (i.e. showing) value when applicable, and (b) the device locked value that is
+ * tracked by TrustManagerService and is queryable via KeyguardManager.
  */
 class LockStateTrackingRule : TestRule {
     private val context: Context = getApplicationContext()
-    private val windowManager = WindowManagerGlobal.getWindowManagerService()
+    private val windowManager = checkNotNull(WindowManagerGlobal.getWindowManagerService())
+    private val keyguardManager = context.getSystemService(KeyguardManager::class.java) as KeyguardManager
 
-    @Volatile lateinit var lockState: LockState
+    @Volatile lateinit var trustState: TrustState
         private set
 
     override fun apply(base: Statement, description: Description) = object : Statement() {
         override fun evaluate() {
-            lockState = LockState(locked = windowManager.isKeyguardLocked)
+            trustState = TrustState()
             val trustManager = context.getSystemService(TrustManager::class.java) as TrustManager
             val listener = Listener()
 
@@ -52,12 +58,25 @@
     }
 
     fun assertLocked() {
-        wait("un-locked per TrustListener") { lockState.locked == true }
-        wait("keyguard lock") { windowManager.isKeyguardLocked }
+        wait("device locked") { keyguardManager.isDeviceLocked }
+        // isDeviceLocked implies isKeyguardLocked && !trusted.
+        wait("keyguard locked") { windowManager.isKeyguardLocked }
+        wait("not trusted") { trustState.trusted == false }
     }
 
-    fun assertUnlocked() {
-        wait("locked per TrustListener") { lockState.locked == false }
+    // TODO(b/299298338) remove this when removing FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS
+    fun assertUnlockedButNotReally() {
+        wait("device unlocked") { !keyguardManager.isDeviceLocked }
+        wait("not trusted") { trustState.trusted == false }
+        wait("keyguard locked") { windowManager.isKeyguardLocked }
+    }
+
+    fun assertUnlockedAndTrusted() {
+        wait("device unlocked") { !keyguardManager.isDeviceLocked }
+        wait("trusted") { trustState.trusted == true }
+        // Can't check for !isKeyguardLocked here, since isKeyguardLocked
+        // returns true in the case where the keyguard is dismissible with
+        // swipe, which is considered "device unlocked"!
     }
 
     inner class Listener : TrustListener {
@@ -69,7 +88,7 @@
             trustGrantedMessages: MutableList<String>
         ) {
             Log.d(TAG, "Device became trusted=$enabled")
-            lockState = lockState.copy(locked = !enabled)
+            trustState = trustState.copy(trusted=enabled)
         }
 
         override fun onTrustManagedChanged(enabled: Boolean, userId: Int) {
@@ -77,10 +96,13 @@
 
         override fun onTrustError(message: CharSequence) {
         }
+
+        override fun onEnabledTrustAgentsChanged(userId: Int) {
+        }
     }
 
-    data class LockState(
-        val locked: Boolean? = null
+    data class TrustState(
+        val trusted: Boolean? = null
     )
 
     companion object {
diff --git a/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
index 4189baa..f1edca3 100644
--- a/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
+++ b/tests/TrustTests/src/android/trust/test/lib/ScreenLockRule.kt
@@ -36,7 +36,7 @@
 class ScreenLockRule : TestRule {
     private val context: Context = getApplicationContext()
     private val uiDevice = UiDevice.getInstance(getInstrumentation())
-    private val windowManager = WindowManagerGlobal.getWindowManagerService()
+    private val windowManager = checkNotNull(WindowManagerGlobal.getWindowManagerService())
     private val lockPatternUtils = LockPatternUtils(context)
     private var instantLockSavedValue = false
 
diff --git a/tools/aapt/ZipEntry.cpp b/tools/aapt/ZipEntry.cpp
index 5339285..6886993 100644
--- a/tools/aapt/ZipEntry.cpp
+++ b/tools/aapt/ZipEntry.cpp
@@ -18,6 +18,8 @@
 // Access to entries in a Zip archive.
 //
 
+#define _POSIX_THREAD_SAFE_FUNCTIONS // For mingw localtime_r().
+
 #define LOG_TAG "zip"
 
 #include "ZipEntry.h"
@@ -337,39 +339,26 @@
 /*
  * Set the CDE/LFH timestamp from UNIX time.
  */
-void ZipEntry::setModWhen(time_t when)
-{
-#if !defined(_WIN32)
-    struct tm tmResult;
-#endif
-    time_t even;
-    unsigned short zdate, ztime;
-
-    struct tm* ptm;
-
+void ZipEntry::setModWhen(time_t when) {
     /* round up to an even number of seconds */
-    even = (time_t)(((unsigned long)(when) + 1) & (~1));
+    time_t even = (time_t)(((unsigned long)(when) + 1) & (~1));
 
     /* expand */
-#if !defined(_WIN32)
-    ptm = localtime_r(&even, &tmResult);
-#else
-    ptm = localtime(&even);
-#endif
+    struct tm tmResult;
+    struct tm* ptm = localtime_r(&even, &tmResult);
 
     int year;
     year = ptm->tm_year;
     if (year < 80)
         year = 80;
 
-    zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday;
-    ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
+    unsigned short zdate = (year - 80) << 9 | (ptm->tm_mon + 1) << 5 | ptm->tm_mday;
+    unsigned short ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1;
 
     mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime;
     mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate;
 }
 
-
 /*
  * ===========================================================================
  *      ZipEntry::LocalFileHeader
diff --git a/tools/aapt2/compile/InlineXmlFormatParser.h b/tools/aapt2/compile/InlineXmlFormatParser.h
index 4300023..3a5161b 100644
--- a/tools/aapt2/compile/InlineXmlFormatParser.h
+++ b/tools/aapt2/compile/InlineXmlFormatParser.h
@@ -21,8 +21,8 @@
 #include <vector>
 
 #include "android-base/macros.h"
-
 #include "process/IResourceTableConsumer.h"
+#include "xml/XmlDom.h"
 
 namespace aapt {
 
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index 9828b97..f93949b 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -116,9 +116,7 @@
 
 class ManifestExtractor {
  public:
-
-  explicit ManifestExtractor(LoadedApk* apk, DumpManifestOptions& options)
-      : apk_(apk), options_(options) { }
+  explicit ManifestExtractor(LoadedApk* apk, DumpManifestOptions& options);
 
   class Element {
    public:
@@ -387,7 +385,7 @@
   DumpManifestOptions& options_;
 
  private:
-  std::unique_ptr<CommonFeatureGroup> commonFeatureGroup_ = util::make_unique<CommonFeatureGroup>();
+  std::unique_ptr<CommonFeatureGroup> commonFeatureGroup_;
   std::map<std::string, ConfigDescription> locales_;
   std::map<uint16_t, ConfigDescription> densities_;
   std::vector<Element*> parent_stack_;
@@ -1970,6 +1968,12 @@
   }
 }
 
+// Define this constructor after the CommonFeatureGroup class definition to avoid errors with using
+// std::unique_ptr on an incomplete type.
+ManifestExtractor::ManifestExtractor(LoadedApk* apk, DumpManifestOptions& options)
+    : apk_(apk), options_(options), commonFeatureGroup_(util::make_unique<CommonFeatureGroup>()) {
+}
+
 bool ManifestExtractor::Dump(text::Printer* printer, IDiagnostics* diag) {
   // Load the manifest
   std::unique_ptr<xml::XmlResource> doc = apk_->LoadXml("AndroidManifest.xml", diag);
diff --git a/tools/lint/common/Android.bp b/tools/lint/common/Android.bp
index 898f88b..8bfbfe5 100644
--- a/tools/lint/common/Android.bp
+++ b/tools/lint/common/Android.bp
@@ -27,3 +27,30 @@
     libs: ["lint_api"],
     kotlincflags: ["-Xjvm-default=all"],
 }
+
+java_defaults {
+    name: "AndroidLintCheckerTestDefaults",
+    srcs: ["checks/src/test/java/**/*.kt"],
+    static_libs: [
+        "junit",
+        "lint",
+        "lint_tests",
+    ],
+    test_options: {
+        unit_test: true,
+        tradefed_options: [
+            {
+                // lint bundles in some classes that were built with older versions
+                // of libraries, and no longer load. Since tradefed tries to load
+                // all classes in the jar to look for tests, it crashes loading them.
+                // Exclude these classes from tradefed's search.
+                name: "exclude-paths",
+                value: "org/apache",
+            },
+            {
+                name: "exclude-paths",
+                value: "META-INF",
+            },
+        ],
+    },
+}
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
similarity index 100%
rename from tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
rename to tools/lint/common/src/main/java/com/google/android/lint/aidl/AidlImplementationDetector.kt
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
similarity index 100%
rename from tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/Constants.kt
rename to tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
similarity index 100%
rename from tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
rename to tools/lint/common/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt
diff --git a/tools/lint/fix/soong_lint_fix.py b/tools/lint/fix/soong_lint_fix.py
index cd4d778d..acc0ad0 100644
--- a/tools/lint/fix/soong_lint_fix.py
+++ b/tools/lint/fix/soong_lint_fix.py
@@ -29,6 +29,39 @@
 PATH_SUFFIX = "android_common/lint"
 FIX_ZIP = "suggested-fixes.zip"
 
+
+class SoongModule:
+    """A Soong module to lint.
+
+    The constructor takes the name of the module (for example,
+    "framework-minus-apex"). find() must be called to extract the intermediate
+    module path from Soong's module-info.json
+    """
+    def __init__(self, name):
+        self._name = name
+
+    def find(self, module_info):
+        """Finds the module in the loaded module_info.json."""
+        if self._name not in module_info:
+            raise Exception(f"Module {self._name} not found!")
+
+        partial_path = module_info[self._name]["path"][0]
+        print(f"Found module {partial_path}/{self._name}.")
+        self._path = f"{PATH_PREFIX}/{partial_path}/{self._name}/{PATH_SUFFIX}"
+
+    @property
+    def name(self):
+        return self._name
+
+    @property
+    def lint_report(self):
+        return f"{self._path}/lint-report.txt"
+
+    @property
+    def suggested_fixes(self):
+        return f"{self._path}/{FIX_ZIP}"
+
+
 class SoongLintFix:
     """
     This class creates a command line tool that will
@@ -53,16 +86,14 @@
         self._parser = _setup_parser()
         self._args = None
         self._kwargs = None
-        self._path = None
-        self._target = None
+        self._modules = []
 
-
-    def run(self, additional_setup=None, custom_fix=None):
+    def run(self):
         """
         Run the script
         """
         self._setup()
-        self._find_module()
+        self._find_modules()
         self._lint()
 
         if not self._args.no_fix:
@@ -87,8 +118,6 @@
 
         os.chdir(ANDROID_BUILD_TOP)
 
-
-    def _find_module(self):
         print("Refreshing soong modules...")
         try:
             os.mkdir(ANDROID_PRODUCT_OUT)
@@ -97,48 +126,47 @@
         subprocess.call(f"{SOONG_UI} --make-mode {PRODUCT_OUT}/module-info.json", **self._kwargs)
         print("done.")
 
+
+    def _find_modules(self):
         with open(f"{ANDROID_PRODUCT_OUT}/module-info.json") as f:
             module_info = json.load(f)
 
-        if self._args.module not in module_info:
-            sys.exit(f"Module {self._args.module} not found!")
-
-        module_path = module_info[self._args.module]["path"][0]
-        print(f"Found module {module_path}/{self._args.module}.")
-
-        self._path = f"{PATH_PREFIX}/{module_path}/{self._args.module}/{PATH_SUFFIX}"
-        self._target = f"{self._path}/lint-report.txt"
-
+        for module_name in self._args.modules:
+            module = SoongModule(module_name)
+            module.find(module_info)
+            self._modules.append(module)
 
     def _lint(self):
         print("Cleaning up any old lint results...")
-        try:
-            os.remove(f"{self._target}")
-            os.remove(f"{self._path}/{FIX_ZIP}")
-        except FileNotFoundError:
-            pass
+        for module in self._modules:
+            try:
+                os.remove(f"{module.lint_report}")
+                os.remove(f"{module.suggested_fixes}")
+            except FileNotFoundError:
+                pass
         print("done.")
 
-        print(f"Generating {self._target}")
-        subprocess.call(f"{SOONG_UI} --make-mode {self._target}", **self._kwargs)
+        target = " ".join([ module.lint_report for module in self._modules ])
+        print(f"Generating {target}")
+        subprocess.call(f"{SOONG_UI} --make-mode {target}", **self._kwargs)
         print("done.")
 
-
     def _fix(self):
-        print("Copying suggested fixes to the tree...")
-        with zipfile.ZipFile(f"{self._path}/{FIX_ZIP}") as zip:
-            for name in zip.namelist():
-                if name.startswith("out") or not name.endswith(".java"):
-                    continue
-                with zip.open(name) as src, open(f"{ANDROID_BUILD_TOP}/{name}", "wb") as dst:
-                    shutil.copyfileobj(src, dst)
+        for module in self._modules:
+            print(f"Copying suggested fixes for {module.name} to the tree...")
+            with zipfile.ZipFile(f"{module.suggested_fixes}") as zip:
+                for name in zip.namelist():
+                    if name.startswith("out") or not name.endswith(".java"):
+                        continue
+                    with zip.open(name) as src, open(f"{ANDROID_BUILD_TOP}/{name}", "wb") as dst:
+                        shutil.copyfileobj(src, dst)
             print("done.")
 
-
     def _print(self):
-        print("### lint-report.txt ###", end="\n\n")
-        with open(self._target, "r") as f:
-            print(f.read())
+        for module in self._modules:
+            print(f"### lint-report.txt {module.name} ###", end="\n\n")
+            with open(module.lint_report, "r") as f:
+                print(f.read())
 
 
 def _setup_parser():
@@ -151,7 +179,8 @@
         **Gotcha**: You must have run `source build/envsetup.sh` and `lunch` first.
         """, formatter_class=argparse.RawTextHelpFormatter)
 
-    parser.add_argument('module',
+    parser.add_argument('modules',
+                        nargs='+',
                         help='The soong build module to run '
                              '(e.g. framework-minus-apex or services.core.unboosted)')
 
@@ -170,4 +199,4 @@
     return parser
 
 if __name__ == "__main__":
-    SoongLintFix().run()
\ No newline at end of file
+    SoongLintFix().run()
diff --git a/tools/lint/framework/Android.bp b/tools/lint/framework/Android.bp
index 30a6daa..5acdf43 100644
--- a/tools/lint/framework/Android.bp
+++ b/tools/lint/framework/Android.bp
@@ -37,28 +37,9 @@
 
 java_test_host {
     name: "AndroidFrameworkLintCheckerTest",
+    defaults: ["AndroidLintCheckerTestDefaults"],
     srcs: ["checks/src/test/java/**/*.kt"],
     static_libs: [
         "AndroidFrameworkLintChecker",
-        "junit",
-        "lint",
-        "lint_tests",
     ],
-    test_options: {
-        unit_test: true,
-        tradefed_options: [
-            {
-                // lint bundles in some classes that were built with older versions
-                // of libraries, and no longer load. Since tradefed tries to load
-                // all classes in the jar to look for tests, it crashes loading them.
-                // Exclude these classes from tradefed's search.
-                name: "exclude-paths",
-                value: "org/apache",
-            },
-            {
-                name: "exclude-paths",
-                value: "META-INF",
-            },
-        ],
-    },
 }
diff --git a/tools/lint/global/Android.bp b/tools/lint/global/Android.bp
index bedb7bd..3e74171 100644
--- a/tools/lint/global/Android.bp
+++ b/tools/lint/global/Android.bp
@@ -38,28 +38,9 @@
 
 java_test_host {
     name: "AndroidGlobalLintCheckerTest",
+    defaults: ["AndroidLintCheckerTestDefaults"],
     srcs: ["checks/src/test/java/**/*.kt"],
     static_libs: [
         "AndroidGlobalLintChecker",
-        "junit",
-        "lint",
-        "lint_tests",
     ],
-    test_options: {
-        unit_test: true,
-        tradefed_options: [
-            {
-                // lint bundles in some classes that were built with older versions
-                // of libraries, and no longer load. Since tradefed tries to load
-                // all classes in the jar to look for tests, it crashes loading them.
-                // Exclude these classes from tradefed's search.
-                name: "exclude-paths",
-                value: "org/apache",
-            },
-            {
-                name: "exclude-paths",
-                value: "META-INF",
-            },
-        ],
-    },
 }
diff --git a/tools/lint/utils/Android.bp b/tools/lint/utils/Android.bp
new file mode 100644
index 0000000..75e8d68
--- /dev/null
+++ b/tools/lint/utils/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2023 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library_host {
+    name: "AndroidUtilsLintChecker",
+    srcs: ["checks/src/main/java/**/*.kt"],
+    plugins: ["auto_service_plugin"],
+    libs: [
+        "auto_service_annotations",
+        "lint_api",
+    ],
+    static_libs: [
+        "AndroidCommonLint",
+    ],
+    kotlincflags: ["-Xjvm-default=all"],
+}
+
+java_test_host {
+    name: "AndroidUtilsLintCheckerTest",
+    defaults: ["AndroidLintCheckerTestDefaults"],
+    srcs: ["checks/src/test/java/**/*.kt"],
+    static_libs: [
+        "AndroidUtilsLintChecker",
+    ],
+}
diff --git a/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt b/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt
new file mode 100644
index 0000000..fa61c42
--- /dev/null
+++ b/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 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.google.android.lint
+
+import com.android.tools.lint.client.api.IssueRegistry
+import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.android.lint.aidl.AnnotatedAidlCounter
+import com.google.auto.service.AutoService
+
+@AutoService(IssueRegistry::class)
+@Suppress("UnstableApiUsage")
+class AndroidUtilsIssueRegistry : IssueRegistry() {
+    override val issues = listOf(
+        AnnotatedAidlCounter.ISSUE_ANNOTATED_AIDL_COUNTER,
+    )
+
+    override val api: Int
+        get() = CURRENT_API
+
+    override val minApi: Int
+        get() = 8
+
+    override val vendor: Vendor = Vendor(
+        vendorName = "Android",
+        feedbackUrl = "http://b/issues/new?component=315013",
+        contact = "tweek@google.com"
+    )
+}
diff --git a/tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/AnnotatedAidlCounter.kt b/tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/AnnotatedAidlCounter.kt
new file mode 100644
index 0000000..f0ec3f4
--- /dev/null
+++ b/tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/AnnotatedAidlCounter.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2023 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.google.android.lint.aidl
+
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Context
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import org.jetbrains.uast.UBlockExpression
+import org.jetbrains.uast.UMethod
+
+import java.util.TreeMap
+
+/**
+ *  Count the number of AIDL interfaces. Reports the number of annotated and
+ *  non-annotated methods.
+ */
+@Suppress("UnstableApiUsage")
+class AnnotatedAidlCounter : AidlImplementationDetector() {
+
+    private data class Stat(
+        var unannotated: Int = 0,
+        var enforced: Int = 0,
+        var notRequired: Int = 0,
+    )
+
+    private var packagesStats: TreeMap<String, Stat> = TreeMap<String, Stat>()
+
+    override fun visitAidlMethod(
+            context: JavaContext,
+            node: UMethod,
+            interfaceName: String,
+            body: UBlockExpression
+    ) {
+        val packageName = context.uastFile?.packageName ?: "<unknown>"
+        var packageStat = packagesStats.getOrDefault(packageName, Stat())
+        when {
+            node.hasAnnotation(ANNOTATION_ENFORCE_PERMISSION) -> packageStat.enforced += 1
+            node.hasAnnotation(ANNOTATION_REQUIRES_NO_PERMISSION) -> packageStat.notRequired += 1
+            else -> packageStat.unannotated += 1
+        }
+        packagesStats.put(packageName, packageStat)
+        // context.driver.client.log(null, "%s.%s#%s".format(packageName, interfaceName, node.name))
+    }
+
+    override fun afterCheckRootProject(context: Context) {
+        var total = Stat()
+        for ((packageName, stat) in packagesStats) {
+            context.client.log(null, "package $packageName => $stat")
+            total.unannotated += stat.unannotated
+            total.enforced += stat.enforced
+            total.notRequired += stat.notRequired
+        }
+        val location = Location.create(context.project.dir)
+        context.report(
+            ISSUE_ANNOTATED_AIDL_COUNTER,
+            location,
+            "module ${context.project.name} => $total"
+        )
+    }
+
+    companion object {
+
+        @JvmField
+        val ISSUE_ANNOTATED_AIDL_COUNTER = Issue.create(
+                id = "AnnotatedAidlCounter",
+                briefDescription = "Statistics on the number of annotated AIDL methods.",
+                explanation = "",
+                category = Category.SECURITY,
+                priority = 5,
+                severity = Severity.INFORMATIONAL,
+                implementation = Implementation(
+                        AnnotatedAidlCounter::class.java,
+                        Scope.JAVA_FILE_SCOPE
+                ),
+        )
+    }
+}
diff --git a/tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/AnnotatedAidlCounterTest.kt b/tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/AnnotatedAidlCounterTest.kt
new file mode 100644
index 0000000..692b7da
--- /dev/null
+++ b/tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/AnnotatedAidlCounterTest.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2023 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.google.android.lint.aidl
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+@Suppress("UnstableApiUsage")
+class AnnotatedAidlCounterTest : LintDetectorTest() {
+    override fun getDetector(): Detector = AnnotatedAidlCounter()
+
+    override fun getIssues(): List<Issue> = listOf(
+        AnnotatedAidlCounter.ISSUE_ANNOTATED_AIDL_COUNTER,
+    )
+
+    override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
+
+    /** No issue scenario */
+
+    fun testDoesNotDetectIssuesCorrectAnnotationOnMethod() {
+        lint().files(java(
+            """
+            package test.pkg;
+            import android.annotation.EnforcePermission;
+            public class TestClass2 extends IFooMethod.Stub {
+                @Override
+                @EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
+                public void testMethod() {}
+            }
+            """).indented(),
+                *stubs
+        )
+        .run()
+        .expect("""
+        app: Information: module app => Stat(unannotated=0, enforced=1, notRequired=0) [AnnotatedAidlCounter]
+        0 errors, 0 warnings
+        """)
+    }
+
+    // A service with permission annotation on the method.
+    private val interfaceIFooMethodStub: TestFile = java(
+        """
+        public interface IFooMethod extends android.os.IInterface {
+         public static abstract class Stub extends android.os.Binder implements IFooMethod {}
+          @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
+          public void testMethod();
+        }
+        """
+    ).indented()
+
+    // A service without any permission annotation.
+    private val interfaceIBarStub: TestFile = java(
+        """
+        public interface IBar extends android.os.IInterface {
+         public static abstract class Stub extends android.os.Binder implements IBar {
+            @Override
+            public void testMethod() {}
+          }
+          public void testMethod();
+        }
+        """
+    ).indented()
+
+    private val manifestPermissionStub: TestFile = java(
+        """
+        package android.Manifest;
+        class permission {
+          public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
+        }
+        """
+    ).indented()
+
+    private val enforcePermissionAnnotationStub: TestFile = java(
+        """
+        package android.annotation;
+        public @interface EnforcePermission {}
+        """
+    ).indented()
+
+    private val stubs = arrayOf(interfaceIFooMethodStub, interfaceIBarStub,
+            manifestPermissionStub, enforcePermissionAnnotationStub)
+}