Merge "Explicitly exit from the am instrument after test completes"
diff --git a/Android.bp b/Android.bp
index d976b91..00b4198 100644
--- a/Android.bp
+++ b/Android.bp
@@ -294,6 +294,7 @@
     srcs: [
         ":framework-non-updatable-sources",
         "core/java/**/*.logtags",
+        ":apex-info-list",
     ],
     aidl: {
         generate_get_transaction_name: true,
diff --git a/ApiDocs.bp b/ApiDocs.bp
index a926ddc..8af2e02 100644
--- a/ApiDocs.bp
+++ b/ApiDocs.bp
@@ -112,7 +112,6 @@
 }
 
 // Defaults module for doc-stubs targets that use module source code as input.
-// This is the default/normal.
 stubs_defaults {
     name: "framework-doc-stubs-sources-default",
     defaults: ["framework-doc-stubs-default"],
@@ -147,12 +146,6 @@
 }
 
 droidstubs {
-    name: "framework-doc-stubs",
-    defaults: ["framework-doc-stubs-sources-default"],
-    args: metalava_framework_docs_args,
-}
-
-droidstubs {
     name: "framework-doc-system-stubs",
     defaults: ["framework-doc-stubs-sources-default"],
     args: metalava_framework_docs_args +
@@ -160,11 +153,8 @@
     api_levels_sdk_type: "system",
 }
 
-// Experimental target building doc stubs with module stub source code as input.
-// This is intended to eventually replace framework-doc-stubs, once all diffs
-// have been eliminated.
 droidstubs {
-    name: "framework-doc-stubs-module-stubs",
+    name: "framework-doc-stubs",
     defaults: ["framework-doc-stubs-default"],
     args: metalava_framework_docs_args,
     srcs: [
diff --git a/PACKAGE_MANAGER_OWNERS b/PACKAGE_MANAGER_OWNERS
new file mode 100644
index 0000000..e4549b4
--- /dev/null
+++ b/PACKAGE_MANAGER_OWNERS
@@ -0,0 +1,3 @@
+chiuwinson@google.com
+patb@google.com
+schfan@google.com
\ No newline at end of file
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 4e46aa3..9564dde 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -41,6 +41,10 @@
     private IActivityManager mAm;
     private IPackageManager mPm;
 
+    Am() {
+        svcInit();
+    }
+
     /**
      * Command-line entry point.
      *
@@ -50,6 +54,20 @@
         (new Am()).run(args);
     }
 
+    private void svcInit() {
+        mAm = ActivityManager.getService();
+        if (mAm == null) {
+            System.err.println(NO_SYSTEM_ERROR_CODE);
+            return;
+        }
+
+        mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
+        if (mPm == null) {
+            System.err.println(NO_SYSTEM_ERROR_CODE);
+            return;
+        }
+    }
+
     @Override
     public void onShowUsage(PrintStream out) {
         try {
@@ -61,19 +79,6 @@
 
     @Override
     public void onRun() throws Exception {
-
-        mAm = ActivityManager.getService();
-        if (mAm == null) {
-            System.err.println(NO_SYSTEM_ERROR_CODE);
-            throw new AndroidException("Can't connect to activity manager; is the system running?");
-        }
-
-        mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
-        if (mPm == null) {
-            System.err.println(NO_SYSTEM_ERROR_CODE);
-            throw new AndroidException("Can't connect to package manager; is the system running?");
-        }
-
         String op = nextArgRequired();
 
         if (op.equals("instrument")) {
diff --git a/core/api/current.txt b/core/api/current.txt
index 0eba9d7..1c014454 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -112,6 +112,7 @@
     field public static final String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE";
     field public static final String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";
     field public static final String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
+    field public static final String NEARBY_WIFI_DEVICES = "android.permission.NEARBY_WIFI_DEVICES";
     field public static final String NFC = "android.permission.NFC";
     field public static final String NFC_PREFERRED_PAYMENT_INFO = "android.permission.NFC_PREFERRED_PAYMENT_INFO";
     field public static final String NFC_TRANSACTION_EVENT = "android.permission.NFC_TRANSACTION_EVENT";
@@ -8647,12 +8648,14 @@
     method public android.bluetooth.BluetoothDevice getRemoteDevice(byte[]);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public int getScanMode();
     method public int getState();
+    method public int isCisCentralSupported();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN) public boolean isDiscovering();
     method public boolean isEnabled();
     method public boolean isLe2MPhySupported();
     method public boolean isLeCodedPhySupported();
     method public boolean isLeExtendedAdvertisingSupported();
     method public boolean isLePeriodicAdvertisingSupported();
+    method public int isLePeriodicAdvertisingSyncTransferSenderSupported();
     method public boolean isMultipleAdvertisementSupported();
     method public boolean isOffloadedFilteringSupported();
     method public boolean isOffloadedScanBatchingSupported();
@@ -9505,6 +9508,7 @@
     field public static final int ERROR_BLUETOOTH_NOT_ALLOWED = 2; // 0x2
     field public static final int ERROR_BLUETOOTH_NOT_ENABLED = 1; // 0x1
     field public static final int ERROR_DEVICE_NOT_BONDED = 3; // 0x3
+    field public static final int ERROR_FEATURE_NOT_SUPPORTED = 8; // 0x8
     field public static final int ERROR_MISSING_BLUETOOTH_CONNECT_PERMISSION = 6; // 0x6
     field public static final int ERROR_UNKNOWN = 2147483647; // 0x7fffffff
     field public static final int SUCCESS = 0; // 0x0
@@ -31432,7 +31436,9 @@
     method @NonNull public static android.os.Parcel obtain();
     method @NonNull public static android.os.Parcel obtain(@NonNull android.os.IBinder);
     method @Nullable public Object[] readArray(@Nullable ClassLoader);
+    method @Nullable public <T> T[] readArray(@Nullable ClassLoader, @NonNull Class<T>);
     method @Nullable public java.util.ArrayList readArrayList(@Nullable ClassLoader);
+    method @Nullable public <T> java.util.ArrayList<T> readArrayList(@Nullable ClassLoader, @NonNull Class<? extends T>);
     method public void readBinderArray(@NonNull android.os.IBinder[]);
     method public void readBinderList(@NonNull java.util.List<android.os.IBinder>);
     method public boolean readBoolean();
@@ -31460,15 +31466,18 @@
     method @Nullable public <T extends android.os.Parcelable> T readParcelable(@Nullable ClassLoader);
     method @Nullable public <T extends android.os.Parcelable> T readParcelable(@Nullable ClassLoader, @NonNull Class<T>);
     method @Nullable public android.os.Parcelable[] readParcelableArray(@Nullable ClassLoader);
+    method @Nullable public <T> T[] readParcelableArray(@Nullable ClassLoader, @NonNull Class<T>);
     method @Nullable public android.os.Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader);
     method @Nullable public <T> android.os.Parcelable.Creator<T> readParcelableCreator(@Nullable ClassLoader, @NonNull Class<T>);
     method @NonNull public <T extends android.os.Parcelable> java.util.List<T> readParcelableList(@NonNull java.util.List<T>, @Nullable ClassLoader);
     method @Nullable public android.os.PersistableBundle readPersistableBundle();
     method @Nullable public android.os.PersistableBundle readPersistableBundle(@Nullable ClassLoader);
     method @Nullable public java.io.Serializable readSerializable();
+    method @Nullable public <T extends java.io.Serializable> T readSerializable(@Nullable ClassLoader, @NonNull Class<T>);
     method @NonNull public android.util.Size readSize();
     method @NonNull public android.util.SizeF readSizeF();
     method @Nullable public <T> android.util.SparseArray<T> readSparseArray(@Nullable ClassLoader);
+    method @Nullable public <T> android.util.SparseArray<T> readSparseArray(@Nullable ClassLoader, @NonNull Class<? extends T>);
     method @Nullable public android.util.SparseBooleanArray readSparseBooleanArray();
     method @Nullable public String readString();
     method public void readStringArray(@NonNull String[]);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 172818d..c3f9c20 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -113,6 +113,11 @@
   public class AudioManager {
     method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
     method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
+    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setA2dpSuspended(boolean);
+    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setBluetoothHeadsetProperties(@NonNull String, boolean, boolean);
+    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setHfpEnabled(boolean);
+    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setHfpSamplingRate(int);
+    method @RequiresPermission("android.permission.BLUETOOTH_STACK") public void setHfpVolume(int);
     method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
     field public static final int FLAG_FROM_KEY = 4096; // 0x1000
   }
@@ -312,7 +317,7 @@
 package android.provider {
 
   public static final class ContactsContract.RawContactsEntity implements android.provider.BaseColumns android.provider.ContactsContract.DataColumns android.provider.ContactsContract.RawContactsColumns {
-    method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public static java.util.Map<java.lang.String,java.util.List<android.content.ContentValues>> queryRawContactEntity(@NonNull android.content.Context, long);
+    method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public static java.util.Map<java.lang.String,java.util.List<android.content.ContentValues>> queryRawContactEntity(@NonNull android.content.ContentResolver, long);
   }
 
   public final class DeviceConfig {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 6f825ae..ac6943c 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -475,6 +475,8 @@
     field public static final String OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED = "android:auto_revoke_permissions_if_unused";
     field public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE = "android:bind_accessibility_service";
     field public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
+    field public static final String OPSTR_ESTABLISH_VPN_MANAGER = "android:establish_vpn_manager";
+    field public static final String OPSTR_ESTABLISH_VPN_SERVICE = "android:establish_vpn_service";
     field public static final String OPSTR_GET_ACCOUNTS = "android:get_accounts";
     field public static final String OPSTR_GPS = "android:gps";
     field public static final String OPSTR_INSTANT_APP_START_FOREGROUND = "android:instant_app_start_foreground";
@@ -1935,6 +1937,22 @@
     field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED";
   }
 
+  public final class BluetoothActivityEnergyInfo implements android.os.Parcelable {
+    method public int getBluetoothStackState();
+    method public long getControllerEnergyUsed();
+    method public long getControllerIdleTimeMillis();
+    method public long getControllerRxTimeMillis();
+    method public long getControllerTxTimeMillis();
+    method public long getTimestampMillis();
+    method @NonNull public java.util.List<android.bluetooth.UidTraffic> getUidTraffic();
+    method public boolean isValid();
+    field public static final int BT_STACK_STATE_INVALID = 0; // 0x0
+    field public static final int BT_STACK_STATE_STATE_ACTIVE = 1; // 0x1
+    field public static final int BT_STACK_STATE_STATE_IDLE = 3; // 0x3
+    field public static final int BT_STACK_STATE_STATE_SCANNING = 2; // 0x2
+    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BluetoothActivityEnergyInfo> CREATOR;
+  }
+
   public final class BluetoothAdapter {
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean addOnMetadataChangedListener(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.concurrent.Executor, @NonNull android.bluetooth.BluetoothAdapter.OnMetadataChangedListener);
     method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean disable(boolean);
@@ -2234,6 +2252,13 @@
     method @NonNull public android.bluetooth.OobData.LeBuilder setRandomizerHash(@NonNull byte[]);
   }
 
+  public final class UidTraffic implements java.lang.Cloneable android.os.Parcelable {
+    method public long getRxBytes();
+    method public long getTxBytes();
+    method public int getUid();
+    field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.UidTraffic> CREATOR;
+  }
+
 }
 
 package android.bluetooth.le {
@@ -9126,6 +9151,7 @@
     field public static final String NAMESPACE_BIOMETRICS = "biometrics";
     field public static final String NAMESPACE_BLOBSTORE = "blobstore";
     field public static final String NAMESPACE_BLUETOOTH = "bluetooth";
+    field public static final String NAMESPACE_CAPTIVEPORTALLOGIN = "captive_portal_login";
     field public static final String NAMESPACE_CLIPBOARD = "clipboard";
     field public static final String NAMESPACE_CONNECTIVITY = "connectivity";
     field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
@@ -9161,6 +9187,7 @@
     field public static final String NAMESPACE_SYSTEMUI = "systemui";
     field public static final String NAMESPACE_SYSTEM_TIME = "system_time";
     field public static final String NAMESPACE_TELEPHONY = "telephony";
+    field public static final String NAMESPACE_TETHERING = "tethering";
     field public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
     field public static final String NAMESPACE_WINDOW_MANAGER_NATIVE_BOOT = "window_manager_native_boot";
   }
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 5f2c456..e08a493 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -158,10 +158,7 @@
         "android/util/LocalLog.java",
         // This should be android.util.IndentingPrintWriter, but it's not available in all branches.
         "com/android/internal/util/IndentingPrintWriter.java",
-        "com/android/internal/util/IState.java",
         "com/android/internal/util/MessageUtils.java",
-        "com/android/internal/util/State.java",
-        "com/android/internal/util/StateMachine.java",
         "com/android/internal/util/WakeupMessage.java",
     ],
 }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index d932a29..63f700b 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1292,6 +1292,9 @@
     /** @hide */
     public static final int OP_UWB_RANGING = AppProtoEnums.APP_OP_UWB_RANGING;
 
+    /** @hide */
+    public static final int OP_NEARBY_WIFI_DEVICES = AppProtoEnums.APP_OP_NEARBY_WIFI_DEVICES;
+
     /**
      * Activity recognition being accessed by an activity recognition source, which
      * is a component that already has access since it is the one that detects
@@ -1310,9 +1313,23 @@
     public static final int OP_RECORD_INCOMING_PHONE_AUDIO =
             AppProtoEnums.APP_OP_RECORD_INCOMING_PHONE_AUDIO;
 
+    /**
+     * VPN app establishes a connection through the VpnService API.
+     *
+     * @hide
+     */
+    public static final int OP_ESTABLISH_VPN_SERVICE = AppProtoEnums.APP_OP_ESTABLISH_VPN_SERVICE;
+
+    /**
+     * VPN app establishes a connection through the VpnManager API.
+     *
+     * @hide
+     */
+    public static final int OP_ESTABLISH_VPN_MANAGER = AppProtoEnums.APP_OP_ESTABLISH_VPN_MANAGER;
+
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final int _NUM_OP = 116;
+    public static final int _NUM_OP = 119;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -1731,6 +1748,8 @@
     public static final String OPSTR_MANAGE_MEDIA = "android:manage_media";
     /** @hide */
     public static final String OPSTR_UWB_RANGING = "android:uwb_ranging";
+    /** @hide */
+    public static final String OPSTR_NEARBY_WIFI_DEVICES = "android:nearby_wifi_devices";
 
     /**
      * Activity recognition being accessed by an activity recognition source, which
@@ -1749,6 +1768,22 @@
     public static final String OPSTR_RECORD_INCOMING_PHONE_AUDIO =
             "android:record_incoming_phone_audio";
 
+    /**
+     * VPN app establishes a connection through the VpnService API.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String OPSTR_ESTABLISH_VPN_SERVICE = "android:establish_vpn_service";
+
+    /**
+     * VPN app establishes a connection through the VpnManager API.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String OPSTR_ESTABLISH_VPN_MANAGER = "android:establish_vpn_manager";
+
     /** {@link #sAppOpsToNote} not initialized yet for this op */
     private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
     /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -1819,6 +1854,7 @@
             OP_BLUETOOTH_CONNECT,
             OP_BLUETOOTH_ADVERTISE,
             OP_UWB_RANGING,
+            OP_NEARBY_WIFI_DEVICES,
 
             // APPOP PERMISSIONS
             OP_ACCESS_NOTIFICATIONS,
@@ -1963,6 +1999,9 @@
             OP_ACTIVITY_RECOGNITION,            // OP_ACTIVITY_RECOGNITION_SOURCE
             OP_BLUETOOTH_ADVERTISE,             // OP_BLUETOOTH_ADVERTISE
             OP_RECORD_INCOMING_PHONE_AUDIO,     // OP_RECORD_INCOMING_PHONE_AUDIO
+            OP_NEARBY_WIFI_DEVICES,             // OP_NEARBY_WIFI_DEVICES
+            OP_ESTABLISH_VPN_SERVICE,           // OP_ESTABLISH_VPN_SERVICE
+            OP_ESTABLISH_VPN_MANAGER,           // OP_ESTABLISH_VPN_MANAGER
     };
 
     /**
@@ -2085,6 +2124,9 @@
             OPSTR_ACTIVITY_RECOGNITION_SOURCE,
             OPSTR_BLUETOOTH_ADVERTISE,
             OPSTR_RECORD_INCOMING_PHONE_AUDIO,
+            OPSTR_NEARBY_WIFI_DEVICES,
+            OPSTR_ESTABLISH_VPN_SERVICE,
+            OPSTR_ESTABLISH_VPN_MANAGER,
     };
 
     /**
@@ -2208,6 +2250,9 @@
             "ACTIVITY_RECOGNITION_SOURCE",
             "BLUETOOTH_ADVERTISE",
             "RECORD_INCOMING_PHONE_AUDIO",
+            "NEARBY_WIFI_DEVICES",
+            "ESTABLISH_VPN_SERVICE",
+            "ESTABLISH_VPN_MANAGER",
     };
 
     /**
@@ -2332,6 +2377,9 @@
             null, // no permission for OP_ACTIVITY_RECOGNITION_SOURCE,
             Manifest.permission.BLUETOOTH_ADVERTISE,
             null, // no permission for OP_RECORD_INCOMING_PHONE_AUDIO,
+            Manifest.permission.NEARBY_WIFI_DEVICES,
+            null, // no permission for OP_ESTABLISH_VPN_SERVICE
+            null, // no permission for OP_ESTABLISH_VPN_MANAGER
     };
 
     /**
@@ -2456,6 +2504,9 @@
             null, // ACTIVITY_RECOGNITION_SOURCE
             null, // BLUETOOTH_ADVERTISE
             null, // RECORD_INCOMING_PHONE_AUDIO
+            null, // NEARBY_WIFI_DEVICES
+            null, // ESTABLISH_VPN_SERVICE
+            null, // ESTABLISH_VPN_MANAGER
     };
 
     /**
@@ -2579,6 +2630,9 @@
             null, // ACTIVITY_RECOGNITION_SOURCE
             null, // BLUETOOTH_ADVERTISE
             null, // RECORD_INCOMING_PHONE_AUDIO
+            null, // NEARBY_WIFI_DEVICES
+            null, // ESTABLISH_VPN_SERVICE
+            null, // ESTABLISH_VPN_MANAGER
     };
 
     /**
@@ -2701,6 +2755,9 @@
             AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION_SOURCE
             AppOpsManager.MODE_ALLOWED, // BLUETOOTH_ADVERTISE
             AppOpsManager.MODE_ALLOWED, // RECORD_INCOMING_PHONE_AUDIO
+            AppOpsManager.MODE_ALLOWED, // NEARBY_WIFI_DEVICES
+            AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_SERVICE
+            AppOpsManager.MODE_ALLOWED, // ESTABLISH_VPN_MANAGER
     };
 
     /**
@@ -2827,6 +2884,9 @@
             false, // ACTIVITY_RECOGNITION_SOURCE
             false, // BLUETOOTH_ADVERTISE
             false, // RECORD_INCOMING_PHONE_AUDIO
+            false, // NEARBY_WIFI_DEVICES
+            false, // OP_ESTABLISH_VPN_SERVICE
+            false, // OP_ESTABLISH_VPN_MANAGER
     };
 
     /**
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 08cd0b3..53b16d3 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -48,18 +48,19 @@
                                ClassLoader parent, String classLoaderName) {
         return getClassLoaderWithSharedLibraries(zip, targetSdkVersion, isBundled,
                               librarySearchPath, libraryPermittedPath, parent, classLoaderName,
-                              null, null);
+                              null, null, null);
     }
 
     ClassLoader getClassLoaderWithSharedLibraries(
             String zip, int targetSdkVersion, boolean isBundled,
             String librarySearchPath, String libraryPermittedPath,
             ClassLoader parent, String classLoaderName,
-            List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries) {
+            List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries,
+            List<ClassLoader> sharedLibrariesLoadedAfterApp) {
         // For normal usage the cache key used is the same as the zip path.
         return getClassLoader(zip, targetSdkVersion, isBundled, librarySearchPath,
                               libraryPermittedPath, parent, zip, classLoaderName, sharedLibraries,
-                              nativeSharedLibraries);
+                              nativeSharedLibraries, sharedLibrariesLoadedAfterApp);
     }
 
     /**
@@ -71,7 +72,8 @@
      */
     ClassLoader getSharedLibraryClassLoaderWithSharedLibraries(String zip, int targetSdkVersion,
             boolean isBundled, String librarySearchPath, String libraryPermittedPath,
-            ClassLoader parent, String classLoaderName, List<ClassLoader> sharedLibraries) {
+            ClassLoader parent, String classLoaderName, List<ClassLoader> sharedLibraries,
+            List<ClassLoader> sharedLibrariesAfter) {
         ClassLoader loader = getCachedNonBootclasspathSystemLib(zip, parent, classLoaderName,
                 sharedLibraries);
         if (loader != null) {
@@ -86,14 +88,15 @@
         nativeSharedLibraries.add("ALL");
         return getClassLoaderWithSharedLibraries(zip, targetSdkVersion, isBundled,
               librarySearchPath, libraryPermittedPath, parent, classLoaderName, sharedLibraries,
-              nativeSharedLibraries);
+              nativeSharedLibraries, sharedLibrariesAfter);
     }
 
     private ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled,
                                        String librarySearchPath, String libraryPermittedPath,
                                        ClassLoader parent, String cacheKey,
                                        String classLoaderName, List<ClassLoader> sharedLibraries,
-                                       List<String> nativeSharedLibraries) {
+                                       List<String> nativeSharedLibraries,
+                                       List<ClassLoader> sharedLibrariesLoadedAfterApp) {
         /*
          * This is the parent we use if they pass "null" in.  In theory
          * this should be the "system" class loader; in practice we
@@ -123,7 +126,7 @@
                 ClassLoader classloader = ClassLoaderFactory.createClassLoader(
                         zip,  librarySearchPath, libraryPermittedPath, parent,
                         targetSdkVersion, isBundled, classLoaderName, sharedLibraries,
-                        nativeSharedLibraries);
+                        nativeSharedLibraries, sharedLibrariesLoadedAfterApp);
 
                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
@@ -140,7 +143,8 @@
 
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, zip);
             ClassLoader loader = ClassLoaderFactory.createClassLoader(
-                    zip, null, parent, classLoaderName, sharedLibraries);
+                    zip, null, parent, classLoaderName, sharedLibraries,
+                    null /*sharedLibrariesLoadedAfterApp*/);
             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
             return loader;
         }
@@ -196,7 +200,7 @@
         ClassLoader classLoader = getClassLoader(path, Build.VERSION.SDK_INT, true /*isBundled*/,
                 null /*librarySearchPath*/, null /*libraryPermittedPath*/, null /*parent*/,
                 null /*cacheKey*/, null /*classLoaderName*/, sharedLibraries /*sharedLibraries*/,
-                null /* nativeSharedLibraries */);
+                null /* nativeSharedLibraries */, null /*sharedLibrariesLoadedAfterApp*/);
 
         if (classLoader == null) {
             // bad configuration or break in classloading code
@@ -267,7 +271,8 @@
         // stub's APK path, when the actual package path is the donor APK.
         return getClassLoader(packagePath, Build.VERSION.SDK_INT, false, libsPath, null, null,
                               cacheKey, null /* classLoaderName */, null /* sharedLibraries */,
-                              null /* nativeSharedLibraries */);
+                              null /* nativeSharedLibraries */,
+                              null /*sharedLibrariesLoadedAfterApp*/);
     }
 
     /**
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index a2c9795..f6d27e1 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -54,10 +54,12 @@
 import android.util.AndroidRuntimeException;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.view.DisplayAdjustments;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.ArrayUtils;
 
@@ -76,6 +78,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Objects;
@@ -700,7 +703,7 @@
     ClassLoader createSharedLibraryLoader(SharedLibraryInfo sharedLibrary,
             boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
         List<String> paths = sharedLibrary.getAllCodePaths();
-        List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
+        Pair<List<ClassLoader>, List<ClassLoader>> sharedLibraries = createSharedLibrariesLoaders(
                 sharedLibrary.getDependencies(), isBundledApp, librarySearchPath,
                 libraryPermittedPath);
         final String jars = (paths.size() == 1) ? paths.get(0) :
@@ -711,15 +714,31 @@
         return ApplicationLoaders.getDefault().getSharedLibraryClassLoaderWithSharedLibraries(jars,
                     mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
                     libraryPermittedPath, /* parent */ null,
-                    /* classLoaderName */ null, sharedLibraries);
+                    /* classLoaderName */ null, sharedLibraries.first, sharedLibraries.second);
     }
 
-    private List<ClassLoader> createSharedLibrariesLoaders(List<SharedLibraryInfo> sharedLibraries,
+    /**
+     *
+     * @return a {@link Pair} of List<ClassLoader> where the first is for standard shared libraries
+     *         and the second is list for shared libraries that code should be loaded after the dex
+     */
+    private Pair<List<ClassLoader>, List<ClassLoader>> createSharedLibrariesLoaders(
+            List<SharedLibraryInfo> sharedLibraries,
             boolean isBundledApp, String librarySearchPath, String libraryPermittedPath) {
-        if (sharedLibraries == null) {
-            return null;
+        if (sharedLibraries == null || sharedLibraries.isEmpty()) {
+            return new Pair<>(null, null);
         }
+
+        // if configured to do so, shared libs are split into 2 collections: those that are
+        // on the class path before the applications code, which is standard, and those
+        // specified to be loaded after the applications code.
+        HashSet<String> libsToLoadAfter = new HashSet<>();
+        Resources systemR = Resources.getSystem();
+        Collections.addAll(libsToLoadAfter, systemR.getStringArray(
+                R.array.config_sharedLibrariesLoadedAfterApp));
+
         List<ClassLoader> loaders = new ArrayList<>();
+        List<ClassLoader> after = new ArrayList<>();
         for (SharedLibraryInfo info : sharedLibraries) {
             if (info.isNative()) {
                 // Native shared lib doesn't contribute to the native lib search path. Its name is
@@ -727,10 +746,19 @@
                 // default linker namespace.
                 continue;
             }
-            loaders.add(createSharedLibraryLoader(
-                    info, isBundledApp, librarySearchPath, libraryPermittedPath));
+            if (libsToLoadAfter.contains(info.getName())) {
+                if (DEBUG) {
+                    Slog.v(ActivityThread.TAG,
+                            info.getName() + " will be loaded after application code");
+                }
+                after.add(createSharedLibraryLoader(
+                        info, isBundledApp, librarySearchPath, libraryPermittedPath));
+            } else {
+                loaders.add(createSharedLibraryLoader(
+                        info, isBundledApp, librarySearchPath, libraryPermittedPath));
+            }
         }
-        return loaders;
+        return new Pair<>(loaders, after);
     }
 
     private StrictMode.ThreadPolicy allowThreadDiskReads() {
@@ -955,9 +983,9 @@
             // as this is early and necessary.
             StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
 
-            List<ClassLoader> sharedLibraries = createSharedLibrariesLoaders(
-                    mApplicationInfo.sharedLibraryInfos, isBundledApp, librarySearchPath,
-                    libraryPermittedPath);
+            Pair<List<ClassLoader>, List<ClassLoader>> sharedLibraries =
+                    createSharedLibrariesLoaders(mApplicationInfo.sharedLibraryInfos, isBundledApp,
+                            librarySearchPath, libraryPermittedPath);
 
             List<String> nativeSharedLibraries = new ArrayList<>();
             if (mApplicationInfo.sharedLibraryInfos != null) {
@@ -971,7 +999,8 @@
             mDefaultClassLoader = ApplicationLoaders.getDefault().getClassLoaderWithSharedLibraries(
                     zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
                     libraryPermittedPath, mBaseClassLoader,
-                    mApplicationInfo.classLoaderName, sharedLibraries, nativeSharedLibraries);
+                    mApplicationInfo.classLoaderName, sharedLibraries.first, nativeSharedLibraries,
+                    sharedLibraries.second);
             mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
 
             setThreadPolicy(oldPolicy);
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index e0e9b62..4da51c1 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -28,6 +28,7 @@
 per-file Service* = file:/services/core/java/com/android/server/am/OWNERS
 per-file SystemServiceRegistry.java = file:/services/core/java/com/android/server/am/OWNERS
 per-file *UserSwitchObserver* = file:/services/core/java/com/android/server/am/OWNERS
+per-file UiAutomation.java = file:/services/accessibility/OWNERS
 
 # ActivityThread
 per-file ActivityThread.java = file:/services/core/java/com/android/server/am/OWNERS
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 32ea41b..e2fd359 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1914,39 +1914,6 @@
         public abstract T createService() throws ServiceNotFoundException;
     }
 
-    /**
-     * Like StaticServiceFetcher, creates only one instance of the service per application, but when
-     * creating the service for the first time, passes it the application context of the creating
-     * application.
-     *
-     * TODO: Delete this once its only user (ConnectivityManager) is known to work well in the
-     * case where multiple application components each have their own ConnectivityManager object.
-     */
-    static abstract class StaticApplicationContextServiceFetcher<T> implements ServiceFetcher<T> {
-        private T mCachedInstance;
-
-        @Override
-        public final T getService(ContextImpl ctx) {
-            synchronized (StaticApplicationContextServiceFetcher.this) {
-                if (mCachedInstance == null) {
-                    Context appContext = ctx.getApplicationContext();
-                    // If the application context is null, we're either in the system process or
-                    // it's the application context very early in app initialization. In both these
-                    // cases, the passed-in ContextImpl will not be freed, so it's safe to pass it
-                    // to the service. http://b/27532714 .
-                    try {
-                        mCachedInstance = createService(appContext != null ? appContext : ctx);
-                    } catch (ServiceNotFoundException e) {
-                        onServiceNotFound(e);
-                    }
-                }
-                return mCachedInstance;
-            }
-        }
-
-        public abstract T createService(Context applicationContext) throws ServiceNotFoundException;
-    }
-
     /** @hide */
     public static void onServiceNotFound(ServiceNotFoundException e) {
         // We're mostly interested in tracking down long-lived core system
diff --git a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
index df065bf..c17a7b4 100644
--- a/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
+++ b/core/java/android/bluetooth/BluetoothActivityEnergyInfo.java
@@ -16,18 +16,26 @@
 
 package android.bluetooth;
 
+import android.annotation.ElapsedRealtimeLong;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.util.Arrays;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
+import java.util.List;
 
 /**
  * Record of energy and activity information from controller and
  * underlying bt stack state.Timestamp the record with system
- * time
+ * time.
  *
  * @hide
  */
+@SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
 public final class BluetoothActivityEnergyInfo implements Parcelable {
     private final long mTimestamp;
     private int mBluetoothStackState;
@@ -35,13 +43,24 @@
     private long mControllerRxTimeMs;
     private long mControllerIdleTimeMs;
     private long mControllerEnergyUsed;
-    private UidTraffic[] mUidTraffic;
+    private List<UidTraffic> mUidTraffic;
+
+    /** @hide */
+    @IntDef(prefix = { "BT_STACK_STATE_" }, value = {
+            BT_STACK_STATE_INVALID,
+            BT_STACK_STATE_STATE_ACTIVE,
+            BT_STACK_STATE_STATE_SCANNING,
+            BT_STACK_STATE_STATE_IDLE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface BluetoothStackState {}
 
     public static final int BT_STACK_STATE_INVALID = 0;
     public static final int BT_STACK_STATE_STATE_ACTIVE = 1;
     public static final int BT_STACK_STATE_STATE_SCANNING = 2;
     public static final int BT_STACK_STATE_STATE_IDLE = 3;
 
+    /** @hide */
     public BluetoothActivityEnergyInfo(long timestamp, int stackState,
             long txTime, long rxTime, long idleTime, long energyUsed) {
         mTimestamp = timestamp;
@@ -52,17 +71,18 @@
         mControllerEnergyUsed = energyUsed;
     }
 
-    @SuppressWarnings("unchecked")
-    BluetoothActivityEnergyInfo(Parcel in) {
+    /** @hide */
+    private BluetoothActivityEnergyInfo(Parcel in) {
         mTimestamp = in.readLong();
         mBluetoothStackState = in.readInt();
         mControllerTxTimeMs = in.readLong();
         mControllerRxTimeMs = in.readLong();
         mControllerIdleTimeMs = in.readLong();
         mControllerEnergyUsed = in.readLong();
-        mUidTraffic = in.createTypedArray(UidTraffic.CREATOR);
+        mUidTraffic = in.createTypedArrayList(UidTraffic.CREATOR);
     }
 
+    /** @hide */
     @Override
     public String toString() {
         return "BluetoothActivityEnergyInfo{"
@@ -72,11 +92,11 @@
                 + " mControllerRxTimeMs=" + mControllerRxTimeMs
                 + " mControllerIdleTimeMs=" + mControllerIdleTimeMs
                 + " mControllerEnergyUsed=" + mControllerEnergyUsed
-                + " mUidTraffic=" + Arrays.toString(mUidTraffic)
+                + " mUidTraffic=" + mUidTraffic
                 + " }";
     }
 
-    public static final @android.annotation.NonNull Parcelable.Creator<BluetoothActivityEnergyInfo> CREATOR =
+    public static final @NonNull Parcelable.Creator<BluetoothActivityEnergyInfo> CREATOR =
             new Parcelable.Creator<BluetoothActivityEnergyInfo>() {
                 public BluetoothActivityEnergyInfo createFromParcel(Parcel in) {
                     return new BluetoothActivityEnergyInfo(in);
@@ -87,9 +107,8 @@
                 }
             };
 
-
+    /** @hide */
     @Override
-    @SuppressWarnings("unchecked")
     public void writeToParcel(Parcel out, int flags) {
         out.writeLong(mTimestamp);
         out.writeInt(mBluetoothStackState);
@@ -97,17 +116,21 @@
         out.writeLong(mControllerRxTimeMs);
         out.writeLong(mControllerIdleTimeMs);
         out.writeLong(mControllerEnergyUsed);
-        out.writeTypedArray(mUidTraffic, flags);
+        out.writeTypedList(mUidTraffic);
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
     }
 
     /**
-     * @return bt stack reported state
+     * Get the Bluetooth stack state associated with the energy info.
+     *
+     * @return one of {@link #BluetoothStackState} states
      */
+    @BluetoothStackState
     public int getBluetoothStackState() {
         return mBluetoothStackState;
     }
@@ -134,7 +157,7 @@
     }
 
     /**
-     * product of current(mA), voltage(V) and time(ms)
+     * Get the product of current (mA), voltage (V), and time (ms).
      *
      * @return energy used
      */
@@ -143,22 +166,31 @@
     }
 
     /**
-     * @return timestamp(real time elapsed in milliseconds since boot) of record creation.
+     * @return timestamp (real time elapsed in milliseconds since boot) of record creation
      */
-    public long getTimeStamp() {
+    public @ElapsedRealtimeLong long getTimestampMillis() {
         return mTimestamp;
     }
 
-    public UidTraffic[] getUidTraffic() {
+    /**
+     * Get the {@link List} of each application {@link android.bluetooth.UidTraffic}.
+     *
+     * @return current {@link List} of {@link android.bluetooth.UidTraffic}
+     */
+    public @NonNull List<UidTraffic> getUidTraffic() {
+        if (mUidTraffic == null) {
+            return Collections.emptyList();
+        }
         return mUidTraffic;
     }
 
-    public void setUidTraffic(UidTraffic[] traffic) {
+    /** @hide */
+    public void setUidTraffic(List<UidTraffic> traffic) {
         mUidTraffic = traffic;
     }
 
     /**
-     * @return if the record is valid
+     * @return true if the record Tx time, Rx time, and Idle time are more than 0.
      */
     public boolean isValid() {
         return ((mControllerTxTimeMs >= 0) && (mControllerRxTimeMs >= 0)
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 06ce053..dac8ffe 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -2272,6 +2272,66 @@
         return false;
     }
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {
+            BluetoothStatusCodes.SUCCESS,
+            BluetoothStatusCodes.ERROR_UNKNOWN,
+            BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED,
+            BluetoothStatusCodes.ERROR_FEATURE_NOT_SUPPORTED,
+    })
+    public @interface LeFeatureReturnValues {}
+
+    /**
+     * Returns {@link BluetoothStatusCodes#SUCCESS} if LE Connected Isochronous Stream Central
+     * feature is supported, returns {@link BluetoothStatusCodes#ERROR_FEATURE_NOT_SUPPORTED} if
+     * the feature is not supported or an error code.
+     *
+     * @return whether the chipset supports the LE Connected Isochronous Stream Central feature
+     */
+    @RequiresNoPermission
+    public @LeFeatureReturnValues int isCisCentralSupported() {
+        if (!getLeAccess()) {
+            return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+        }
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) {
+                return mService.isCisCentralSupported();
+            }
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return BluetoothStatusCodes.ERROR_UNKNOWN;
+    }
+
+    /**
+     * Returns {@link BluetoothStatusCodes#SUCCESS} if LE Periodic Advertising Sync Transfer Sender
+     * feature is supported, returns {@link BluetoothStatusCodes#ERROR_FEATURE_NOT_SUPPORTED} if the
+     * feature is not supported or an error code
+     *
+     * @return whether the chipset supports the LE Periodic Advertising Sync Transfer Sender feature
+     */
+    @RequiresNoPermission
+    public @LeFeatureReturnValues int isLePeriodicAdvertisingSyncTransferSenderSupported() {
+        if (!getLeAccess()) {
+            return BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED;
+        }
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) {
+                return mService.isLePeriodicAdvertisingSyncTransferSenderSupported();
+            }
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return BluetoothStatusCodes.ERROR_UNKNOWN;
+    }
+
     /**
      * Return the maximum LE advertising data length in bytes,
      * if LE Extended Advertising feature is supported, 0 otherwise.
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 9caeb29..c71fcc6 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1186,6 +1186,11 @@
         mAttributionSource = attributionSource;
     }
 
+    /** {@hide} */
+    public void prepareToEnterProcess(@NonNull AttributionSource attributionSource) {
+        setAttributionSource(attributionSource);
+    }
+
     @Override
     public boolean equals(@Nullable Object o) {
         if (o instanceof BluetoothDevice) {
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 83108d2..a5a2470 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -817,7 +817,7 @@
     @RequiresBluetoothConnectPermission
     @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
     public Bundle getCurrentAgEvents(BluetoothDevice device) {
-        if (DBG) log("getCurrentCalls()");
+        if (DBG) log("getCurrentAgEvents()");
         final IBluetoothHeadsetClient service =
                 getService();
         if (service != null && isEnabled() && isValidDevice(device)) {
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index b5df4db..20152f3 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -62,15 +62,15 @@
     private static final String TAG = "BluetoothManager";
     private static final boolean DBG = false;
 
-    private static AttributionSource sAttributionSource = null;
+    private final AttributionSource mAttributionSource;
     private final BluetoothAdapter mAdapter;
 
     /**
      * @hide
      */
     public BluetoothManager(Context context) {
-        sAttributionSource = resolveAttributionSource(context);
-        mAdapter = BluetoothAdapter.createAdapter(sAttributionSource);
+        mAttributionSource = resolveAttributionSource(context);
+        mAdapter = BluetoothAdapter.createAdapter(mAttributionSource);
     }
 
     /** {@hide} */
@@ -79,9 +79,6 @@
         if (context != null) {
             res = context.getAttributionSource();
         }
-        else if (sAttributionSource != null) {
-            return sAttributionSource;
-        }
         if (res == null) {
             res = ActivityThread.currentAttributionSource();
         }
@@ -201,8 +198,8 @@
             IBluetoothGatt iGatt = managerService.getBluetoothGatt();
             if (iGatt == null) return devices;
             devices = Attributable.setAttributionSource(
-                    iGatt.getDevicesMatchingConnectionStates(states, sAttributionSource),
-                    sAttributionSource);
+                    iGatt.getDevicesMatchingConnectionStates(states, mAttributionSource),
+                    mAttributionSource);
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
         }
diff --git a/core/java/android/bluetooth/BluetoothStatusCodes.java b/core/java/android/bluetooth/BluetoothStatusCodes.java
index 3e46c49..63e84ed 100644
--- a/core/java/android/bluetooth/BluetoothStatusCodes.java
+++ b/core/java/android/bluetooth/BluetoothStatusCodes.java
@@ -79,6 +79,11 @@
     public static final int ERROR_MISSING_BLUETOOTH_SCAN_PERMISSION = 7;
 
     /**
+     * Error code indicating that the feature is not supported.
+     */
+    public static final int ERROR_FEATURE_NOT_SUPPORTED = 8;
+
+    /**
      * If another application has already requested {@link OobData} then another fetch will be
      * disallowed until the callback is removed.
      *
diff --git a/core/java/android/bluetooth/UidTraffic.java b/core/java/android/bluetooth/UidTraffic.java
index 2ee786a..9982fa6 100644
--- a/core/java/android/bluetooth/UidTraffic.java
+++ b/core/java/android/bluetooth/UidTraffic.java
@@ -15,6 +15,7 @@
  */
 package android.bluetooth;
 
+import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -23,27 +24,27 @@
  *
  * @hide
  */
-public class UidTraffic implements Cloneable, Parcelable {
+@SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
+public final class UidTraffic implements Cloneable, Parcelable {
     private final int mAppUid;
     private long mRxBytes;
     private long mTxBytes;
 
-    public UidTraffic(int appUid) {
-        mAppUid = appUid;
-    }
-
+    /** @hide */
     public UidTraffic(int appUid, long rx, long tx) {
         mAppUid = appUid;
         mRxBytes = rx;
         mTxBytes = tx;
     }
 
-    UidTraffic(Parcel in) {
+    /** @hide */
+    private UidTraffic(Parcel in) {
         mAppUid = in.readInt();
         mRxBytes = in.readLong();
         mTxBytes = in.readLong();
     }
 
+    /** @hide */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mAppUid);
@@ -51,44 +52,60 @@
         dest.writeLong(mTxBytes);
     }
 
+    /** @hide */
     public void setRxBytes(long bytes) {
         mRxBytes = bytes;
     }
 
+    /** @hide */
     public void setTxBytes(long bytes) {
         mTxBytes = bytes;
     }
 
+    /** @hide */
     public void addRxBytes(long bytes) {
         mRxBytes += bytes;
     }
 
+    /** @hide */
     public void addTxBytes(long bytes) {
         mTxBytes += bytes;
     }
 
+    /**
+     * @return corresponding app Uid
+     */
     public int getUid() {
         return mAppUid;
     }
 
+    /**
+     * @return rx bytes count
+     */
     public long getRxBytes() {
         return mRxBytes;
     }
 
+    /**
+     * @return tx bytes count
+     */
     public long getTxBytes() {
         return mTxBytes;
     }
 
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /** @hide */
     @Override
     public UidTraffic clone() {
         return new UidTraffic(mAppUid, mRxBytes, mTxBytes);
     }
 
+    /** @hide */
     @Override
     public String toString() {
         return "UidTraffic{mAppUid=" + mAppUid + ", mRxBytes=" + mRxBytes + ", mTxBytes="
diff --git a/core/java/android/bluetooth/le/BluetoothLeUtils.java b/core/java/android/bluetooth/le/BluetoothLeUtils.java
index 6381f55..ed50b09 100644
--- a/core/java/android/bluetooth/le/BluetoothLeUtils.java
+++ b/core/java/android/bluetooth/le/BluetoothLeUtils.java
@@ -24,6 +24,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.UUID;
 
 /**
  * Helper class for Bluetooth LE utils.
@@ -137,4 +138,21 @@
         }
     }
 
+    /**
+     * Compares two UUIDs with a UUID mask.
+     *
+     * @param data first {@link #UUID} to compare.
+     * @param uuid second {@link #UUID} to compare.
+     * @param mask mask {@link #UUID}.
+     * @return true if both UUIDs are equals when masked, false otherwise.
+     */
+    static boolean maskedEquals(UUID data, UUID uuid, UUID mask) {
+        if (mask == null) {
+            return Objects.equals(data, uuid);
+        }
+        return (data.getLeastSignificantBits() & mask.getLeastSignificantBits())
+                == (uuid.getLeastSignificantBits() & mask.getLeastSignificantBits())
+                && (data.getMostSignificantBits() & mask.getMostSignificantBits())
+                == (uuid.getMostSignificantBits() & mask.getMostSignificantBits());
+    }
 }
diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java
index 8ff0181..b059193 100644
--- a/core/java/android/bluetooth/le/ScanFilter.java
+++ b/core/java/android/bluetooth/le/ScanFilter.java
@@ -28,8 +28,6 @@
 import android.os.ParcelUuid;
 import android.os.Parcelable;
 
-import com.android.internal.util.BitUtils;
-
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -448,7 +446,7 @@
 
     // Check if the uuid pattern matches the particular service uuid.
     private static boolean matchesServiceUuid(UUID uuid, UUID mask, UUID data) {
-        return BitUtils.maskedEquals(data, uuid, mask);
+        return BluetoothLeUtils.maskedEquals(data, uuid, mask);
     }
 
     /**
@@ -478,7 +476,7 @@
     // Check if the solicitation uuid pattern matches the particular service solicitation uuid.
     private static boolean matchesServiceSolicitationUuid(UUID solicitationUuid,
             UUID solicitationUuidMask, UUID data) {
-        return BitUtils.maskedEquals(data, solicitationUuid, solicitationUuidMask);
+        return BluetoothLeUtils.maskedEquals(data, solicitationUuid, solicitationUuidMask);
     }
 
     // Check whether the data pattern matches the parsed data.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2fd437d..d811040 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -31,6 +31,7 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.app.AppGlobals;
+import android.bluetooth.BluetoothDevice;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
@@ -11461,6 +11462,16 @@
         if (fromProtectedComponent) {
             mLocalFlags |= LOCAL_FLAG_FROM_PROTECTED_COMPONENT;
         }
+
+        // Special attribution fix-up logic for any BluetoothDevice extras
+        // passed via Bluetooth intents
+        if (mAction != null && mAction.startsWith("android.bluetooth.")
+                && hasExtra(BluetoothDevice.EXTRA_DEVICE)) {
+            final BluetoothDevice device = getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
+            if (device != null) {
+                device.prepareToEnterProcess(source);
+            }
+        }
     }
 
     /** @hide */
diff --git a/core/java/android/content/OWNERS b/core/java/android/content/OWNERS
index c7f92c9..660368a 100644
--- a/core/java/android/content/OWNERS
+++ b/core/java/android/content/OWNERS
@@ -2,11 +2,9 @@
 per-file Context.java = *
 per-file ContextWrapper.java = *
 per-file Content* = file:/services/core/java/com/android/server/am/OWNERS
-per-file IntentFilter.java = toddke@google.com
-per-file IntentFilter.java = patb@google.com
+per-file IntentFilter.java = file:/PACKAGE_MANAGER_OWNERS
 per-file IntentFilter.java = file:/services/core/java/com/android/server/am/OWNERS
-per-file Intent.java = toddke@google.com
-per-file Intent.java = patb@google.com
+per-file Intent.java = file:/PACKAGE_MANAGER_OWNERS
 per-file Intent.java = file:/services/core/java/com/android/server/wm/OWNERS
 per-file Intent.java = file:/services/core/java/com/android/server/am/OWNERS
 per-file AutofillOptions* = file:/core/java/android/service/autofill/OWNERS
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 1d07a03..eb8f43e 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -220,8 +220,10 @@
         String networkId = null;
         boolean roaming = !snapshot.getNetworkCapabilities().hasCapability(
                 NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-        boolean metered = !snapshot.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+        boolean metered = !(snapshot.getNetworkCapabilities().hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
+                || snapshot.getNetworkCapabilities().hasCapability(
+                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
 
         final int oemManaged = getOemBitfield(snapshot.getNetworkCapabilities());
 
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 08f75df..74506da 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -160,19 +160,19 @@
     }
 
     /**
-     * Template to match cellular networks with the given IMSI and {@code ratType}.
-     * Use {@link #NETWORK_TYPE_ALL} to include all network types when filtering.
-     * See {@code TelephonyManager.NETWORK_TYPE_*}.
+     * Template to match cellular networks with the given IMSI, {@code ratType} and
+     * {@code metered}. Use {@link #NETWORK_TYPE_ALL} to include all network types when
+     * filtering. See {@code TelephonyManager.NETWORK_TYPE_*}.
      */
     public static NetworkTemplate buildTemplateMobileWithRatType(@Nullable String subscriberId,
-            @NetworkType int ratType) {
+            @NetworkType int ratType, int metered) {
         if (TextUtils.isEmpty(subscriberId)) {
             return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null, null,
-                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
+                    metered, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
                     SUBSCRIBER_ID_MATCH_RULE_EXACT);
         }
         return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[]{subscriberId}, null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
+                metered, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL,
                 SUBSCRIBER_ID_MATCH_RULE_EXACT);
     }
 
@@ -305,6 +305,7 @@
         }
     }
 
+    // TODO: Deprecate this constructor, mark it @UnsupportedAppUsage(maxTargetSdk = S)
     @UnsupportedAppUsage
     public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
         this(matchRule, subscriberId, new String[] { subscriberId }, networkId);
@@ -312,9 +313,14 @@
 
     public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
             String networkId) {
-        this(matchRule, subscriberId, matchSubscriberIds, networkId, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
-                SUBSCRIBER_ID_MATCH_RULE_EXACT);
+        // Older versions used to only match MATCH_MOBILE and MATCH_MOBILE_WILDCARD templates
+        // to metered networks. It is now possible to match mobile with any meteredness, but
+        // in order to preserve backward compatibility of @UnsupportedAppUsage methods, this
+        //constructor passes METERED_YES for these types.
+        this(matchRule, subscriberId, matchSubscriberIds, networkId,
+                (matchRule == MATCH_MOBILE || matchRule == MATCH_MOBILE_WILDCARD) ? METERED_YES
+                : METERED_ALL , ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                OEM_MANAGED_ALL, SUBSCRIBER_ID_MATCH_RULE_EXACT);
     }
 
     // TODO: Remove it after updating all of the caller.
@@ -589,11 +595,7 @@
             // TODO: consider matching against WiMAX subscriber identity
             return true;
         } else {
-            // Only metered mobile network would be matched regardless of metered filter.
-            // This is used to exclude non-metered APNs, e.g. IMS. See ag/908650.
-            // TODO: Respect metered filter and remove mMetered condition.
-            return (ident.mType == TYPE_MOBILE && ident.mMetered)
-                    && !ArrayUtils.isEmpty(mMatchSubscriberIds)
+            return ident.mType == TYPE_MOBILE && !ArrayUtils.isEmpty(mMatchSubscriberIds)
                     && ArrayUtils.contains(mMatchSubscriberIds, ident.mSubscriberId)
                     && matchesCollapsedRatType(ident);
         }
@@ -707,8 +709,7 @@
         if (ident.mType == TYPE_WIMAX) {
             return true;
         } else {
-            return (ident.mType == TYPE_MOBILE && ident.mMetered)
-                    && matchesCollapsedRatType(ident);
+            return ident.mType == TYPE_MOBILE && matchesCollapsedRatType(ident);
         }
     }
 
diff --git a/core/java/android/net/TEST_MAPPING b/core/java/android/net/TEST_MAPPING
index 8c13ef9..a379c33 100644
--- a/core/java/android/net/TEST_MAPPING
+++ b/core/java/android/net/TEST_MAPPING
@@ -16,5 +16,24 @@
     {
       "path": "frameworks/opt/net/wifi"
     }
+  ],
+  "postsubmit": [
+    {
+      "name": "FrameworksCoreTests",
+      "options": [
+        {
+          "include-filter": "android.net"
+        },
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        },
+        {
+          "exclude-annotation": "org.junit.Ignore"
+        }
+      ]
+    }
   ]
 }
diff --git a/core/java/android/net/sntp/Duration64.java b/core/java/android/net/sntp/Duration64.java
index 939b289..7f29cdb 100644
--- a/core/java/android/net/sntp/Duration64.java
+++ b/core/java/android/net/sntp/Duration64.java
@@ -26,7 +26,7 @@
  *
  * @hide
  */
-public class Duration64 {
+public final class Duration64 {
 
     public static final Duration64 ZERO = new Duration64(0);
     private final long mBits;
diff --git a/core/java/android/net/sntp/Timestamp64.java b/core/java/android/net/sntp/Timestamp64.java
index 81a3310..8ddfd77 100644
--- a/core/java/android/net/sntp/Timestamp64.java
+++ b/core/java/android/net/sntp/Timestamp64.java
@@ -15,6 +15,8 @@
  */
 package android.net.sntp;
 
+import android.text.TextUtils;
+
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.time.Instant;
@@ -113,7 +115,7 @@
 
     @Override
     public String toString() {
-        return String.format("%08x.%08x", mEraSeconds, mFractionBits);
+        return TextUtils.formatSimple("%08x.%08x", mEraSeconds, mFractionBits);
     }
 
     /** Returns the instant represented by this value in the specified NTP era. */
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
index 09f5283..be57372 100644
--- a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
+++ b/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
@@ -79,6 +79,7 @@
         IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH);
         IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_MOBIKE);
         IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_FORCE_PORT_4500);
+        IKE_OPTIONS.add(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT);
     }
 
     /** Serializes an IkeSessionParams to a PersistableBundle. */
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 635f581..b677b69 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -313,7 +313,7 @@
      * @hide
      */
     @CriticalNative
-    public static final native boolean isHandlingTransaction();
+    public static final native boolean isDirectlyHandlingTransaction();
 
     /**
      * Return the Linux uid assigned to the process that sent the transaction
@@ -323,7 +323,7 @@
      *        executing an incoming transaction.
      */
     public static final int getCallingUidOrThrow() {
-        if (!isHandlingTransaction()) {
+        if (!isDirectlyHandlingTransaction()) {
             throw new IllegalStateException(
                   "Thread is not in a binder transcation");
         }
diff --git a/core/java/android/os/BytesMatcher.java b/core/java/android/os/BytesMatcher.java
deleted file mode 100644
index 8974c5e..0000000
--- a/core/java/android/os/BytesMatcher.java
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2021 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.os;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.bluetooth.BluetoothUuid;
-import android.net.MacAddress;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.internal.util.HexDump;
-
-import java.util.ArrayList;
-import java.util.function.Predicate;
-
-/**
- * Predicate that tests if a given {@code byte[]} value matches a set of
- * configured rules.
- * <p>
- * Rules are tested in the order in which they were originally added, which
- * means a narrow rule can reject a specific value before a later broader rule
- * might accept that same value, or vice versa.
- * <p>
- * Matchers can contain rules of varying lengths, and tested values will only be
- * matched against rules of the exact same length. This is designed to support
- * {@link BluetoothUuid} style values which can be variable length.
- *
- * @hide
- */
-public class BytesMatcher implements Predicate<byte[]> {
-    private static final String TAG = "BytesMatcher";
-
-    private static final char TYPE_EXACT_ACCEPT = '+';
-    private static final char TYPE_EXACT_REJECT = '-';
-    private static final char TYPE_PREFIX_ACCEPT = '⊆';
-    private static final char TYPE_PREFIX_REJECT = '⊈';
-
-    private final ArrayList<Rule> mRules = new ArrayList<>();
-
-    private static class Rule {
-        public final char type;
-        public final @NonNull byte[] value;
-        public final @Nullable byte[] mask;
-
-        public Rule(char type, @NonNull byte[] value, @Nullable byte[] mask) {
-            if (mask != null && value.length != mask.length) {
-                throw new IllegalArgumentException(
-                        "Expected length " + value.length + " but found " + mask.length);
-            }
-            this.type = type;
-            this.value = value;
-            this.mask = mask;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            encode(builder);
-            return builder.toString();
-        }
-
-        public void encode(@NonNull StringBuilder builder) {
-            builder.append(type);
-            builder.append(HexDump.toHexString(value));
-            if (mask != null) {
-                builder.append('/');
-                builder.append(HexDump.toHexString(mask));
-            }
-        }
-
-        public boolean test(@NonNull byte[] value) {
-            switch (type) {
-                case TYPE_EXACT_ACCEPT:
-                case TYPE_EXACT_REJECT:
-                    if (value.length != this.value.length) {
-                        return false;
-                    }
-                    break;
-                case TYPE_PREFIX_ACCEPT:
-                case TYPE_PREFIX_REJECT:
-                    if (value.length < this.value.length) {
-                        return false;
-                    }
-                    break;
-            }
-            for (int i = 0; i < this.value.length; i++) {
-                byte local = this.value[i];
-                byte remote = value[i];
-                if (this.mask != null) {
-                    local &= this.mask[i];
-                    remote &= this.mask[i];
-                }
-                if (local != remote) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Add a rule that will result in {@link #test(byte[])} returning
-     * {@code true} when a value being tested matches it. This rule will only
-     * match values of the exact same length.
-     * <p>
-     * Rules are tested in the order in which they were originally added, which
-     * means a narrow rule can reject a specific value before a later broader
-     * rule might accept that same value, or vice versa.
-     *
-     * @param value to be matched
-     * @param mask to be applied to both values before testing for equality; if
-     *            {@code null} then both values must match exactly
-     */
-    public void addExactAcceptRule(@NonNull byte[] value, @Nullable byte[] mask) {
-        mRules.add(new Rule(TYPE_EXACT_ACCEPT, value, mask));
-    }
-
-    /**
-     * Add a rule that will result in {@link #test(byte[])} returning
-     * {@code false} when a value being tested matches it. This rule will only
-     * match values of the exact same length.
-     * <p>
-     * Rules are tested in the order in which they were originally added, which
-     * means a narrow rule can reject a specific value before a later broader
-     * rule might accept that same value, or vice versa.
-     *
-     * @param value to be matched
-     * @param mask to be applied to both values before testing for equality; if
-     *            {@code null} then both values must match exactly
-     */
-    public void addExactRejectRule(@NonNull byte[] value, @Nullable byte[] mask) {
-        mRules.add(new Rule(TYPE_EXACT_REJECT, value, mask));
-    }
-
-    /**
-     * Add a rule that will result in {@link #test(byte[])} returning
-     * {@code true} when a value being tested matches it. This rule will match
-     * values of the exact same length or longer.
-     * <p>
-     * Rules are tested in the order in which they were originally added, which
-     * means a narrow rule can reject a specific value before a later broader
-     * rule might accept that same value, or vice versa.
-     *
-     * @param value to be matched
-     * @param mask to be applied to both values before testing for equality; if
-     *            {@code null} then both values must match exactly
-     */
-    public void addPrefixAcceptRule(@NonNull byte[] value, @Nullable byte[] mask) {
-        mRules.add(new Rule(TYPE_PREFIX_ACCEPT, value, mask));
-    }
-
-    /**
-     * Add a rule that will result in {@link #test(byte[])} returning
-     * {@code false} when a value being tested matches it. This rule will match
-     * values of the exact same length or longer.
-     * <p>
-     * Rules are tested in the order in which they were originally added, which
-     * means a narrow rule can reject a specific value before a later broader
-     * rule might accept that same value, or vice versa.
-     *
-     * @param value to be matched
-     * @param mask to be applied to both values before testing for equality; if
-     *            {@code null} then both values must match exactly
-     */
-    public void addPrefixRejectRule(@NonNull byte[] value, @Nullable byte[] mask) {
-        mRules.add(new Rule(TYPE_PREFIX_REJECT, value, mask));
-    }
-
-    /**
-     * Test if the given {@code ParcelUuid} value matches the set of rules
-     * configured in this matcher.
-     */
-    public boolean testBluetoothUuid(@NonNull ParcelUuid value) {
-        return test(BluetoothUuid.uuidToBytes(value));
-    }
-
-    /**
-     * Test if the given {@code MacAddress} value matches the set of rules
-     * configured in this matcher.
-     */
-    public boolean testMacAddress(@NonNull MacAddress value) {
-        return test(value.toByteArray());
-    }
-
-    /**
-     * Test if the given {@code byte[]} value matches the set of rules
-     * configured in this matcher.
-     */
-    @Override
-    public boolean test(@NonNull byte[] value) {
-        return test(value, false);
-    }
-
-    /**
-     * Test if the given {@code byte[]} value matches the set of rules
-     * configured in this matcher.
-     */
-    public boolean test(@NonNull byte[] value, boolean defaultValue) {
-        final int size = mRules.size();
-        for (int i = 0; i < size; i++) {
-            final Rule rule = mRules.get(i);
-            if (rule.test(value)) {
-                switch (rule.type) {
-                    case TYPE_EXACT_ACCEPT:
-                    case TYPE_PREFIX_ACCEPT:
-                        return true;
-                    case TYPE_EXACT_REJECT:
-                    case TYPE_PREFIX_REJECT:
-                        return false;
-                }
-            }
-        }
-        return defaultValue;
-    }
-
-    /**
-     * Encode the given matcher into a human-readable {@link String} which can
-     * be used to transport matchers across device boundaries.
-     * <p>
-     * The human-readable format is an ordered list separated by commas, where
-     * each rule is a {@code +} or {@code -} symbol indicating if the match
-     * should be accepted or rejected, then followed by a hex value and an
-     * optional hex mask. For example, {@code -caff,+cafe/ff00} is a valid
-     * encoded matcher.
-     *
-     * @see #decode(String)
-     */
-    public static @NonNull String encode(@NonNull BytesMatcher matcher) {
-        final StringBuilder builder = new StringBuilder();
-        final int size = matcher.mRules.size();
-        for (int i = 0; i < size; i++) {
-            final Rule rule = matcher.mRules.get(i);
-            rule.encode(builder);
-            builder.append(',');
-        }
-        if (builder.length() > 0) {
-            builder.deleteCharAt(builder.length() - 1);
-        }
-        return builder.toString();
-    }
-
-    /**
-     * Decode the given human-readable {@link String} used to transport matchers
-     * across device boundaries.
-     * <p>
-     * The human-readable format is an ordered list separated by commas, where
-     * each rule is a {@code +} or {@code -} symbol indicating if the match
-     * should be accepted or rejected, then followed by a hex value and an
-     * optional hex mask. For example, {@code -caff,+cafe/ff00} is a valid
-     * encoded matcher.
-     *
-     * @see #encode(BytesMatcher)
-     */
-    public static @NonNull BytesMatcher decode(@Nullable String value) {
-        final BytesMatcher matcher = new BytesMatcher();
-        if (TextUtils.isEmpty(value)) return matcher;
-
-        final int length = value.length();
-        for (int i = 0; i < length;) {
-            final char type = value.charAt(i);
-
-            int nextRule = value.indexOf(',', i);
-            int nextMask = value.indexOf('/', i);
-
-            if (nextRule == -1) nextRule = length;
-            if (nextMask > nextRule) nextMask = -1;
-
-            final byte[] ruleValue;
-            final byte[] ruleMask;
-            if (nextMask >= 0) {
-                ruleValue = HexDump.hexStringToByteArray(value.substring(i + 1, nextMask));
-                ruleMask = HexDump.hexStringToByteArray(value.substring(nextMask + 1, nextRule));
-            } else {
-                ruleValue = HexDump.hexStringToByteArray(value.substring(i + 1, nextRule));
-                ruleMask = null;
-            }
-
-            switch (type) {
-                case TYPE_EXACT_ACCEPT:
-                    matcher.addExactAcceptRule(ruleValue, ruleMask);
-                    break;
-                case TYPE_EXACT_REJECT:
-                    matcher.addExactRejectRule(ruleValue, ruleMask);
-                    break;
-                case TYPE_PREFIX_ACCEPT:
-                    matcher.addPrefixAcceptRule(ruleValue, ruleMask);
-                    break;
-                case TYPE_PREFIX_REJECT:
-                    matcher.addPrefixRejectRule(ruleValue, ruleMask);
-                    break;
-                default:
-                    Log.w(TAG, "Ignoring unknown type " + type);
-                    break;
-            }
-
-            i = nextRule + 1;
-        }
-        return matcher;
-    }
-}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index ab2c8c0..dd0cb8c 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -20,6 +20,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SuppressLint;
 import android.annotation.TestApi;
 import android.app.AppOpsManager;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -380,6 +381,8 @@
     private static native void nativeUnmarshall(
             long nativePtr, byte[] data, int offset, int length);
     private static native int nativeCompareData(long thisNativePtr, long otherNativePtr);
+    private static native boolean nativeCompareDataInRange(
+            long ptrA, int offsetA, long ptrB, int offsetB, int length);
     private static native void nativeAppendFrom(
             long thisNativePtr, long otherNativePtr, int offset, int length);
     @CriticalNative
@@ -677,11 +680,16 @@
     }
 
     /** @hide */
-    public final int compareData(Parcel other) {
+    public int compareData(Parcel other) {
         return nativeCompareData(mNativePtr, other.mNativePtr);
     }
 
     /** @hide */
+    public static boolean compareData(Parcel a, int offsetA, Parcel b, int offsetB, int length) {
+        return nativeCompareDataInRange(a.mNativePtr, offsetA, b.mNativePtr, offsetB, length);
+    }
+
+    /** @hide */
     public final void setClassCookie(Class clz, Object cookie) {
         if (mClassCookies == null) {
             mClassCookies = new ArrayMap<>();
@@ -2440,9 +2448,9 @@
 
             writeByteArray(baos.toByteArray());
         } catch (IOException ioe) {
-            throw new RuntimeException("Parcelable encountered " +
-                "IOException writing serializable object (name = " + name +
-                ")", ioe);
+            throw new BadParcelableException("Parcelable encountered "
+                    + "IOException writing serializable object (name = "
+                    + name + ")", ioe);
         }
     }
 
@@ -3094,14 +3102,24 @@
      * Parcelables.
      */
     @Nullable
-    public final ArrayList readArrayList(@Nullable ClassLoader loader) {
-        int N = readInt();
-        if (N < 0) {
-            return null;
-        }
-        ArrayList l = new ArrayList(N);
-        readListInternal(l, N, loader, /* clazz */ null);
-        return l;
+    public ArrayList readArrayList(@Nullable ClassLoader loader) {
+        return readArrayListInternal(loader, /* clazz */ null);
+    }
+
+    /**
+     * Same as {@link #readArrayList(ClassLoader)} but accepts {@code clazz} parameter as
+     * the type required for each item.
+     *
+     * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
+     * is not an instance of that class or any of its children classes or there was an error
+     * trying to instantiate an element.
+     */
+    @SuppressLint({"ConcreteCollection", "NullableCollection"})
+    @Nullable
+    public <T> ArrayList<T> readArrayList(@Nullable ClassLoader loader,
+            @NonNull Class<? extends T> clazz) {
+        Objects.requireNonNull(clazz);
+        return readArrayListInternal(loader, clazz);
     }
 
     /**
@@ -3111,14 +3129,23 @@
      * Parcelables.
      */
     @Nullable
-    public final Object[] readArray(@Nullable ClassLoader loader) {
-        int N = readInt();
-        if (N < 0) {
-            return null;
-        }
-        Object[] l = new Object[N];
-        readArrayInternal(l, N, loader);
-        return l;
+    public Object[] readArray(@Nullable ClassLoader loader) {
+        return readArrayInternal(loader, /* clazz */ null);
+    }
+
+    /**
+     * Same as {@link #readArray(ClassLoader)} but accepts {@code clazz} parameter as
+     * the type required for each item.
+     *
+     * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
+     * is not an instance of that class or any of its children classes or there was an error
+     * trying to instantiate an element.
+     */
+    @SuppressLint({"ArrayReturn", "NullableCollection"})
+    @Nullable
+    public <T> T[] readArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+        Objects.requireNonNull(clazz);
+        return readArrayInternal(loader, clazz);
     }
 
     /**
@@ -3128,14 +3155,23 @@
      * Parcelables.
      */
     @Nullable
-    public final <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader) {
-        int N = readInt();
-        if (N < 0) {
-            return null;
-        }
-        SparseArray sa = new SparseArray(N);
-        readSparseArrayInternal(sa, N, loader);
-        return sa;
+    public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader) {
+        return readSparseArrayInternal(loader, /* clazz */ null);
+    }
+
+    /**
+     * Same as {@link #readSparseArray(ClassLoader)} but accepts {@code clazz} parameter as
+     * the type required for each item.
+     *
+     * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
+     * is not an instance of that class or any of its children classes or there was an error
+     * trying to instantiate an element.
+     */
+    @Nullable
+    public <T> SparseArray<T> readSparseArray(@Nullable ClassLoader loader,
+            @NonNull Class<? extends T> clazz) {
+        Objects.requireNonNull(clazz);
+        return readSparseArrayInternal(loader, clazz);
     }
 
     /**
@@ -3580,7 +3616,6 @@
         private final int mType;
         @Nullable private final ClassLoader mLoader;
         @Nullable private Object mObject;
-        @Nullable private volatile Parcel mValueParcel;
 
         /**
          * This goes from non-null to null once. Always check the nullability of this object before
@@ -3678,7 +3713,7 @@
                 return false;
             }
             // Finally we compare the payload.
-            return getValueParcel(source).compareData(value.getValueParcel(otherSource)) == 0;
+            return Parcel.compareData(source, mPosition, otherSource, value.mPosition, mLength);
         }
 
         @Override
@@ -3686,17 +3721,6 @@
             // Accessing mSource first to provide memory barrier for mObject
             return Objects.hash(mSource == null, mObject, mLoader, mType, mLength);
         }
-
-        /** This extracts the parcel section responsible for the object and returns it. */
-        private Parcel getValueParcel(Parcel source) {
-            Parcel parcel = mValueParcel;
-            if (parcel == null) {
-                parcel = Parcel.obtain();
-                parcel.appendFrom(source, mPosition, mLength);
-                mValueParcel = parcel;
-            }
-            return parcel;
-        }
     }
 
     /**
@@ -3794,7 +3818,7 @@
                 break;
 
             case VAL_SERIALIZABLE:
-                object = readSerializable(loader);
+                object = readSerializableInternal(loader, clazz);
                 break;
 
             case VAL_PARCELABLEARRAY:
@@ -3851,7 +3875,7 @@
                     "Parcel " + this + ": Unmarshalling unknown type code " + type
                             + " at offset " + off);
         }
-        if (clazz != null && !clazz.isInstance(object)) {
+        if (object != null && clazz != null && !clazz.isInstance(object)) {
             throw new BadParcelableException("Unparcelled object " + object
                     + " is not an instance of required class " + clazz.getName()
                     + " provided in the parameter");
@@ -3910,7 +3934,6 @@
     }
 
     /**
-     *
      * @param clazz The type of the parcelable expected or {@code null} for performing no checks.
      */
     @SuppressWarnings("unchecked")
@@ -3969,7 +3992,7 @@
      * as the required type.
      *
      * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
-     * is not an instance of that class or any of its children class or there there was an error
+     * is not an instance of that class or any of its children classes or there there was an error
      * trying to read the {@link Parcelable.Creator}.
      */
     @Nullable
@@ -4092,17 +4115,25 @@
         return p;
     }
 
-    /** @hide */
+    /**
+     * Same as {@link #readParcelableArray(ClassLoader)}  but accepts {@code clazz} parameter as
+     * the type required for each item.
+     *
+     * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
+     * is not an instance of that class or any of its children classes or there was an error
+     * trying to instantiate an element.
+     */
+    @SuppressLint({"ArrayReturn", "NullableCollection"})
+    @SuppressWarnings("unchecked")
     @Nullable
-    public final <T extends Parcelable> T[] readParcelableArray(@Nullable ClassLoader loader,
-            @NonNull Class<T> clazz) {
-        int N = readInt();
-        if (N < 0) {
+    public <T> T[] readParcelableArray(@Nullable ClassLoader loader, @NonNull Class<T> clazz) {
+        int n = readInt();
+        if (n < 0) {
             return null;
         }
-        T[] p = (T[]) Array.newInstance(clazz, N);
-        for (int i = 0; i < N; i++) {
-            p[i] = readParcelable(loader);
+        T[] p = (T[]) Array.newInstance(clazz, n);
+        for (int i = 0; i < n; i++) {
+            p[i] = readParcelableInternal(loader, clazz);
         }
         return p;
     }
@@ -4113,12 +4144,37 @@
      * wasn't found in the parcel.
      */
     @Nullable
-    public final Serializable readSerializable() {
-        return readSerializable(null);
+    public Serializable readSerializable() {
+        return readSerializableInternal(/* loader */ null, /* clazz */ null);
     }
 
+    /**
+     * Same as {@link #readSerializable()} but accepts {@code loader} parameter
+     * as the primary classLoader for resolving the Serializable class; and {@code clazz} parameter
+     * as the required type.
+     *
+     * @throws BadParcelableException Throws BadParcelableException if the item to be deserialized
+     * is not an instance of that class or any of its children class or there there was an error
+     * deserializing the object.
+     */
     @Nullable
-    private final Serializable readSerializable(@Nullable final ClassLoader loader) {
+    public <T extends Serializable> T readSerializable(@Nullable ClassLoader loader,
+            @NonNull Class<T> clazz) {
+        Objects.requireNonNull(clazz);
+        return readSerializableInternal(loader, clazz);
+    }
+
+    /**
+     * @param clazz The type of the serializable expected or {@code null} for performing no checks
+     */
+    @Nullable
+    private <T> T readSerializableInternal(@Nullable final ClassLoader loader,
+            @Nullable Class<T> clazz) {
+        if (clazz != null && !Serializable.class.isAssignableFrom(clazz)) {
+            throw new BadParcelableException("About to unparcel a serializable object "
+                    + " but class required " + clazz.getName() + " is not Serializable");
+        }
+
         String name = readString();
         if (name == null) {
             // For some reason we were unable to read the name of the Serializable (either there
@@ -4127,9 +4183,20 @@
             return null;
         }
 
-        byte[] serializedData = createByteArray();
-        ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
         try {
+            if (clazz != null && loader != null) {
+                // If custom classloader is provided, resolve the type of serializable using the
+                // name, then check the type before deserialization. As in this case we can resolve
+                // the class the same way as ObjectInputStream, using the provided classloader.
+                Class<?> cl = Class.forName(name, false, loader);
+                if (!clazz.isAssignableFrom(cl)) {
+                    throw new BadParcelableException("Serializable object "
+                            + cl.getName() + " is not a subclass of required class "
+                            + clazz.getName() + " provided in the parameter");
+                }
+            }
+            byte[] serializedData = createByteArray();
+            ByteArrayInputStream bais = new ByteArrayInputStream(serializedData);
             ObjectInputStream ois = new ObjectInputStream(bais) {
                 @Override
                 protected Class<?> resolveClass(ObjectStreamClass osClass)
@@ -4137,22 +4204,31 @@
                     // try the custom classloader if provided
                     if (loader != null) {
                         Class<?> c = Class.forName(osClass.getName(), false, loader);
-                        if (c != null) {
-                            return c;
-                        }
+                        return Objects.requireNonNull(c);
                     }
                     return super.resolveClass(osClass);
                 }
             };
-            return (Serializable) ois.readObject();
+            T object = (T) ois.readObject();
+            if (clazz != null && loader == null) {
+                // If custom classloader is not provided, check the type of the serializable using
+                // the deserialized object, as we cannot resolve the class the same way as
+                // ObjectInputStream.
+                if (!clazz.isAssignableFrom(object.getClass())) {
+                    throw new BadParcelableException("Serializable object "
+                            + object.getClass().getName() + " is not a subclass of required class "
+                            + clazz.getName() + " provided in the parameter");
+                }
+            }
+            return object;
         } catch (IOException ioe) {
-            throw new RuntimeException("Parcelable encountered " +
-                "IOException reading a Serializable object (name = " + name +
-                ")", ioe);
+            throw new BadParcelableException("Parcelable encountered "
+                    + "IOException reading a Serializable object (name = "
+                    + name + ")", ioe);
         } catch (ClassNotFoundException cnfe) {
-            throw new RuntimeException("Parcelable encountered " +
-                "ClassNotFoundException reading a Serializable object (name = "
-                + name + ")", cnfe);
+            throw new BadParcelableException("Parcelable encountered "
+                    + "ClassNotFoundException reading a Serializable object (name = "
+                    + name + ")", cnfe);
         }
     }
 
@@ -4320,9 +4396,12 @@
         return result;
     }
 
-    private void readListInternal(@NonNull List outVal, int n,
-            @Nullable ClassLoader loader) {
-        readListInternal(outVal, n, loader, null);
+    /**
+     * The method is replaced by {@link #readListInternal(List, int, ClassLoader, Class)}, however
+     * we are keeping this unused method here to allow unsupported app usages.
+     */
+    private void readListInternal(@NonNull List outVal, int n, @Nullable ClassLoader loader) {
+        readListInternal(outVal, n, loader,  /* clazz */ null);
     }
 
     /**
@@ -4338,26 +4417,88 @@
         }
     }
 
+    /**
+     * @param clazz The type of the object expected or {@code null} for performing no checks.
+     */
+    @SuppressLint({"ConcreteCollection", "NullableCollection"})
+    @Nullable
+    private <T> ArrayList<T> readArrayListInternal(@Nullable ClassLoader loader,
+            @Nullable Class<? extends T> clazz) {
+        int n = readInt();
+        if (n < 0) {
+            return null;
+        }
+        ArrayList<T> l = new ArrayList<>(n);
+        readListInternal(l, n, loader, clazz);
+        return l;
+    }
+
+    /**
+     * The method is replaced by {@link #readArrayInternal(ClassLoader, Class)}, however
+     * we are keeping this unused method here to allow unsupported app usages.
+     */
     private void readArrayInternal(@NonNull Object[] outVal, int N,
             @Nullable ClassLoader loader) {
         for (int i = 0; i < N; i++) {
-            Object value = readValue(loader);
-            //Log.d(TAG, "Unmarshalling value=" + value);
+            Object value = readValue(loader, /* clazz */ null);
             outVal[i] = value;
         }
     }
 
+    /**
+     * @param clazz The type of the object expected or {@code null} for performing no checks.
+     */
+    @SuppressWarnings("unchecked")
+    @Nullable
+    private <T> T[] readArrayInternal(@Nullable ClassLoader loader, @Nullable Class<T> clazz) {
+        int n = readInt();
+        if (n < 0) {
+            return null;
+        }
+        T[] outVal = (T[]) ((clazz == null) ? new Object[n] : Array.newInstance(clazz, n));
+
+        for (int i = 0; i < n; i++) {
+            T value = readValue(loader, clazz);
+            outVal[i] = value;
+        }
+        return outVal;
+    }
+
+    /**
+     * The method is replaced by {@link #readSparseArray(ClassLoader, Class)}, however
+     * we are keeping this unused method here to allow unsupported app usages.
+     */
     private void readSparseArrayInternal(@NonNull SparseArray outVal, int N,
             @Nullable ClassLoader loader) {
         while (N > 0) {
             int key = readInt();
             Object value = readValue(loader);
-            //Log.i(TAG, "Unmarshalling key=" + key + " value=" + value);
             outVal.append(key, value);
             N--;
         }
     }
 
+    /**
+     * @param clazz The type of the object expected or {@code null} for performing no checks.
+     */
+    @Nullable
+    private <T> SparseArray<T> readSparseArrayInternal(@Nullable ClassLoader loader,
+            @Nullable Class<? extends T> clazz) {
+        int n = readInt();
+        if (n < 0) {
+            return null;
+        }
+        SparseArray<T> outVal = new SparseArray<>(n);
+
+        while (n > 0) {
+            int key = readInt();
+            T value = readValue(loader, clazz);
+            outVal.append(key, value);
+            n--;
+        }
+        return outVal;
+    }
+
 
     private void readSparseBooleanArrayInternal(@NonNull SparseBooleanArray outVal, int N) {
         while (N > 0) {
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index a0f8615..eda3699 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -5207,7 +5207,7 @@
         @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
         @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
         public static @NonNull Map<String, List<ContentValues>> queryRawContactEntity(
-                @NonNull Context context, long contactId) {
+                @NonNull ContentResolver contentResolver, long contactId) {
             Uri uri = RawContactsEntity.CONTENT_URI;
             long realContactId = contactId;
 
@@ -5225,7 +5225,7 @@
                 final String selection = Data.CONTACT_ID + "=?";
                 final String[] selectionArgs = new String[] {String.valueOf(realContactId)};
 
-                entityIterator = RawContacts.newEntityIterator(context.getContentResolver().query(
+                entityIterator = RawContacts.newEntityIterator(contentResolver.query(
                             uri, null, selection, selectionArgs, null));
 
                 if (entityIterator == null) {
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 25e3a4f..8ac5c03 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -181,6 +181,22 @@
     public static final String NAMESPACE_CONNECTIVITY = "connectivity";
 
     /**
+     * Namespace for CaptivePortalLogin module.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_CAPTIVEPORTALLOGIN = "captive_portal_login";
+
+    /**
+     * Namespace for Tethering module.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String NAMESPACE_TETHERING = "tethering";
+
+    /**
      * Namespace for content capture feature used by on-device machine intelligence
      * to provide suggestions in a privacy-safe manner.
      *
diff --git a/core/java/android/security/attestationverification/OWNERS b/core/java/android/security/attestationverification/OWNERS
new file mode 100644
index 0000000..80a1f44
--- /dev/null
+++ b/core/java/android/security/attestationverification/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 1111194
+
+dlm@google.com
+dkrahn@google.com
diff --git a/core/java/com/android/internal/content/om/OverlayConfig.java b/core/java/com/android/internal/content/om/OverlayConfig.java
index 3f3c9bd..7c39118 100644
--- a/core/java/com/android/internal/content/om/OverlayConfig.java
+++ b/core/java/com/android/internal/content/om/OverlayConfig.java
@@ -25,17 +25,22 @@
 import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.apex.ApexInfo;
+import com.android.apex.XmlParser;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.om.OverlayConfigParser.OverlayPartition;
 import com.android.internal.content.om.OverlayConfigParser.ParsedConfiguration;
 import com.android.internal.content.om.OverlayScanner.ParsedOverlayInfo;
 import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.TriConsumer;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
-import java.util.function.BiConsumer;
+import java.util.List;
 import java.util.function.Supplier;
 
 /**
@@ -73,7 +78,7 @@
     public interface PackageProvider {
 
         /** Performs the given action for each package. */
-        void forEachPackage(BiConsumer<ParsingPackageRead, Boolean> p);
+        void forEachPackage(TriConsumer<ParsingPackageRead, Boolean, File> p);
     }
 
     private static final Comparator<ParsedConfiguration> sStaticOverlayComparator = (c1, c2) -> {
@@ -115,6 +120,8 @@
                             p)));
         }
 
+        ArrayMap<Integer, List<String>> activeApexesPerPartition = getActiveApexes(partitions);
+
         boolean foundConfigFile = false;
         ArrayList<ParsedOverlayInfo> packageManagerOverlayInfos = null;
 
@@ -123,7 +130,9 @@
             final OverlayPartition partition = partitions.get(i);
             final OverlayScanner scanner = (scannerFactory == null) ? null : scannerFactory.get();
             final ArrayList<ParsedConfiguration> partitionOverlays =
-                    OverlayConfigParser.getConfigurations(partition, scanner);
+                    OverlayConfigParser.getConfigurations(partition, scanner,
+                            activeApexesPerPartition.getOrDefault(partition.type,
+                                    Collections.emptyList()));
             if (partitionOverlays != null) {
                 foundConfigFile = true;
                 overlays.addAll(partitionOverlays);
@@ -145,7 +154,8 @@
                 // Filter out overlays not present in the partition.
                 partitionOverlayInfos = new ArrayList<>(packageManagerOverlayInfos);
                 for (int j = partitionOverlayInfos.size() - 1; j >= 0; j--) {
-                    if (!partition.containsFile(partitionOverlayInfos.get(j).path)) {
+                    if (!partition.containsFile(partitionOverlayInfos.get(j)
+                            .getOriginalPartitionPath())) {
                         partitionOverlayInfos.remove(j);
                     }
                 }
@@ -292,16 +302,49 @@
     private static ArrayList<ParsedOverlayInfo> getOverlayPackageInfos(
             @NonNull PackageProvider packageManager) {
         final ArrayList<ParsedOverlayInfo> overlays = new ArrayList<>();
-        packageManager.forEachPackage((ParsingPackageRead p, Boolean isSystem) -> {
+        packageManager.forEachPackage((ParsingPackageRead p, Boolean isSystem,
+                @Nullable File preInstalledApexPath) -> {
             if (p.getOverlayTarget() != null && isSystem) {
                 overlays.add(new ParsedOverlayInfo(p.getPackageName(), p.getOverlayTarget(),
                         p.getTargetSdkVersion(), p.isOverlayIsStatic(), p.getOverlayPriority(),
-                        new File(p.getBaseApkPath())));
+                        new File(p.getBaseApkPath()), preInstalledApexPath));
             }
         });
         return overlays;
     }
 
+    /** Returns a map of PartitionType to List of active APEX module names. */
+    @NonNull
+    private static ArrayMap<Integer, List<String>> getActiveApexes(
+            @NonNull List<OverlayPartition> partitions) {
+        // An Overlay in an APEX, which is an update of an APEX in a given partition,
+        // is considered as belonging to that partition.
+        ArrayMap<Integer, List<String>> result = new ArrayMap<>();
+        for (OverlayPartition partition : partitions) {
+            result.put(partition.type, new ArrayList<String>());
+        }
+        // Read from apex-info-list because ApexManager is not accessible to zygote.
+        File apexInfoList = new File("/apex/apex-info-list.xml");
+        if (apexInfoList.exists() && apexInfoList.canRead()) {
+            try (FileInputStream stream = new FileInputStream(apexInfoList)) {
+                List<ApexInfo> apexInfos = XmlParser.readApexInfoList(stream).getApexInfo();
+                for (ApexInfo info : apexInfos) {
+                    if (info.getIsActive()) {
+                        for (OverlayPartition partition : partitions) {
+                            if (partition.containsPath(info.getPreinstalledModulePath())) {
+                                result.get(partition.type).add(info.getModuleName());
+                                break;
+                            }
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                Log.w(TAG, "Error reading apex-info-list: " + e);
+            }
+        }
+        return result;
+    }
+
     /** Represents a single call to idmap create-multiple. */
     @VisibleForTesting
     public static class IdmapInvocation {
diff --git a/core/java/com/android/internal/content/om/OverlayConfigParser.java b/core/java/com/android/internal/content/om/OverlayConfigParser.java
index a86e595..d48c2e7 100644
--- a/core/java/com/android/internal/content/om/OverlayConfigParser.java
+++ b/core/java/com/android/internal/content/om/OverlayConfigParser.java
@@ -40,6 +40,7 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Responsible for parsing configurations of Runtime Resource Overlays that control mutability,
@@ -192,13 +193,19 @@
      */
     @Nullable
     static ArrayList<ParsedConfiguration> getConfigurations(
-            @NonNull OverlayPartition partition, @Nullable OverlayScanner scanner) {
-        if (partition.getOverlayFolder() == null) {
-            return null;
+            @NonNull OverlayPartition partition, @Nullable OverlayScanner scanner,
+            @NonNull List<String> activeApexes) {
+        if (scanner != null) {
+            if (partition.getOverlayFolder() != null) {
+                scanner.scanDir(partition.getOverlayFolder());
+            }
+            for (String apex : activeApexes) {
+                scanner.scanDir(new File("/apex/" + apex + "/overlay/"));
+            }
         }
 
-        if (scanner != null) {
-            scanner.scanDir(partition.getOverlayFolder());
+        if (partition.getOverlayFolder() == null) {
+            return null;
         }
 
         final File configFile = new File(partition.getOverlayFolder(), CONFIG_DEFAULT_FILENAME);
diff --git a/core/java/com/android/internal/content/om/OverlayScanner.java b/core/java/com/android/internal/content/om/OverlayScanner.java
index 6b5cb8d..138d1ce 100644
--- a/core/java/com/android/internal/content/om/OverlayScanner.java
+++ b/core/java/com/android/internal/content/om/OverlayScanner.java
@@ -47,23 +47,38 @@
         public final boolean isStatic;
         public final int priority;
         public final File path;
+        @Nullable public final File preInstalledApexPath;
 
         public ParsedOverlayInfo(String packageName, String targetPackageName,
-                int targetSdkVersion, boolean isStatic, int priority, File path) {
+                int targetSdkVersion, boolean isStatic, int priority, File path,
+                @Nullable File preInstalledApexPath) {
             this.packageName = packageName;
             this.targetPackageName = targetPackageName;
             this.targetSdkVersion = targetSdkVersion;
             this.isStatic = isStatic;
             this.priority = priority;
             this.path = path;
+            this.preInstalledApexPath = preInstalledApexPath;
         }
 
         @Override
         public String toString() {
             return getClass().getSimpleName() + String.format("{packageName=%s"
                             + ", targetPackageName=%s, targetSdkVersion=%s, isStatic=%s"
-                            + ", priority=%s, path=%s}",
-                    packageName, targetPackageName, targetSdkVersion, isStatic, priority, path);
+                            + ", priority=%s, path=%s, preInstalledApexPath=%s}",
+                    packageName, targetPackageName, targetSdkVersion, isStatic,
+                    priority, path, preInstalledApexPath);
+        }
+
+        /**
+         * Retrieves the path of the overlay in its original installation partition.
+         *
+         * An Overlay in an APEX, which is an update of an APEX in a given partition,
+         * is considered as belonging to that partition.
+         */
+        @NonNull
+        public File getOriginalPartitionPath() {
+            return preInstalledApexPath != null ? preInstalledApexPath : path;
         }
     }
 
@@ -138,6 +153,6 @@
         return apkLite.getTargetPackageName() == null ? null :
                 new ParsedOverlayInfo(apkLite.getPackageName(), apkLite.getTargetPackageName(),
                         apkLite.getTargetSdkVersion(), apkLite.isOverlayIsStatic(),
-                        apkLite.getOverlayPriority(), new File(apkLite.getPath()));
+                        apkLite.getOverlayPriority(), new File(apkLite.getPath()), null);
     }
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 8c63f38..630851d 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -12143,7 +12143,7 @@
             rxTimeMs = info.getControllerRxTimeMillis();
             txTimeMs = info.getControllerTxTimeMillis();
             energy = info.getControllerEnergyUsed();
-            if (info.getUidTraffic() != null) {
+            if (!info.getUidTraffic().isEmpty()) {
                 for (UidTraffic traffic : info.getUidTraffic()) {
                     uidRxBytes.put(traffic.getUid(), traffic.getRxBytes());
                     uidTxBytes.put(traffic.getUid(), traffic.getTxBytes());
@@ -12294,10 +12294,10 @@
         long totalTxBytes = 0;
         long totalRxBytes = 0;
 
-        final UidTraffic[] uidTraffic = info.getUidTraffic();
-        final int numUids = uidTraffic != null ? uidTraffic.length : 0;
+        final List<UidTraffic> uidTraffic = info.getUidTraffic();
+        final int numUids = uidTraffic.size();
         for (int i = 0; i < numUids; i++) {
-            final UidTraffic traffic = uidTraffic[i];
+            final UidTraffic traffic = uidTraffic.get(i);
             final long rxBytes = traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(
                     traffic.getUid());
             final long txBytes = traffic.getTxBytes() - mLastBluetoothActivityInfo.uidTxBytes.get(
@@ -12320,7 +12320,7 @@
         if ((totalTxBytes != 0 || totalRxBytes != 0) && (leftOverRxTimeMs != 0
                 || leftOverTxTimeMs != 0)) {
             for (int i = 0; i < numUids; i++) {
-                final UidTraffic traffic = uidTraffic[i];
+                final UidTraffic traffic = uidTraffic.get(i);
                 final int uid = traffic.getUid();
                 final long rxBytes =
                         traffic.getRxBytes() - mLastBluetoothActivityInfo.uidRxBytes.get(uid);
diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java
index d347f2e..8b0411d 100644
--- a/core/java/com/android/internal/os/ClassLoaderFactory.java
+++ b/core/java/com/android/internal/os/ClassLoaderFactory.java
@@ -80,15 +80,20 @@
      */
     public static ClassLoader createClassLoader(String dexPath,
             String librarySearchPath, ClassLoader parent, String classloaderName,
-            List<ClassLoader> sharedLibraries) {
+            List<ClassLoader> sharedLibraries, List<ClassLoader> sharedLibrariesLoadedAfter) {
         ClassLoader[] arrayOfSharedLibraries = (sharedLibraries == null)
                 ? null
                 : sharedLibraries.toArray(new ClassLoader[sharedLibraries.size()]);
+        ClassLoader[] arrayOfSharedLibrariesLoadedAfterApp = (sharedLibrariesLoadedAfter == null)
+                ? null
+                : sharedLibrariesLoadedAfter.toArray(
+                        new ClassLoader[sharedLibrariesLoadedAfter.size()]);
         if (isPathClassLoaderName(classloaderName)) {
-            return new PathClassLoader(dexPath, librarySearchPath, parent, arrayOfSharedLibraries);
+            return new PathClassLoader(dexPath, librarySearchPath, parent, arrayOfSharedLibraries,
+                    arrayOfSharedLibrariesLoadedAfterApp);
         } else if (isDelegateLastClassLoaderName(classloaderName)) {
             return new DelegateLastClassLoader(dexPath, librarySearchPath, parent,
-                    arrayOfSharedLibraries);
+                    arrayOfSharedLibraries, arrayOfSharedLibrariesLoadedAfterApp);
         }
 
         throw new AssertionError("Invalid classLoaderName: " + classloaderName);
@@ -102,20 +107,20 @@
             String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
             int targetSdkVersion, boolean isNamespaceShared, String classLoaderName) {
         return createClassLoader(dexPath, librarySearchPath, libraryPermittedPath,
-            parent, targetSdkVersion, isNamespaceShared, classLoaderName, null, null);
+            parent, targetSdkVersion, isNamespaceShared, classLoaderName, null, null, null);
     }
 
-
     /**
      * Create a ClassLoader and initialize a linker-namespace for it.
      */
     public static ClassLoader createClassLoader(String dexPath,
             String librarySearchPath, String libraryPermittedPath, ClassLoader parent,
             int targetSdkVersion, boolean isNamespaceShared, String classLoaderName,
-            List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries) {
+            List<ClassLoader> sharedLibraries, List<String> nativeSharedLibraries,
+            List<ClassLoader> sharedLibrariesAfter) {
 
         final ClassLoader classLoader = createClassLoader(dexPath, librarySearchPath, parent,
-                classLoaderName, sharedLibraries);
+                classLoaderName, sharedLibraries, sharedLibrariesAfter);
 
         String sonameList = "";
         if (nativeSharedLibraries != null) {
diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java
index 5ec882c..475caa5 100644
--- a/core/java/com/android/internal/os/SomeArgs.java
+++ b/core/java/com/android/internal/os/SomeArgs.java
@@ -63,6 +63,8 @@
     public int argi4;
     public int argi5;
     public int argi6;
+    public long argl1;
+    public long argl2;
 
     private SomeArgs() {
         /* do nothing - reduce visibility */
@@ -129,5 +131,7 @@
         argi4 = 0;
         argi5 = 0;
         argi6 = 0;
+        argl1 = 0;
+        argl2 = 0;
     }
 }
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 0d33807..0d530f6 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -604,6 +604,25 @@
     return thisParcel->compareData(*otherParcel);
 }
 
+static jboolean android_os_Parcel_compareDataInRange(JNIEnv* env, jclass clazz, jlong thisNativePtr,
+                                                     jint thisOffset, jlong otherNativePtr,
+                                                     jint otherOffset, jint length) {
+    Parcel* thisParcel = reinterpret_cast<Parcel*>(thisNativePtr);
+    LOG_ALWAYS_FATAL_IF(thisParcel == nullptr, "Should not be null");
+
+    Parcel* otherParcel = reinterpret_cast<Parcel*>(otherNativePtr);
+    LOG_ALWAYS_FATAL_IF(otherParcel == nullptr, "Should not be null");
+
+    int result;
+    status_t err =
+            thisParcel->compareDataInRange(thisOffset, *otherParcel, otherOffset, length, &result);
+    if (err != NO_ERROR) {
+        signalExceptionForError(env, clazz, err);
+        return JNI_FALSE;
+    }
+    return (result == 0) ? JNI_TRUE : JNI_FALSE;
+}
+
 static void android_os_Parcel_appendFrom(JNIEnv* env, jclass clazz, jlong thisNativePtr,
                                           jlong otherNativePtr, jint offset, jint length)
 {
@@ -641,7 +660,7 @@
     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
     if (parcel != NULL) {
         bool result;
-        status_t err = parcel->hasFileDescriptorsInRange(offset, length, result);
+        status_t err = parcel->hasFileDescriptorsInRange(offset, length, &result);
         if (err != NO_ERROR) {
             signalExceptionForError(env, clazz, err);
             return JNI_FALSE;
@@ -841,6 +860,7 @@
     {"nativeMarshall",            "(J)[B", (void*)android_os_Parcel_marshall},
     {"nativeUnmarshall",          "(J[BII)V", (void*)android_os_Parcel_unmarshall},
     {"nativeCompareData",         "(JJ)I", (void*)android_os_Parcel_compareData},
+    {"nativeCompareDataInRange",  "(JIJII)Z", (void*)android_os_Parcel_compareDataInRange},
     {"nativeAppendFrom",          "(JJII)V", (void*)android_os_Parcel_appendFrom},
     // @CriticalNative
     {"nativeHasFileDescriptors",  "(J)Z", (void*)android_os_Parcel_hasFileDescriptors},
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 793b4eb..61b91dd 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -959,8 +959,7 @@
     return IPCThreadState::self()->getCallingUid();
 }
 
-static jboolean android_os_Binder_isHandlingTransaction()
-{
+static jboolean android_os_Binder_isDirectlyHandlingTransaction() {
     return getCurrentServingCall() == BinderCallType::BINDER;
 }
 
@@ -1056,6 +1055,7 @@
 
 // ----------------------------------------------------------------------------
 
+// clang-format off
 static const JNINativeMethod gBinderMethods[] = {
      /* name, signature, funcPtr */
     // @CriticalNative
@@ -1063,7 +1063,7 @@
     // @CriticalNative
     { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
     // @CriticalNative
-    { "isHandlingTransaction", "()Z", (void*)android_os_Binder_isHandlingTransaction },
+    { "isDirectlyHandlingTransaction", "()Z", (void*)android_os_Binder_isDirectlyHandlingTransaction },
     // @CriticalNative
     { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
     // @CriticalNative
@@ -1088,6 +1088,7 @@
     { "getExtension", "()Landroid/os/IBinder;", (void*)android_os_Binder_getExtension },
     { "setExtension", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension },
 };
+// clang-format on
 
 const char* const kBinderPathName = "android/os/Binder";
 
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index 6f5cc53..40f6e4f 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -138,6 +138,14 @@
         return true;
     }
 
+    // Allow Runtime Resource Overlays inside APEXes.
+    static const char* kOverlayPathSuffix = "/overlay";
+    if (android::base::StartsWith(path, kApexPrefix) &&
+        android::base::EndsWith(android::base::Dirname(path), kOverlayPathSuffix) &&
+        android::base::EndsWith(path, kApkSuffix) && path.find("/../") == std::string::npos) {
+        return true;
+    }
+
     static const char* kOverlayIdmapPrefix = "/data/resource-cache/";
     static const char* kOverlayIdmapSuffix = ".apk@idmap";
     if (android::base::StartsWith(path, kOverlayIdmapPrefix) &&
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index bd89578..1418dbe 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1976,6 +1976,14 @@
         android:label="@string/permlab_uwb_ranging"
         android:protectionLevel="dangerous" />
 
+    <!-- Required to be able to advertise and connect to nearby devices via Wi-Fi.
+         <p>Protection level: dangerous -->
+    <permission android:name="android.permission.NEARBY_WIFI_DEVICES"
+                android:permissionGroup="android.permission-group.UNDEFINED"
+                android:description="@string/permdesc_nearby_wifi_devices"
+                android:label="@string/permlab_nearby_wifi_devices"
+                android:protectionLevel="dangerous" />
+
     <!-- @SystemApi @TestApi Allows an application to suspend other apps, which will prevent the
          user from using them until they are unsuspended.
          @hide
diff --git a/core/res/OWNERS b/core/res/OWNERS
index 684202b..165dcad 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -28,3 +28,6 @@
 
 # Multiuser
 per-file res/xml/config_user_types.xml = file:/MULTIUSER_OWNERS
+
+# Car
+per-file res/values/dimens_car.xml = file:/platform/packages/services/Car:/OWNERS
\ No newline at end of file
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index aa05b13..7db2fe9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -5047,6 +5047,11 @@
          to 0, the seconds hand will be disabled. -->
     <integer name="config_defaultAnalogClockSecondsHandFps">1</integer>
 
+    <!-- List of shared library packages that should be loaded by the classloader after the
+         code and resources provided by applications. This value will be set by the manufacturer  -->
+    <string-array name="config_sharedLibrariesLoadedAfterApp" translatable="false">
+    </string-array>
+
     <!-- the number of the max cached processes in the system. -->
     <integer name="config_customizedMaxCachedProcesses">32</integer>
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index a99a220..a350d14 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1488,6 +1488,11 @@
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=120]-->
     <string name="permdesc_uwb_ranging">Allow the app to determine relative position between nearby Ultra-Wideband devices</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50]-->
+    <string name="permlab_nearby_wifi_devices">interact with nearby Wi\u2011Fi devices</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=120]-->
+    <string name="permdesc_nearby_wifi_devices">Allows the app to advertise, connect, and determine the relative position of nearby Wi\u2011Fi devices</string>
+
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_preferredPaymentInfo">Preferred NFC Payment Service Information</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 092be40..1c44526 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4425,5 +4425,9 @@
 
   <java-symbol type="bool" name="config_volumeShowRemoteSessions" />
 
+  <!-- List of shared library packages that should be loaded by the classloader after the
+       code and resources provided by applications. -->
+  <java-symbol type="array" name="config_sharedLibrariesLoadedAfterApp" />
+
   <java-symbol type="integer" name="config_customizedMaxCachedProcesses" />
 </resources>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index f1c66c5..4c20ae1 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -105,6 +105,9 @@
          http://www.tja.ee/public/documents/Elektrooniline_side/Oigusaktid/ENG/Estonian_Numbering_Plan_annex_06_09_2010.mht -->
     <shortcode country="ee" pattern="1\\d{2,4}" premium="90\\d{5}|15330|1701[0-3]" free="116\\d{3}|95034" />
 
+    <!-- Egypt: 4 digits, known codes listed -->
+    <shortcode country="eg" pattern="\\d{4}" free="1499" />
+
     <!-- Spain: 5-6 digits: 25xxx, 27xxx, 280xx, 35xxx, 37xxx, 795xxx, 797xxx, 995xxx, 997xxx, plus EU.
          http://www.legallink.es/?q=en/content/which-current-regulatory-status-premium-rate-services-spain -->
     <shortcode country="es" premium="[23][57]\\d{3}|280\\d{2}|[79]9[57]\\d{3}" free="116\\d{3}|22791|222145|22189" />
@@ -196,7 +199,7 @@
     <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223|1662" />
 
     <!-- Nigeria -->
-    <shortcode country="ng" pattern="\\d{1,5}" free="2441|55019" />
+    <shortcode country="ng" pattern="\\d{1,5}" free="2441|55020" />
 
     <!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
     <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" free="2171" />
diff --git a/core/tests/bluetoothtests/Android.bp b/core/tests/bluetoothtests/Android.bp
index a2e4dff..68416dd 100644
--- a/core/tests/bluetoothtests/Android.bp
+++ b/core/tests/bluetoothtests/Android.bp
@@ -15,7 +15,10 @@
         "android.test.runner",
         "android.test.base",
     ],
-    static_libs: ["junit"],
+    static_libs: [
+        "junit",
+        "modules-utils-bytesmatcher",
+    ],
     platform_apis: true,
     certificate: "platform",
 }
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java b/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java
index c287ea9..4e817d4 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/le/ScanRecordTest.java
@@ -16,11 +16,11 @@
 
 package android.bluetooth.le;
 
-import android.os.BytesMatcher;
 import android.os.ParcelUuid;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.util.HexDump;
+import com.android.modules.utils.BytesMatcher;
 
 import junit.framework.TestCase;
 
diff --git a/core/tests/coretests/src/android/net/sntp/Duration64Test.java b/core/tests/coretests/src/android/net/sntp/Duration64Test.java
index 933800f..60b69f6 100644
--- a/core/tests/coretests/src/android/net/sntp/Duration64Test.java
+++ b/core/tests/coretests/src/android/net/sntp/Duration64Test.java
@@ -21,13 +21,17 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.time.Duration;
 import java.time.Instant;
 import java.time.LocalDateTime;
 import java.time.ZoneOffset;
 
+@RunWith(AndroidJUnit4.class)
 public class Duration64Test {
 
     @Test
diff --git a/core/tests/coretests/src/android/net/sntp/Timestamp64Test.java b/core/tests/coretests/src/android/net/sntp/Timestamp64Test.java
index c923812..1b1c500 100644
--- a/core/tests/coretests/src/android/net/sntp/Timestamp64Test.java
+++ b/core/tests/coretests/src/android/net/sntp/Timestamp64Test.java
@@ -21,13 +21,17 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import androidx.test.runner.AndroidJUnit4;
+
 import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.time.Instant;
 import java.util.HashSet;
 import java.util.Random;
 import java.util.Set;
 
+@RunWith(AndroidJUnit4.class)
 public class Timestamp64Test {
 
     @Test
@@ -191,6 +195,7 @@
         }
     }
 
+    @SuppressWarnings("JavaInstantGetSecondsGetNano")
     private static void assertInstantCreationOnlyFractionExact(
             int fractionBits, long expectedNanos) {
         Timestamp64 timestamp64 = Timestamp64.fromComponents(0, fractionBits);
@@ -201,6 +206,7 @@
         assertEquals(expectedNanos, instant.getNano());
     }
 
+    @SuppressWarnings("JavaInstantGetSecondsGetNano")
     private static void assertNanosWithTruncationAllowed(long expectedNanos, Instant instant) {
         // Allow for < 1ns difference due to truncation.
         long actualNanos = instant.getNano();
@@ -208,6 +214,7 @@
                 actualNanos == expectedNanos || actualNanos == expectedNanos - 1);
     }
 
+    @SuppressWarnings("JavaInstantGetSecondsGetNano")
     @Test
     public void testMillisRandomizationConstant() {
         // Mathematically, we can say that to represent 1000 different values, we need 10 binary
diff --git a/core/tests/coretests/src/android/os/BundleTest.java b/core/tests/coretests/src/android/os/BundleTest.java
index ddd0070..09f4840 100644
--- a/core/tests/coretests/src/android/os/BundleTest.java
+++ b/core/tests/coretests/src/android/os/BundleTest.java
@@ -273,16 +273,21 @@
         Parcelable p1 = new CustomParcelable(13, "Tiramisu");
         Parcelable p2 = new CustomParcelable(13, "Tiramisu");
         Bundle a = new Bundle();
-        a.putParcelable("key", p1);
+        a.putParcelable("key1", p1);
         a.readFromParcel(getParcelledBundle(a));
         a.setClassLoader(getClass().getClassLoader());
         Bundle b = new Bundle();
-        b.putParcelable("key", p2);
+        // Adding extra element so that the position of the elements of interest in their respective
+        // source parcels are different so we can cover that case of Parcel.compareData(). We'll
+        // remove the element later so the map is equal.
+        b.putString("key0", "string");
+        b.putParcelable("key1", p2);
         b.readFromParcel(getParcelledBundle(b));
         b.setClassLoader(getClass().getClassLoader());
-        // 2 lazy values with identical parcels inside
         a.isEmpty();
         b.isEmpty();
+        b.remove("key0");
+        // 2 lazy values with identical parcels inside
 
         assertTrue(Bundle.kindofEquals(a, b));
     }
diff --git a/core/tests/coretests/src/android/os/BytesMatcherTest.java b/core/tests/coretests/src/android/os/BytesMatcherTest.java
deleted file mode 100644
index b28e309..0000000
--- a/core/tests/coretests/src/android/os/BytesMatcherTest.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2021 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.os;
-
-import static com.android.internal.util.HexDump.hexStringToByteArray;
-
-import android.bluetooth.BluetoothUuid;
-import android.net.MacAddress;
-
-import androidx.test.filters.SmallTest;
-
-import junit.framework.TestCase;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-@SmallTest
-public class BytesMatcherTest extends TestCase {
-    @Test
-    public void testEmpty() throws Exception {
-        BytesMatcher matcher = BytesMatcher.decode("");
-        assertFalse(matcher.test(hexStringToByteArray("cafe")));
-        assertFalse(matcher.test(hexStringToByteArray("")));
-    }
-
-    @Test
-    public void testExact() throws Exception {
-        BytesMatcher matcher = BytesMatcher.decode("+cafe");
-        assertTrue(matcher.test(hexStringToByteArray("cafe")));
-        assertFalse(matcher.test(hexStringToByteArray("beef")));
-        assertFalse(matcher.test(hexStringToByteArray("ca")));
-        assertFalse(matcher.test(hexStringToByteArray("cafe00")));
-    }
-
-    @Test
-    public void testMask() throws Exception {
-        BytesMatcher matcher = BytesMatcher.decode("+cafe/ff00");
-        assertTrue(matcher.test(hexStringToByteArray("cafe")));
-        assertTrue(matcher.test(hexStringToByteArray("ca88")));
-        assertFalse(matcher.test(hexStringToByteArray("beef")));
-        assertFalse(matcher.test(hexStringToByteArray("ca")));
-        assertFalse(matcher.test(hexStringToByteArray("cafe00")));
-    }
-
-    @Test
-    public void testPrefix() throws Exception {
-        BytesMatcher matcher = BytesMatcher.decode("⊆cafe,⊆beef/ff00");
-        assertTrue(matcher.test(hexStringToByteArray("cafe")));
-        assertFalse(matcher.test(hexStringToByteArray("caff")));
-        assertTrue(matcher.test(hexStringToByteArray("cafecafe")));
-        assertFalse(matcher.test(hexStringToByteArray("ca")));
-        assertTrue(matcher.test(hexStringToByteArray("beef")));
-        assertTrue(matcher.test(hexStringToByteArray("beff")));
-        assertTrue(matcher.test(hexStringToByteArray("beffbeff")));
-        assertFalse(matcher.test(hexStringToByteArray("be")));
-    }
-
-    @Test
-    public void testMacAddress() throws Exception {
-        BytesMatcher matcher = BytesMatcher.decode("+cafe00112233/ffffff000000");
-        assertTrue(matcher.testMacAddress(
-                MacAddress.fromString("ca:fe:00:00:00:00")));
-        assertFalse(matcher.testMacAddress(
-                MacAddress.fromString("f0:0d:00:00:00:00")));
-    }
-
-    @Test
-    public void testBluetoothUuid() throws Exception {
-        BytesMatcher matcher = BytesMatcher.decode("+cafe/ff00");
-        assertTrue(matcher.testBluetoothUuid(
-                BluetoothUuid.parseUuidFrom(hexStringToByteArray("cafe"))));
-        assertFalse(matcher.testBluetoothUuid(
-                BluetoothUuid.parseUuidFrom(hexStringToByteArray("beef"))));
-    }
-
-    /**
-     * Verify that single matcher can be configured to match Bluetooth UUIDs of
-     * varying lengths.
-     */
-    @Test
-    public void testBluetoothUuid_Mixed() throws Exception {
-        BytesMatcher matcher = BytesMatcher.decode("+aaaa/ff00,+bbbbbbbb/ffff0000");
-        assertTrue(matcher.testBluetoothUuid(
-                BluetoothUuid.parseUuidFrom(hexStringToByteArray("aaaa"))));
-        assertFalse(matcher.testBluetoothUuid(
-                BluetoothUuid.parseUuidFrom(hexStringToByteArray("bbbb"))));
-        assertTrue(matcher.testBluetoothUuid(
-                BluetoothUuid.parseUuidFrom(hexStringToByteArray("bbbbbbbb"))));
-        assertFalse(matcher.testBluetoothUuid(
-                BluetoothUuid.parseUuidFrom(hexStringToByteArray("aaaaaaaa"))));
-    }
-
-    @Test
-    public void testSerialize_Empty() throws Exception {
-        BytesMatcher matcher = new BytesMatcher();
-        matcher = BytesMatcher.decode(BytesMatcher.encode(matcher));
-
-        // Also very empty and null values
-        BytesMatcher.decode("");
-        BytesMatcher.decode(null);
-    }
-
-    @Test
-    public void testSerialize_Exact() throws Exception {
-        BytesMatcher matcher = new BytesMatcher();
-        matcher.addExactRejectRule(hexStringToByteArray("cafe00112233"),
-                hexStringToByteArray("ffffff000000"));
-        matcher.addExactRejectRule(hexStringToByteArray("beef00112233"),
-                null);
-        matcher.addExactAcceptRule(hexStringToByteArray("000000000000"),
-                hexStringToByteArray("000000000000"));
-
-        assertFalse(matcher.test(hexStringToByteArray("cafe00ffffff")));
-        assertFalse(matcher.test(hexStringToByteArray("beef00112233")));
-        assertTrue(matcher.test(hexStringToByteArray("beef00ffffff")));
-
-        // Bounce through serialization pass and confirm it still works
-        matcher = BytesMatcher.decode(BytesMatcher.encode(matcher));
-
-        assertFalse(matcher.test(hexStringToByteArray("cafe00ffffff")));
-        assertFalse(matcher.test(hexStringToByteArray("beef00112233")));
-        assertTrue(matcher.test(hexStringToByteArray("beef00ffffff")));
-    }
-
-    @Test
-    public void testSerialize_Prefix() throws Exception {
-        BytesMatcher matcher = new BytesMatcher();
-        matcher.addExactRejectRule(hexStringToByteArray("aa"), null);
-        matcher.addExactAcceptRule(hexStringToByteArray("bb"), null);
-        matcher.addPrefixAcceptRule(hexStringToByteArray("aa"), null);
-        matcher.addPrefixRejectRule(hexStringToByteArray("bb"), null);
-
-        assertFalse(matcher.test(hexStringToByteArray("aa")));
-        assertTrue(matcher.test(hexStringToByteArray("bb")));
-        assertTrue(matcher.test(hexStringToByteArray("aaaa")));
-        assertFalse(matcher.test(hexStringToByteArray("bbbb")));
-
-        // Bounce through serialization pass and confirm it still works
-        matcher = BytesMatcher.decode(BytesMatcher.encode(matcher));
-
-        assertFalse(matcher.test(hexStringToByteArray("aa")));
-        assertTrue(matcher.test(hexStringToByteArray("bb")));
-        assertTrue(matcher.test(hexStringToByteArray("aaaa")));
-        assertFalse(matcher.test(hexStringToByteArray("bbbb")));
-    }
-
-    @Test
-    public void testOrdering_RejectFirst() throws Exception {
-        BytesMatcher matcher = BytesMatcher.decode("-ff/0f,+ff/f0");
-        assertFalse(matcher.test(hexStringToByteArray("ff")));
-        assertTrue(matcher.test(hexStringToByteArray("f0")));
-        assertFalse(matcher.test(hexStringToByteArray("0f")));
-    }
-
-    @Test
-    public void testOrdering_AcceptFirst() throws Exception {
-        BytesMatcher matcher = BytesMatcher.decode("+ff/f0,-ff/0f");
-        assertTrue(matcher.test(hexStringToByteArray("ff")));
-        assertTrue(matcher.test(hexStringToByteArray("f0")));
-        assertFalse(matcher.test(hexStringToByteArray("0f")));
-    }
-}
diff --git a/core/tests/coretests/src/android/os/ParcelTest.java b/core/tests/coretests/src/android/os/ParcelTest.java
index dcb3e2f..fdd278b 100644
--- a/core/tests/coretests/src/android/os/ParcelTest.java
+++ b/core/tests/coretests/src/android/os/ParcelTest.java
@@ -17,6 +17,9 @@
 package android.os;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
 
 import android.platform.test.annotations.Presubmit;
 
@@ -110,4 +113,130 @@
             assertEquals(string, p.readString16());
         }
     }
+
+    @Test
+    public void testCompareDataInRange_whenSameData() {
+        Parcel pA = Parcel.obtain();
+        int iA = pA.dataPosition();
+        pA.writeInt(13);
+        pA.writeString("Tiramisu");
+        int length = pA.dataPosition() - iA;
+        Parcel pB = Parcel.obtain();
+        pB.writeString("Prefix");
+        int iB = pB.dataPosition();
+        pB.writeInt(13);
+        pB.writeString("Tiramisu");
+
+        assertTrue(Parcel.compareData(pA, iA, pB, iB, length));
+    }
+
+    @Test
+    public void testCompareDataInRange_whenSameDataWithBinder() {
+        Binder binder = new Binder();
+        Parcel pA = Parcel.obtain();
+        int iA = pA.dataPosition();
+        pA.writeInt(13);
+        pA.writeStrongBinder(binder);
+        pA.writeString("Tiramisu");
+        int length = pA.dataPosition() - iA;
+        Parcel pB = Parcel.obtain();
+        pB.writeString("Prefix");
+        int iB = pB.dataPosition();
+        pB.writeInt(13);
+        pB.writeStrongBinder(binder);
+        pB.writeString("Tiramisu");
+
+        assertTrue(Parcel.compareData(pA, iA, pB, iB, length));
+    }
+
+    @Test
+    public void testCompareDataInRange_whenDifferentData() {
+        Parcel pA = Parcel.obtain();
+        int iA = pA.dataPosition();
+        pA.writeInt(13);
+        pA.writeString("Tiramisu");
+        int length = pA.dataPosition() - iA;
+        Parcel pB = Parcel.obtain();
+        int iB = pB.dataPosition();
+        pB.writeString("Prefix");
+        pB.writeInt(13);
+        pB.writeString("Tiramisu");
+
+        assertFalse(Parcel.compareData(pA, iA, pB, iB, length));
+    }
+
+    @Test
+    public void testCompareDataInRange_whenLimitOutOfBounds_throws() {
+        Parcel pA = Parcel.obtain();
+        int iA = pA.dataPosition();
+        pA.writeInt(12);
+        pA.writeString("Tiramisu");
+        int length = pA.dataPosition() - iA;
+        Parcel pB = Parcel.obtain();
+        pB.writeString("Prefix");
+        int iB = pB.dataPosition();
+        pB.writeInt(13);
+        pB.writeString("Tiramisu");
+        pB.writeInt(-1);
+
+        assertThrows(IllegalArgumentException.class,
+                () -> Parcel.compareData(pA, iA + length, pB, iB, 1));
+        assertThrows(IllegalArgumentException.class,
+                () -> Parcel.compareData(pA, iA, pB, pB.dataSize(), 1));
+        assertThrows(IllegalArgumentException.class,
+                () -> Parcel.compareData(pA, iA, pB, iB, length + 1));
+        assertThrows(IllegalArgumentException.class,
+                () -> Parcel.compareData(pA, iA + length + 1, pB, iB, 0));
+        assertThrows(IllegalArgumentException.class,
+                () -> Parcel.compareData(pA, iA, pB, iB + pB.dataSize() + 1, 0));
+    }
+
+    @Test
+    public void testCompareDataInRange_whenLengthZero() {
+        Parcel pA = Parcel.obtain();
+        int iA = pA.dataPosition();
+        pA.writeInt(12);
+        pA.writeString("Tiramisu");
+        int length = pA.dataPosition() - iA;
+        Parcel pB = Parcel.obtain();
+        pB.writeString("Prefix");
+        int iB = pB.dataPosition();
+        pB.writeInt(13);
+        pB.writeString("Tiramisu");
+
+        assertTrue(Parcel.compareData(pA, 0, pB, iB, 0));
+        assertTrue(Parcel.compareData(pA, iA + length, pB, iB, 0));
+        assertTrue(Parcel.compareData(pA, iA, pB, pB.dataSize(), 0));
+    }
+
+    @Test
+    public void testCompareDataInRange_whenNegativeLength_throws() {
+        Parcel pA = Parcel.obtain();
+        int iA = pA.dataPosition();
+        pA.writeInt(12);
+        pA.writeString("Tiramisu");
+        Parcel pB = Parcel.obtain();
+        pB.writeString("Prefix");
+        int iB = pB.dataPosition();
+        pB.writeInt(13);
+        pB.writeString("Tiramisu");
+
+        assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, iA, pB, iB, -1));
+    }
+
+    @Test
+    public void testCompareDataInRange_whenNegativeOffset_throws() {
+        Parcel pA = Parcel.obtain();
+        int iA = pA.dataPosition();
+        pA.writeInt(12);
+        pA.writeString("Tiramisu");
+        Parcel pB = Parcel.obtain();
+        pB.writeString("Prefix");
+        int iB = pB.dataPosition();
+        pB.writeInt(13);
+        pB.writeString("Tiramisu");
+
+        assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, -1, pB, iB, 0));
+        assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, 0, pB, -1, 0));
+    }
 }
diff --git a/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigIterationRule.java b/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigIterationRule.java
index c50c818..e2c40d8 100644
--- a/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigIterationRule.java
+++ b/core/tests/coretests/src/com/android/internal/content/res/OverlayConfigIterationRule.java
@@ -28,6 +28,7 @@
 import com.android.internal.content.om.OverlayConfig.PackageProvider;
 import com.android.internal.content.om.OverlayScanner;
 import com.android.internal.content.om.OverlayScanner.ParsedOverlayInfo;
+import com.android.internal.util.function.TriConsumer;
 
 import org.junit.Assert;
 import org.junit.rules.TestRule;
@@ -39,7 +40,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.Map;
-import java.util.function.BiConsumer;
 import java.util.function.Supplier;
 
 /**
@@ -73,7 +73,7 @@
             final File canonicalPath = new File(path.getCanonicalPath());
             mOverlayStubResults.put(canonicalPath, new ParsedOverlayInfo(
                     packageName, targetPackage, targetSdkVersion, isStatic, priority,
-                    canonicalPath));
+                    canonicalPath, null));
         } catch (IOException e) {
             Assert.fail("Failed to add overlay " + e);
         }
@@ -135,8 +135,8 @@
                 mIteration = Iteration.SYSTEM_SERVER;
                 doAnswer((InvocationOnMock invocation) -> {
                     final Object[] args = invocation.getArguments();
-                    final BiConsumer<ParsingPackageRead, Boolean> f =
-                            (BiConsumer<ParsingPackageRead, Boolean>) args[0];
+                    final TriConsumer<ParsingPackageRead, Boolean, File> f =
+                            (TriConsumer<ParsingPackageRead, Boolean, File>) args[0];
                     for (Map.Entry<File, ParsedOverlayInfo> overlay :
                             mOverlayStubResults.entrySet()) {
                         final ParsingPackageRead a = Mockito.mock(ParsingPackageRead.class);
@@ -147,7 +147,8 @@
                         when(a.isOverlayIsStatic()).thenReturn(info.isStatic);
                         when(a.getOverlayPriority()).thenReturn(info.priority);
                         when(a.getBaseApkPath()).thenReturn(info.path.getPath());
-                        f.accept(a, !info.path.getPath().contains("data/overlay"));
+                        f.accept(a, !info.path.getPath().contains("data/overlay"),
+                                /*preInstalledApexPath=*/null);
                     }
                     return null;
                 }).when(mPkgProvider).forEachPackage(any());
diff --git a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
index 5c84794..d361da9 100644
--- a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
@@ -33,6 +33,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.ArrayList;
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class BluetoothPowerCalculatorTest {
@@ -105,10 +107,10 @@
         final BluetoothActivityEnergyInfo info = new BluetoothActivityEnergyInfo(1000,
                 BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_ACTIVE, 7000, 5000, 0,
                 reportedEnergyUc);
-        info.setUidTraffic(new UidTraffic[]{
-                new UidTraffic(Process.BLUETOOTH_UID, 1000, 2000),
-                new UidTraffic(APP_UID, 3000, 4000)
-        });
+        info.setUidTraffic(new ArrayList<UidTraffic>(){{
+                add(new UidTraffic(Process.BLUETOOTH_UID, 1000, 2000));
+                add(new UidTraffic(APP_UID, 3000, 4000));
+            }});
         mStatsRule.getBatteryStats().updateBluetoothStateLocked(info,
                 consumedEnergyUc, 1000, 1000);
     }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index c068963..cf7039b 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3255,6 +3255,54 @@
     }
 
     /**
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK)
+    public void setHfpEnabled(boolean enable) {
+        AudioSystem.setParameters("hfp_enable=" + enable);
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK)
+    public void setHfpVolume(int volume) {
+        AudioSystem.setParameters("hfp_volume=" + volume);
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK)
+    public void setHfpSamplingRate(int rate) {
+        AudioSystem.setParameters("hfp_set_sampling_rate=" + rate);
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK)
+    public void setBluetoothHeadsetProperties(@NonNull String name, boolean hasNrecEnabled,
+            boolean hasWbsEnabled) {
+        AudioSystem.setParameters("bt_headset_name=" + name
+                + ";bt_headset_nrec=" + (hasNrecEnabled ? "on" : "off")
+                + ";bt_wbs=" + (hasWbsEnabled ? "on" : "off"));
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @RequiresPermission(android.Manifest.permission.BLUETOOTH_STACK)
+    public void setA2dpSuspended(boolean enable) {
+        AudioSystem.setParameters("A2dpSuspended=" + enable);
+    }
+
+    /**
      * Gets a variable number of parameter values from audio hardware.
      *
      * @param keys list of parameters
@@ -5203,21 +5251,6 @@
         }
     }
 
-    /**
-     * @hide
-     * Notifies AudioService that it is connected to an A2DP device that supports absolute volume,
-     * so that AudioService can send volume change events to the A2DP device, rather than handling
-     * them.
-     */
-    public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
-        final IAudioService service = getService();
-        try {
-            service.avrcpSupportsAbsoluteVolume(address, support);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
      /**
       * {@hide}
       */
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 7191280..dd44fdf 100755
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -171,8 +171,6 @@
 
     int getEncodedSurroundMode(int targetSdkVersion);
 
-    oneway void avrcpSupportsAbsoluteVolume(String address, boolean support);
-
     void setSpeakerphoneOn(IBinder cb, boolean on);
 
     boolean isSpeakerphoneOn();
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 49477b9..374cc75 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -182,10 +182,15 @@
         public String mName;
         public int mValue;
         public boolean mDefault;
+        public boolean mInternal;
         public Feature(String name, int value, boolean def) {
+            this(name, value, def, false /* internal */);
+        }
+        public Feature(String name, int value, boolean def, boolean internal) {
             mName = name;
             mValue = value;
             mDefault = def;
+            mInternal = internal;
         }
     }
 
@@ -579,6 +584,11 @@
         public static final String FEATURE_LowLatency = "low-latency";
 
         /**
+         * Do not include in REGULAR_CODECS list in MediaCodecList.
+         */
+        private static final String FEATURE_SpecialCodec = "special-codec";
+
+        /**
          * <b>video encoder only</b>: codec supports quantization parameter bounds.
          * @see MediaFormat#KEY_VIDEO_QP_MAX
          * @see MediaFormat#KEY_VIDEO_QP_MIN
@@ -616,6 +626,8 @@
             new Feature(FEATURE_MultipleFrames,   (1 << 5), false),
             new Feature(FEATURE_DynamicTimestamp, (1 << 6), false),
             new Feature(FEATURE_LowLatency,       (1 << 7), true),
+            // feature to exclude codec from REGULAR codec list
+            new Feature(FEATURE_SpecialCodec,     (1 << 30), false, true),
         };
 
         private static final Feature[] encoderFeatures = {
@@ -623,6 +635,8 @@
             new Feature(FEATURE_MultipleFrames, (1 << 1), false),
             new Feature(FEATURE_DynamicTimestamp, (1 << 2), false),
             new Feature(FEATURE_QpBounds, (1 << 3), false),
+            // feature to exclude codec from REGULAR codec list
+            new Feature(FEATURE_SpecialCodec,     (1 << 30), false, true),
         };
 
         /** @hide */
@@ -630,7 +644,9 @@
             Feature[] features = getValidFeatures();
             String[] res = new String[features.length];
             for (int i = 0; i < res.length; i++) {
-                res[i] = features[i].mName;
+                if (!features[i].mInternal) {
+                    res[i] = features[i].mName;
+                }
             }
             return res;
         }
@@ -778,6 +794,10 @@
 
             // check feature support
             for (Feature feat: getValidFeatures()) {
+                if (feat.mInternal) {
+                    continue;
+                }
+
                 Integer yesNo = (Integer)map.get(MediaFormat.KEY_FEATURE_ + feat.mName);
                 if (yesNo == null) {
                     continue;
@@ -1091,7 +1111,9 @@
                     mFlagsRequired |= feat.mValue;
                 }
                 mFlagsSupported |= feat.mValue;
-                mDefaultFormat.setInteger(key, 1);
+                if (!feat.mInternal) {
+                    mDefaultFormat.setInteger(key, 1);
+                }
                 // TODO restrict features by mFlagsVerified once all codecs reliably verify them
             }
         }
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index bc73f6a..c775b6f 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -183,8 +183,8 @@
         "libmedia",
         "libnativehelper",
         "libutils",
-        "tv_tuner_aidl_interface-ndk_platform",
-        "tv_tuner_resource_manager_aidl_interface-ndk_platform",
+        "tv_tuner_aidl_interface-ndk",
+        "tv_tuner_resource_manager_aidl_interface-ndk",
     ],
 
     static_libs: [
diff --git a/packages/PackageInstaller/OWNERS b/packages/PackageInstaller/OWNERS
index c633113..2736870 100644
--- a/packages/PackageInstaller/OWNERS
+++ b/packages/PackageInstaller/OWNERS
@@ -1,7 +1,5 @@
 svetoslavganov@google.com
-toddke@google.com
-patb@google.com
-suprabh@google.com
+include /PACKAGE_MANAGER_OWNERS
 
 # For automotive related changes
 rogerxue@google.com
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/OWNERS b/packages/SettingsLib/src/com/android/settingslib/inputmethod/OWNERS
index a0e28ba..e3e28cb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/OWNERS
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/OWNERS
@@ -1,5 +1,3 @@
-# Default reviewers for this and subdirectories.
-takaoka@google.com
-yukawa@google.com
+# Bug component: 34867
 
-# Emergency approvers in case the above are not available
\ No newline at end of file
+include platform/frameworks/base:/services/core/java/com/android/server/inputmethod/OWNERS
\ No newline at end of file
diff --git a/packages/SettingsProvider/OWNERS b/packages/SettingsProvider/OWNERS
index 6c61d4b9..5ade971 100644
--- a/packages/SettingsProvider/OWNERS
+++ b/packages/SettingsProvider/OWNERS
@@ -2,6 +2,4 @@
 hackbod@google.com
 narayan@google.com
 svetoslavganov@google.com
-schfan@google.com
-toddke@google.com
-patb@google.com
+include /PACKAGE_MANAGER_OWNERS
diff --git a/services/core/java/android/content/pm/OWNERS b/services/core/java/android/content/pm/OWNERS
index 5eed0b5..3993140 100644
--- a/services/core/java/android/content/pm/OWNERS
+++ b/services/core/java/android/content/pm/OWNERS
@@ -1 +1 @@
-include /core/java/android/content/pm/OWNERS
\ No newline at end of file
+include /PACKAGE_MANAGER_OWNERS
\ No newline at end of file
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 1e608f5..0146aa8 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -81,8 +81,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
 import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicReference;
@@ -1435,11 +1433,7 @@
      */
     public static final class HealthServiceWrapper {
         private static final String TAG = "HealthServiceWrapper";
-        public static final String INSTANCE_HEALTHD = "backup";
         public static final String INSTANCE_VENDOR = "default";
-        // All interesting instances, sorted by priority high -> low.
-        private static final List<String> sAllInstances =
-                Arrays.asList(INSTANCE_VENDOR, INSTANCE_HEALTHD);
 
         private final IServiceNotification mNotification = new Notification();
         private final HandlerThread mHandlerThread = new HandlerThread("HealthServiceHwbinder");
@@ -1471,8 +1465,8 @@
         }
 
         /**
-         * Start monitoring registration of new IHealth services. Only instances that are in
-         * {@code sAllInstances} and in device / framework manifest are used. This function should
+         * Start monitoring registration of new IHealth services. Only instance
+         * {@link #INSTANCE_VENDOR} and in device / framework manifest are used. This function should
          * only be called once.
          *
          * mCallback.onRegistration() is called synchronously (aka in init thread) before
@@ -1481,7 +1475,7 @@
          * @throws RemoteException transaction error when talking to IServiceManager
          * @throws NoSuchElementException if one of the following cases:
          *         - No service manager;
-         *         - none of {@code sAllInstances} are in manifests (i.e. not
+         *         - {@link #INSTANCE_VENDOR} is not in manifests (i.e. not
          *           available on this device), or none of these instances are available to current
          *           process.
          * @throws NullPointerException when supplier is null
@@ -1499,26 +1493,23 @@
 
             // Initialize mLastService and call callback for the first time (in init thread)
             IHealth newService = null;
-            for (String name : sAllInstances) {
-                traceBegin("HealthInitGetService_" + name);
-                try {
-                    newService = healthSupplier.get(name);
-                } catch (NoSuchElementException ex) {
-                    /* ignored, handled below */
-                } finally {
-                    traceEnd();
-                }
-                if (newService != null) {
-                    mInstanceName = name;
-                    mLastService.set(newService);
-                    break;
-                }
+            traceBegin("HealthInitGetService_" + INSTANCE_VENDOR);
+            try {
+                newService = healthSupplier.get(INSTANCE_VENDOR);
+            } catch (NoSuchElementException ex) {
+                /* ignored, handled below */
+            } finally {
+                traceEnd();
+            }
+            if (newService != null) {
+                mInstanceName = INSTANCE_VENDOR;
+                mLastService.set(newService);
             }
 
             if (mInstanceName == null || newService == null) {
                 throw new NoSuchElementException(String.format(
-                        "No IHealth service instance among %s is available. Perhaps no permission?",
-                        sAllInstances.toString()));
+                        "IHealth service instance %s isn't available. Perhaps no permission?",
+                        INSTANCE_VENDOR));
             }
 
             if (callback != null) {
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index d6ee951..aeb8143 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -58,13 +58,13 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Range;
-import android.util.Slog;
 import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
+import com.android.net.module.util.BinderUtils;
 import com.android.net.module.util.NetdUtils;
 import com.android.net.module.util.PermissionUtils;
 
@@ -1056,9 +1056,9 @@
 
     public void systemReady() {
         if (isNetdAlive()) {
-            Slog.d(TAG, "IpSecService is ready");
+            Log.d(TAG, "IpSecService is ready");
         } else {
-            Slog.wtf(TAG, "IpSecService not ready: failed to connect to NetD Native Service!");
+            Log.wtf(TAG, "IpSecService not ready: failed to connect to NetD Native Service!");
         }
     }
 
@@ -1332,7 +1332,7 @@
             final INetd netd = mSrvConfig.getNetdInstance();
             netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
 
-            Binder.withCleanCallingIdentity(() -> {
+            BinderUtils.withCleanCallingIdentity(() -> {
                 NetdUtils.setInterfaceUp(netd, intfName);
             });
 
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 3ea0ce1..c7e9068 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -59,9 +59,6 @@
 import android.net.RouteInfo;
 import android.net.TetherStatsParcel;
 import android.net.UidRangeParcel;
-import android.net.shared.NetdUtils;
-import android.net.shared.RouteUtils;
-import android.net.shared.RouteUtils.ModifyOperation;
 import android.net.util.NetdService;
 import android.os.BatteryStats;
 import android.os.Binder;
@@ -88,6 +85,8 @@
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.HexDump;
 import com.android.internal.util.Preconditions;
+import com.android.net.module.util.NetdUtils;
+import com.android.net.module.util.NetdUtils.ModifyOperation;
 
 import com.google.android.collect.Maps;
 
@@ -831,13 +830,13 @@
     @Override
     public void addRoute(int netId, RouteInfo route) {
         NetworkStack.checkNetworkStackPermission(mContext);
-        RouteUtils.modifyRoute(mNetdService, ModifyOperation.ADD, netId, route);
+        NetdUtils.modifyRoute(mNetdService, ModifyOperation.ADD, netId, route);
     }
 
     @Override
     public void removeRoute(int netId, RouteInfo route) {
         NetworkStack.checkNetworkStackPermission(mContext);
-        RouteUtils.modifyRoute(mNetdService, ModifyOperation.REMOVE, netId, route);
+        NetdUtils.modifyRoute(mNetdService, ModifyOperation.REMOVE, netId, route);
     }
 
     private ArrayList<String> readRouteList(String filename) {
@@ -1785,7 +1784,7 @@
     public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) {
         modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, iface);
         // modifyInterfaceInNetwork already check calling permission.
-        RouteUtils.addRoutesToLocalNetwork(mNetdService, iface, routes);
+        NetdUtils.addRoutesToLocalNetwork(mNetdService, iface, routes);
     }
 
     @Override
@@ -1796,7 +1795,7 @@
     @Override
     public int removeRoutesFromLocalNetwork(List<RouteInfo> routes) {
         NetworkStack.checkNetworkStackPermission(mContext);
-        return RouteUtils.removeRoutesFromLocalNetwork(mNetdService, routes);
+        return NetdUtils.removeRoutesFromLocalNetwork(mNetdService, routes);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 95dc667..b641377 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -16,6 +16,9 @@
 # ServiceWatcher
 per-file ServiceWatcher.java = sooniln@google.com
 
+# Health
+per-file BatteryService.java = file:platform/hardware/interfaces:/health/aidl/OWNERS
+
 per-file *Alarm* = file:/apex/jobscheduler/OWNERS
 per-file *AppOp* = file:/core/java/android/permission/OWNERS
 per-file *Battery* = file:/BATTERY_STATS_OWNERS
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index c11c4de..43bd9e7 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1029,7 +1029,6 @@
             return;
         }
 
-        int phoneId = getPhoneIdFromSubId(subId);
         synchronized (mRecords) {
             // register
             IBinder b = callback.asBinder();
@@ -1052,21 +1051,24 @@
             // Legacy applications pass SubscriptionManager.DEFAULT_SUB_ID,
             // force all illegal subId to SubscriptionManager.DEFAULT_SUB_ID
             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
+                if (DBG) {
+                    log("invalid subscription id, use default id");
+                }
                 r.subId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
             } else {//APP specify subID
                 r.subId = subId;
             }
-            r.phoneId = phoneId;
+            r.phoneId = getPhoneIdFromSubId(r.subId);
             r.eventList = events;
 
             if (DBG) {
-                log("listen:  Register r=" + r + " r.subId=" + r.subId + " phoneId=" + phoneId);
+                log("listen:  Register r=" + r + " r.subId=" + r.subId + " r.phoneId=" + r.phoneId);
             }
-            if (notifyNow && validatePhoneId(phoneId)) {
+            if (notifyNow && validatePhoneId(r.phoneId)) {
                 if (events.contains(TelephonyCallback.EVENT_SERVICE_STATE_CHANGED)){
                     try {
-                        if (VDBG) log("listen: call onSSC state=" + mServiceState[phoneId]);
-                        ServiceState rawSs = new ServiceState(mServiceState[phoneId]);
+                        if (VDBG) log("listen: call onSSC state=" + mServiceState[r.phoneId]);
+                        ServiceState rawSs = new ServiceState(mServiceState[r.phoneId]);
                         if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
                             r.callback.onServiceStateChanged(rawSs);
                         } else if (checkCoarseLocationAccess(r, Build.VERSION_CODES.Q)) {
@@ -1082,8 +1084,8 @@
                 }
                 if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)) {
                     try {
-                        if (mSignalStrength[phoneId] != null) {
-                            int gsmSignalStrength = mSignalStrength[phoneId]
+                        if (mSignalStrength[r.phoneId] != null) {
+                            int gsmSignalStrength = mSignalStrength[r.phoneId]
                                     .getGsmSignalStrength();
                             r.callback.onSignalStrengthChanged((gsmSignalStrength == 99 ? -1
                                     : gsmSignalStrength));
@@ -1096,7 +1098,7 @@
                         TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)) {
                     try {
                         r.callback.onMessageWaitingIndicatorChanged(
-                                mMessageWaiting[phoneId]);
+                                mMessageWaiting[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -1105,7 +1107,7 @@
                         TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)) {
                     try {
                         r.callback.onCallForwardingIndicatorChanged(
-                                mCallForwarding[phoneId]);
+                                mCallForwarding[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -1113,11 +1115,11 @@
                 if (validateEventAndUserLocked(
                         r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)) {
                     try {
-                        if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]);
+                        if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[r.phoneId]);
                         if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
                                 && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
                             // null will be translated to empty CellLocation object in client.
-                            r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
+                            r.callback.onCellLocationChanged(mCellIdentity[r.phoneId]);
                         }
                     } catch (RemoteException ex) {
                         remove(r.binder);
@@ -1125,38 +1127,38 @@
                 }
                 if (events.contains(TelephonyCallback.EVENT_LEGACY_CALL_STATE_CHANGED)) {
                     try {
-                        r.callback.onLegacyCallStateChanged(mCallState[phoneId],
-                                getCallIncomingNumber(r, phoneId));
+                        r.callback.onLegacyCallStateChanged(mCallState[r.phoneId],
+                                getCallIncomingNumber(r, r.phoneId));
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_CALL_STATE_CHANGED)) {
                     try {
-                        r.callback.onCallStateChanged(mCallState[phoneId]);
+                        r.callback.onCallStateChanged(mCallState[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)) {
                     try {
-                        r.callback.onDataConnectionStateChanged(mDataConnectionState[phoneId],
-                                mDataConnectionNetworkType[phoneId]);
+                        r.callback.onDataConnectionStateChanged(mDataConnectionState[r.phoneId],
+                                mDataConnectionNetworkType[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED)) {
                     try {
-                        r.callback.onDataActivity(mDataActivity[phoneId]);
+                        r.callback.onDataActivity(mDataActivity[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)) {
                     try {
-                        if (mSignalStrength[phoneId] != null) {
-                            r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
+                        if (mSignalStrength[r.phoneId] != null) {
+                            r.callback.onSignalStrengthsChanged(mSignalStrength[r.phoneId]);
                         }
                     } catch (RemoteException ex) {
                         remove(r.binder);
@@ -1166,8 +1168,8 @@
                         TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED)) {
                     updateReportSignalStrengthDecision(r.subId);
                     try {
-                        if (mSignalStrength[phoneId] != null) {
-                            r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
+                        if (mSignalStrength[r.phoneId] != null) {
+                            r.callback.onSignalStrengthsChanged(mSignalStrength[r.phoneId]);
                         }
                     } catch (RemoteException ex) {
                         remove(r.binder);
@@ -1176,11 +1178,13 @@
                 if (validateEventAndUserLocked(
                         r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)) {
                     try {
-                        if (DBG_LOC) log("listen: mCellInfo[" + phoneId + "] = "
-                                + mCellInfo.get(phoneId));
+                        if (DBG_LOC) {
+                            log("listen: mCellInfo[" + r.phoneId + "] = "
+                                    + mCellInfo.get(r.phoneId));
+                        }
                         if (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
                                 && checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
-                            r.callback.onCellInfoChanged(mCellInfo.get(phoneId));
+                            r.callback.onCellInfoChanged(mCellInfo.get(r.phoneId));
                         }
                     } catch (RemoteException ex) {
                         remove(r.binder);
@@ -1188,22 +1192,22 @@
                 }
                 if (events.contains(TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED)) {
                     try {
-                        r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]);
+                        r.callback.onPreciseCallStateChanged(mPreciseCallState[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)) {
                     try {
-                        r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId],
-                                mCallPreciseDisconnectCause[phoneId]);
+                        r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[r.phoneId],
+                                mCallPreciseDisconnectCause[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)) {
                     try {
-                        r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(phoneId));
+                        r.callback.onImsCallDisconnectCauseChanged(mImsReasonInfo.get(r.phoneId));
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -1212,7 +1216,7 @@
                         TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)) {
                     try {
                         for (PreciseDataConnectionState pdcs
-                                : mPreciseDataConnectionStates.get(phoneId).values()) {
+                                : mPreciseDataConnectionStates.get(r.phoneId).values()) {
                             r.callback.onPreciseDataConnectionStateChanged(pdcs);
                         }
                     } catch (RemoteException ex) {
@@ -1229,29 +1233,29 @@
                 if (events.contains(TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)) {
                     try {
                         r.callback.onVoiceActivationStateChanged(
-                                mVoiceActivationState[phoneId]);
+                                mVoiceActivationState[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED)) {
                     try {
-                        r.callback.onDataActivationStateChanged(mDataActivationState[phoneId]);
+                        r.callback.onDataActivationStateChanged(mDataActivationState[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)) {
                     try {
-                        r.callback.onUserMobileDataStateChanged(mUserMobileDataState[phoneId]);
+                        r.callback.onUserMobileDataStateChanged(mUserMobileDataState[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)) {
                     try {
-                        if (mTelephonyDisplayInfos[phoneId] != null) {
-                            r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[phoneId]);
+                        if (mTelephonyDisplayInfos[r.phoneId] != null) {
+                            r.callback.onDisplayInfoChanged(mTelephonyDisplayInfos[r.phoneId]);
                         }
                     } catch (RemoteException ex) {
                         remove(r.binder);
@@ -1288,20 +1292,20 @@
                 }
                 if (events.contains(TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)) {
                     try {
-                        r.callback.onSrvccStateChanged(mSrvccState[phoneId]);
+                        r.callback.onSrvccStateChanged(mSrvccState[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)) {
                     try {
-                        r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
+                        r.callback.onCallAttributesChanged(mCallAttributes[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
                 }
                 if (events.contains(TelephonyCallback.EVENT_BARRING_INFO_CHANGED)) {
-                    BarringInfo barringInfo = mBarringInfo.get(phoneId);
+                    BarringInfo barringInfo = mBarringInfo.get(r.phoneId);
                     BarringInfo biNoLocation = barringInfo != null
                             ? barringInfo.createLocationInfoSanitizedCopy() : null;
                     if (VDBG) log("listen: call onBarringInfoChanged=" + barringInfo);
@@ -1319,8 +1323,8 @@
                         r.callback.onPhysicalChannelConfigChanged(
                                 shouldSanitizeLocationForPhysicalChannelConfig(r)
                                         ? getLocationSanitizedConfigs(
-                                                mPhysicalChannelConfigs.get(phoneId))
-                                        : mPhysicalChannelConfigs.get(phoneId));
+                                                mPhysicalChannelConfigs.get(r.phoneId))
+                                        : mPhysicalChannelConfigs.get(r.phoneId));
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -1329,7 +1333,7 @@
                         TelephonyCallback.EVENT_DATA_ENABLED_CHANGED)) {
                     try {
                         r.callback.onDataEnabledChanged(
-                                mIsDataEnabled[phoneId], mDataEnabledReason[phoneId]);
+                                mIsDataEnabled[r.phoneId], mDataEnabledReason[r.phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -1337,9 +1341,9 @@
                 if (events.contains(
                         TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED)) {
                     try {
-                        if (mLinkCapacityEstimateLists.get(phoneId) != null) {
+                        if (mLinkCapacityEstimateLists.get(r.phoneId) != null) {
                             r.callback.onLinkCapacityEstimateChanged(mLinkCapacityEstimateLists
-                                    .get(phoneId));
+                                    .get(r.phoneId));
                         }
                     } catch (RemoteException ex) {
                         remove(r.binder);
@@ -1581,7 +1585,7 @@
                     }
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_SERVICE_STATE_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
 
                         try {
                             ServiceState stateToSend;
@@ -1643,7 +1647,7 @@
                         if ((activationType == SIM_ACTIVATION_TYPE_VOICE)
                                 && r.matchTelephonyCallbackEvent(
                                         TelephonyCallback.EVENT_VOICE_ACTIVATION_STATE_CHANGED)
-                                && idMatch(r.subId, subId, phoneId)) {
+                                && idMatch(r, subId, phoneId)) {
                             if (DBG) {
                                 log("notifyVoiceActivationStateForPhoneId: callback.onVASC r=" + r
                                         + " subId=" + subId + " phoneId=" + phoneId
@@ -1654,7 +1658,7 @@
                         if ((activationType == SIM_ACTIVATION_TYPE_DATA)
                                 && r.matchTelephonyCallbackEvent(
                                         TelephonyCallback.EVENT_DATA_ACTIVATION_STATE_CHANGED)
-                                && idMatch(r.subId, subId, phoneId)) {
+                                && idMatch(r, subId, phoneId)) {
                             if (DBG) {
                                 log("notifyDataActivationStateForPhoneId: callback.onDASC r=" + r
                                         + " subId=" + subId + " phoneId=" + phoneId
@@ -1696,7 +1700,7 @@
                             TelephonyCallback.EVENT_SIGNAL_STRENGTHS_CHANGED)
                             || r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_ALWAYS_REPORTED_SIGNAL_STRENGTH_CHANGED))
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             if (DBG) {
                                 log("notifySignalStrengthForPhoneId: callback.onSsS r=" + r
@@ -1710,7 +1714,7 @@
                     }
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_SIGNAL_STRENGTH_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             int gsmSignalStrength = signalStrength.getGsmSignalStrength();
                             int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
@@ -1757,7 +1761,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_CARRIER_NETWORK_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onCarrierNetworkChange(active);
                         } catch (RemoteException ex) {
@@ -1789,7 +1793,7 @@
                 for (Record r : mRecords) {
                     if (validateEventAndUserLocked(
                             r, TelephonyCallback.EVENT_CELL_INFO_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)
+                            && idMatch(r, subId, phoneId)
                             && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
                                     && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
                         try {
@@ -1823,7 +1827,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_MESSAGE_WAITING_INDICATOR_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onMessageWaitingIndicatorChanged(mwi);
                         } catch (RemoteException ex) {
@@ -1850,7 +1854,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_USER_MOBILE_DATA_STATE_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onUserMobileDataStateChanged(state);
                         } catch (RemoteException ex) {
@@ -1889,7 +1893,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED)
-                            && idMatchWithoutDefaultPhoneCheck(r.subId, subId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             if (!mConfigurationProvider.isDisplayInfoNrAdvancedSupported(
                                     r.callingPackage, Binder.getCallingUserHandle())) {
@@ -1940,7 +1944,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_CALL_FORWARDING_INDICATOR_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onCallForwardingIndicatorChanged(cfi);
                         } catch (RemoteException ex) {
@@ -1969,7 +1973,7 @@
                     // Notify by correct subId.
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_DATA_ACTIVITY_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onDataActivity(state);
                         } catch (RemoteException ex) {
@@ -2017,7 +2021,7 @@
                     for (Record r : mRecords) {
                         if (r.matchTelephonyCallbackEvent(
                                 TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED)
-                                && idMatch(r.subId, subId, phoneId)) {
+                                && idMatch(r, subId, phoneId)) {
                             try {
                                 if (DBG) {
                                     log("Notify data connection state changed on sub: " + subId);
@@ -2042,7 +2046,7 @@
                     for (Record r : mRecords) {
                         if (r.matchTelephonyCallbackEvent(
                                 TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED)
-                                && idMatch(r.subId, subId, phoneId)) {
+                                && idMatch(r, subId, phoneId)) {
                             try {
                                 r.callback.onPreciseDataConnectionStateChanged(preciseState);
                             } catch (RemoteException ex) {
@@ -2089,7 +2093,7 @@
                 for (Record r : mRecords) {
                     if (validateEventAndUserLocked(
                             r, TelephonyCallback.EVENT_CELL_LOCATION_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)
+                            && idMatch(r, subId, phoneId)
                             && (checkCoarseLocationAccess(r, Build.VERSION_CODES.BASE)
                                     && checkFineLocationAccess(r, Build.VERSION_CODES.Q))) {
                         try {
@@ -2143,7 +2147,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_PRECISE_CALL_STATE_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onPreciseCallStateChanged(mPreciseCallState[phoneId]);
                         } catch (RemoteException ex) {
@@ -2152,7 +2156,7 @@
                     }
                     if (notifyCallAttributes && r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
                         } catch (RemoteException ex) {
@@ -2177,7 +2181,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_CALL_DISCONNECT_CAUSE_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause[phoneId],
                                     mCallPreciseDisconnectCause[phoneId]);
@@ -2202,7 +2206,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_IMS_CALL_DISCONNECT_CAUSE_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
                                 log("notifyImsCallDisconnectCause: mImsReasonInfo="
@@ -2234,7 +2238,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_SRVCC_STATE_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
                                 log("notifySrvccStateChanged: mSrvccState=" + state + " r=" + r);
@@ -2263,7 +2267,7 @@
                     }
                     if ((r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_OEM_HOOK_RAW))
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onOemHookRawEvent(rawData);
                         } catch (RemoteException ex) {
@@ -2343,7 +2347,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onRadioPowerStateChanged(state);
                         } catch (RemoteException ex) {
@@ -2372,7 +2376,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_EMERGENCY_NUMBER_LIST_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onEmergencyNumberListChanged(mEmergencyNumberList);
                             if (VDBG) {
@@ -2459,7 +2463,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_CALL_ATTRIBUTES_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onCallAttributesChanged(mCallAttributes[phoneId]);
                         } catch (RemoteException ex) {
@@ -2490,7 +2494,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_REGISTRATION_FAILURE)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onRegistrationFailed(
                                     checkFineLocationAccess(r, Build.VERSION_CODES.BASE)
@@ -2533,7 +2537,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_BARRING_INFO_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
                                 log("notifyBarringInfo: mBarringInfo="
@@ -2578,7 +2582,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             if (DBG_LOC) {
                                 log("notifyPhysicalChannelConfig: mPhysicalChannelConfigs="
@@ -2645,7 +2649,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_DATA_ENABLED_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onDataEnabledChanged(enabled, reason);
                         } catch (RemoteException ex) {
@@ -2680,7 +2684,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_ALLOWED_NETWORK_TYPE_LIST_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             if (VDBG) {
                                 log("notifyAllowedNetworkTypesChanged: reason= " + reason
@@ -2722,7 +2726,7 @@
                 for (Record r : mRecords) {
                     if (r.matchTelephonyCallbackEvent(
                             TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED)
-                            && idMatch(r.subId, subId, phoneId)) {
+                            && idMatch(r, subId, phoneId)) {
                         try {
                             r.callback.onLinkCapacityEstimateChanged(linkCapacityEstimateList);
                         } catch (RemoteException ex) {
@@ -3172,33 +3176,24 @@
     }
 
     /**
-     * If the registrant specified a subId, then we should only notify it if subIds match.
-     * If the registrant registered with DEFAULT subId, we should notify only when the related subId
-     * is default subId (which could be INVALID if there's no default subId).
+     * Match the sub id or phone id of the event to the record
      *
-     * This should be the correct way to check record ID match. in idMatch the record's phoneId is
-     * speculated based on subId passed by the registrant so it's not a good reference.
-     * But to avoid triggering potential regression only replace idMatch with it when an issue with
-     * idMatch is reported. Eventually this should replace all instances of idMatch.
+     * We follow the rules below:
+     * 1) If sub id of the event is invalid, phone id should be used.
+     * 2) The event on default sub should be notified to the records
+     * which register the default sub id.
+     * 3) Sub id should be exactly matched for all other cases.
      */
-    private boolean idMatchWithoutDefaultPhoneCheck(int subIdInRecord, int subIdToNotify) {
-        if (subIdInRecord == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            return (subIdToNotify == mDefaultSubId);
-        } else {
-            return (subIdInRecord == subIdToNotify);
-        }
-    }
+    boolean idMatch(Record r, int subId, int phoneId) {
 
-    boolean idMatch(int rSubId, int subId, int phoneId) {
-
-        if(subId < 0) {
-            // Invalid case, we need compare phoneId with default one.
-            return (mDefaultPhoneId == phoneId);
+        if (subId < 0) {
+            // Invalid case, we need compare phoneId.
+            return (r.phoneId == phoneId);
         }
-        if(rSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
+        if (r.subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
             return (subId == mDefaultSubId);
         } else {
-            return (rSubId == subId);
+            return (r.subId == subId);
         }
     }
 
diff --git a/services/core/java/com/android/server/VpnManagerService.java b/services/core/java/com/android/server/VpnManagerService.java
index a03425c..b48e21e 100644
--- a/services/core/java/com/android/server/VpnManagerService.java
+++ b/services/core/java/com/android/server/VpnManagerService.java
@@ -681,7 +681,7 @@
         intentFilter = new IntentFilter();
         intentFilter.addAction(LockdownVpnTracker.ACTION_LOCKDOWN_RESET);
         mUserAllContext.registerReceiver(
-                mIntentReceiver, intentFilter, NETWORK_STACK, mHandler);
+                mIntentReceiver, intentFilter, NETWORK_STACK, mHandler, Context.RECEIVER_EXPORTED);
     }
 
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index a2fec27..a29a49c 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -4906,7 +4906,9 @@
             sr.setProcess(null, null, 0, null);
             sr.isolatedProc = null;
             sr.executeNesting = 0;
-            sr.forceClearTracker();
+            synchronized (mAm.mProcessStats.mLock) {
+                sr.forceClearTracker();
+            }
             if (mDestroyingServices.remove(sr)) {
                 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "killServices remove destroying " + sr);
             }
@@ -5056,7 +5058,9 @@
             i--;
             ServiceRecord sr = mDestroyingServices.get(i);
             if (sr.app == app) {
-                sr.forceClearTracker();
+                synchronized (mAm.mProcessStats.mLock) {
+                    sr.forceClearTracker();
+                }
                 mDestroyingServices.remove(i);
                 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "killServices remove destroying " + sr);
             }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 8e1b06b..d75f21c 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -6136,6 +6136,11 @@
         if (pkgName == null) {
             pkgName = "";
         }
+        if (device.getType() == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP) {
+            avrcpSupportsAbsoluteVolume(device.getAddress(),
+                    deviceVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+            return;
+        }
 
         int audioSystemDeviceOut = AudioDeviceInfo.convertDeviceTypeToInternalDevice(
                 device.getType());
@@ -7792,7 +7797,7 @@
         }
     }
 
-    public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
+    private void avrcpSupportsAbsoluteVolume(String address, boolean support) {
         // address is not used for now, but may be used when multiple a2dp devices are supported
         sVolumeLogger.log(new AudioEventLogger.StringEvent("avrcpSupportsAbsoluteVolume addr="
                 + address + " support=" + support));
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 091e6c4..a56a8ea 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -227,7 +227,7 @@
             subscriberId = tele.getSubscriberId();
             mNetworkTemplate = new NetworkTemplate(
                     NetworkTemplate.MATCH_MOBILE, subscriberId, new String[] { subscriberId },
-                    null, NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
+                    null, NetworkStats.METERED_YES, NetworkStats.ROAMING_ALL,
                     NetworkStats.DEFAULT_NETWORK_NO, NETWORK_TYPE_ALL, OEM_MANAGED_ALL,
                     SUBSCRIBER_ID_MATCH_RULE_EXACT);
             mUsageCallback = new UsageCallback() {
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 565c9ae..bf4ef48 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -126,6 +126,7 @@
 import libcore.io.IoUtils;
 
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -195,6 +196,7 @@
 
     private final Context mContext;
     private final ConnectivityManager mConnectivityManager;
+    private final AppOpsManager mAppOpsManager;
     // The context is for specific user which is created from mUserId
     private final Context mUserIdContext;
     @VisibleForTesting final Dependencies mDeps;
@@ -407,6 +409,46 @@
         public boolean isInterfacePresent(final Vpn vpn, final String iface) {
             return vpn.jniCheck(iface) != 0;
         }
+
+        /**
+         * @see ParcelFileDescriptor#adoptFd(int)
+         */
+        public ParcelFileDescriptor adoptFd(Vpn vpn, int mtu) {
+            return ParcelFileDescriptor.adoptFd(jniCreate(vpn, mtu));
+        }
+
+        /**
+         * Call native method to create the VPN interface and return the FileDescriptor of /dev/tun.
+         */
+        public int jniCreate(Vpn vpn, int mtu) {
+            return vpn.jniCreate(mtu);
+        }
+
+        /**
+         * Call native method to get the interface name of VPN.
+         */
+        public String jniGetName(Vpn vpn, int fd) {
+            return vpn.jniGetName(fd);
+        }
+
+        /**
+         * Call native method to set the VPN addresses and return the number of addresses.
+         */
+        public int jniSetAddresses(Vpn vpn, String interfaze, String addresses) {
+            return vpn.jniSetAddresses(interfaze, addresses);
+        }
+
+        /**
+         * @see IoUtils#setBlocking(FileDescriptor, boolean)
+         */
+        public void setBlocking(FileDescriptor fd, boolean blocking) {
+            try {
+                IoUtils.setBlocking(fd, blocking);
+            } catch (IOException e) {
+                throw new IllegalStateException(
+                        "Cannot set tunnel's fd as blocking=" + blocking, e);
+            }
+        }
     }
 
     public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd,
@@ -431,6 +473,7 @@
         mVpnProfileStore = vpnProfileStore;
         mContext = context;
         mConnectivityManager = mContext.getSystemService(ConnectivityManager.class);
+        mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
         mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */);
         mDeps = deps;
         mNms = netService;
@@ -826,7 +869,6 @@
             VpnProfile profile = getVpnProfilePrivileged(alwaysOnPackage);
             if (profile != null) {
                 startVpnProfilePrivileged(profile, alwaysOnPackage);
-
                 // If the above startVpnProfilePrivileged() call returns, the Ikev2VpnProfile was
                 // correctly parsed, and the VPN has started running in a different thread. The only
                 // other possibility is that the above call threw an exception, which will be
@@ -974,9 +1016,15 @@
                 } catch (Exception e) {
                     // ignore
                 }
+                mAppOpsManager.finishOp(
+                        AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage, null);
                 mContext.unbindService(mConnection);
                 cleanupVpnStateLocked();
             } else if (mVpnRunner != null) {
+                if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
+                    mAppOpsManager.finishOp(
+                            AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null);
+                }
                 // cleanupVpnStateLocked() is called from mVpnRunner.exit()
                 mVpnRunner.exit();
             }
@@ -1041,10 +1089,8 @@
                     return false;
             }
 
-            final AppOpsManager appOpMgr =
-                    (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
             for (final String appOpStr : toChange) {
-                appOpMgr.setMode(
+                mAppOpsManager.setMode(
                         appOpStr,
                         uid,
                         packageName,
@@ -1270,6 +1316,9 @@
             capsBuilder.addCapability(NET_CAPABILITY_NOT_METERED);
         }
 
+        capsBuilder.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
+                ? Arrays.asList(mConfig.underlyingNetworks) : null);
+
         mNetworkCapabilities = capsBuilder.build();
         mNetworkAgent = new NetworkAgent(mContext, mLooper, NETWORKTYPE /* logtag */,
                 mNetworkCapabilities, lp,
@@ -1290,8 +1339,6 @@
         } finally {
             Binder.restoreCallingIdentity(token);
         }
-        mNetworkAgent.setUnderlyingNetworks((mConfig.underlyingNetworks != null)
-                ? Arrays.asList(mConfig.underlyingNetworks) : null);
         updateState(DetailedState.CONNECTED, "agentConnect");
     }
 
@@ -1365,9 +1412,9 @@
         Set<Range<Integer>> oldUsers = mNetworkCapabilities.getUids();
 
         // Configure the interface. Abort if any of these steps fails.
-        ParcelFileDescriptor tun = ParcelFileDescriptor.adoptFd(jniCreate(config.mtu));
+        final ParcelFileDescriptor tun = mDeps.adoptFd(this, config.mtu);
         try {
-            String interfaze = jniGetName(tun.getFd());
+            final String interfaze = mDeps.jniGetName(this, tun.getFd());
 
             // TEMP use the old jni calls until there is support for netd address setting
             StringBuilder builder = new StringBuilder();
@@ -1375,7 +1422,7 @@
                 builder.append(" ");
                 builder.append(address);
             }
-            if (jniSetAddresses(interfaze, builder.toString()) < 1) {
+            if (mDeps.jniSetAddresses(this, interfaze, builder.toString()) < 1) {
                 throw new IllegalArgumentException("At least one address must be specified");
             }
             Connection connection = new Connection();
@@ -1421,11 +1468,11 @@
                 jniReset(oldInterface);
             }
 
-            try {
-                IoUtils.setBlocking(tun.getFileDescriptor(), config.blocking);
-            } catch (IOException e) {
-                throw new IllegalStateException(
-                        "Cannot set tunnel's fd as blocking=" + config.blocking, e);
+            mDeps.setBlocking(tun.getFileDescriptor(), config.blocking);
+            // Record that the VPN connection is established by an app which uses VpnService API.
+            if (oldNetworkAgent != mNetworkAgent) {
+                mAppOpsManager.startOp(
+                        AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage, null, null);
             }
         } catch (RuntimeException e) {
             IoUtils.closeQuietly(tun);
@@ -1780,9 +1827,17 @@
             synchronized (Vpn.this) {
                 if (interfaze.equals(mInterface) && jniCheck(interfaze) == 0) {
                     if (mConnection != null) {
+                        mAppOpsManager.finishOp(
+                                AppOpsManager.OPSTR_ESTABLISH_VPN_SERVICE, mOwnerUID, mPackage,
+                                null);
                         mContext.unbindService(mConnection);
                         cleanupVpnStateLocked();
                     } else if (mVpnRunner != null) {
+                        if (!VpnConfig.LEGACY_VPN.equals(mPackage)) {
+                            mAppOpsManager.finishOp(
+                                    AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage,
+                                    null);
+                        }
                         // cleanupVpnStateLocked() is called from mVpnRunner.exit()
                         mVpnRunner.exit();
                     }
@@ -3253,8 +3308,7 @@
      *
      * @param packageName the package name of the app provisioning this profile
      */
-    public synchronized void startVpnProfile(
-            @NonNull String packageName) {
+    public synchronized void startVpnProfile(@NonNull String packageName) {
         requireNonNull(packageName, "No package name provided");
 
         enforceNotRestrictedUser();
@@ -3317,6 +3371,13 @@
                     Log.d(TAG, "Unknown VPN profile type: " + profile.type);
                     break;
             }
+
+            // Record that the VPN connection is established by an app which uses VpnManager API.
+            if (!VpnConfig.LEGACY_VPN.equals(packageName)) {
+                mAppOpsManager.startOp(
+                        AppOpsManager.OPSTR_ESTABLISH_VPN_MANAGER, mOwnerUID, mPackage, null,
+                        null);
+            }
         } catch (GeneralSecurityException e) {
             // Reset mConfig
             mConfig = null;
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index d66d7ee..329a696 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -512,7 +512,10 @@
      */
     public void setShouldAlwaysRespectAppRequestedMode(boolean enabled) {
         synchronized (mLock) {
-            mAlwaysRespectAppRequest = enabled;
+            if (mAlwaysRespectAppRequest != enabled) {
+                mAlwaysRespectAppRequest = enabled;
+                notifyDesiredDisplayModeSpecsChangedLocked();
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index a2cb78d..c27293c 100755
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -209,6 +209,12 @@
     void init() {
         assertRunOnServiceThread();
         mPreferredAddress = getPreferredAddress();
+        if (mHandler.hasMessages(MSG_DISABLE_DEVICE_TIMEOUT)) {
+            // Remove and trigger the queued message for clearing all actions when going to standby.
+            // This is necessary because the device may wake up before the message is triggered.
+            mHandler.removeMessages(MSG_DISABLE_DEVICE_TIMEOUT);
+            handleDisableDeviceTimeout();
+        }
         mPendingActionClearedCallback = null;
     }
 
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index e5a8a17d..a571dc0 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -3131,7 +3131,7 @@
                 Slog.v(TAG, "On standby-action cleared:" + device.mDeviceType);
                 devices.remove(device);
                 if (devices.isEmpty()) {
-                    onStandbyCompleted(standbyAction);
+                    onPendingActionsCleared(standbyAction);
                     // We will not clear local devices here, since some OEM/SOC will keep passing
                     // the received packets until the application processor enters to the sleep
                     // actually.
@@ -3193,10 +3193,17 @@
         mHdmiCecNetwork.clearLocalDevices();
     }
 
+    /**
+     * Normally called after all devices have cleared their pending actions, to execute the final
+     * phase of the standby flow.
+     *
+     * This can also be called during wakeup, when pending actions are cleared after failing to be
+     * cleared during standby. In this case, it does not execute the standby flow.
+     */
     @ServiceThreadOnly
-    private void onStandbyCompleted(int standbyAction) {
+    private void onPendingActionsCleared(int standbyAction) {
         assertRunOnServiceThread();
-        Slog.v(TAG, "onStandbyCompleted");
+        Slog.v(TAG, "onPendingActionsCleared");
 
         if (!mPowerStatusController.isPowerStatusTransientToStandby()) {
             return;
diff --git a/services/core/java/com/android/server/health/OWNERS b/services/core/java/com/android/server/health/OWNERS
new file mode 100644
index 0000000..81522fc
--- /dev/null
+++ b/services/core/java/com/android/server/health/OWNERS
@@ -0,0 +1 @@
+file:platform/hardware/interfaces:/health/aidl/OWNERS
diff --git a/services/core/java/com/android/server/inputmethod/OWNERS b/services/core/java/com/android/server/inputmethod/OWNERS
index c09ade9..00cd700 100644
--- a/services/core/java/com/android/server/inputmethod/OWNERS
+++ b/services/core/java/com/android/server/inputmethod/OWNERS
@@ -5,3 +5,4 @@
 tarandeep@google.com
 lumark@google.com
 roosa@google.com
+wilsonwu@google.com
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 3233819..1bdc9f3 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -3,27 +3,25 @@
 jsharkey@android.com
 jsharkey@google.com
 narayan@google.com
-patb@google.com
 svetoslavganov@android.com
 svetoslavganov@google.com
-toddke@android.com
-toddke@google.com
+include /PACKAGE_MANAGER_OWNERS
 
 # apex support
 per-file ApexManager.java = dariofreni@google.com, ioffe@google.com, olilan@google.com
 per-file StagingManager.java = dariofreni@google.com, ioffe@google.com, olilan@google.com
 
 # dex
-per-file AbstractStatsBase.java = calin@google.com, ngeoffray@google.com
-per-file BackgroundDexOptService.java = calin@google.com, ngeoffray@google.com
-per-file CompilerStats.java = calin@google.com, ngeoffray@google.com
-per-file DynamicCodeLoggingService.java = alanstokes@google.com, calin@google.com, ngeoffray@google.com
-per-file InstructionSets.java = calin@google.com, ngeoffray@google.com
-per-file OtaDexoptService.java = calin@google.com, ngeoffray@google.com
-per-file OtaDexoptShellCommand.java = calin@google.com, ngeoffray@google.com
-per-file PackageDexOptimizer.java = calin@google.com, ngeoffray@google.com
-per-file PackageManagerServiceCompilerMapping.java = calin@google.com, ngeoffray@google.com
-per-file PackageUsage.java = calin@google.com, ngeoffray@google.com
+per-file AbstractStatsBase.java = file:dex/OWNERS
+per-file BackgroundDexOptService.java = file:dex/OWNERS
+per-file CompilerStats.java = file:dex/OWNERS
+per-file DynamicCodeLoggingService.java = file:dex/OWNERS
+per-file InstructionSets.java = file:dex/OWNERS
+per-file OtaDexoptService.java = file:dex/OWNERS
+per-file OtaDexoptShellCommand.java = file:dex/OWNERS
+per-file PackageDexOptimizer.java = file:dex/OWNERS
+per-file PackageManagerServiceCompilerMapping.java = file:dex/OWNERS
+per-file PackageUsage.java = file:dex/OWNERS
 
 # multi user / cross profile
 per-file CrossProfileAppsServiceImpl.java = omakoto@google.com, yamasani@google.com
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f6acad0..827dfc0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7337,9 +7337,16 @@
 
             // Parse overlay configuration files to set default enable state, mutability, and
             // priority of system overlays.
+            final ArrayMap<String, File> apkInApexPreInstalledPaths = new ArrayMap<>();
+            for (ApexManager.ActiveApexInfo apexInfo : mApexManager.getActiveApexInfos()) {
+                for (String packageName : mApexManager.getApksInApex(apexInfo.apexModuleName)) {
+                    apkInApexPreInstalledPaths.put(packageName, apexInfo.preInstalledApexPath);
+                }
+            }
             mOverlayConfig = OverlayConfig.initializeSystemInstance(
                     consumer -> mPmInternal.forEachPackage(
-                            pkg -> consumer.accept(pkg, pkg.isSystem())));
+                            pkg -> consumer.accept(pkg, pkg.isSystem(),
+                              apkInApexPreInstalledPaths.get(pkg.getPackageName()))));
 
             // Prune any system packages that no longer exist.
             final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index c2c35b7..08a7215 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -1255,6 +1255,9 @@
                     info.diskImagePath = ai.modulePath;
                     info.versionCode = ai.versionCode;
                     info.versionName = ai.versionName;
+                    info.hasBootClassPathJars = ai.hasBootClassPathJars;
+                    info.hasDex2OatBootClassPathJars = ai.hasDex2OatBootClassPathJars;
+                    info.hasSystemServerClassPathJars = ai.hasSystemServerClassPathJars;
                     return info;
                 }
             }
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index dab980a..7bea018 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -213,6 +213,7 @@
         NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_CONNECT);
         NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN);
         NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.UWB_RANGING);
+        NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.NEARBY_WIFI_DEVICES);
     }
 
     private static final int MSG_READ_DEFAULT_PERMISSION_EXCEPTIONS = 1;
diff --git a/services/core/java/com/android/server/security/OWNERS b/services/core/java/com/android/server/security/OWNERS
index e6f5826..5c2d5ba 100644
--- a/services/core/java/com/android/server/security/OWNERS
+++ b/services/core/java/com/android/server/security/OWNERS
@@ -1,3 +1,4 @@
 # Bug component: 36824
 
+per-file *AttestationVerification* = file:/core/java/android/security/attestationverification/OWNERS
 per-file FileIntegrityService.java = victorhsieh@google.com
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java
index 6366280..7ffff93 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/ConversionUtil.java
@@ -429,15 +429,7 @@
     private static @NonNull
     HidlMemory parcelFileDescriptorToHidlMemory(@Nullable ParcelFileDescriptor data, int dataSize) {
         if (dataSize > 0) {
-            // Extract a dup of the underlying FileDescriptor out of data.
-            FileDescriptor fd = new FileDescriptor();
-            try {
-                ParcelFileDescriptor dup = data.dup();
-                fd.setInt$(dup.detachFd());
-                return HidlMemoryUtil.fileDescriptorToHidlMemory(fd, dataSize);
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
+            return HidlMemoryUtil.fileDescriptorToHidlMemory(data.getFileDescriptor(), dataSize);
         } else {
             return HidlMemoryUtil.fileDescriptorToHidlMemory(null, 0);
         }
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 61770ea..68b760a 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -29,6 +29,7 @@
 import static android.net.NetworkIdentity.OEM_PRIVATE;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
 import static android.net.NetworkStats.METERED_ALL;
+import static android.net.NetworkStats.METERED_YES;
 import static android.net.NetworkStats.ROAMING_ALL;
 import static android.net.NetworkTemplate.MATCH_ETHERNET;
 import static android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD;
@@ -1340,7 +1341,7 @@
     @Nullable private NetworkStats getUidNetworkStatsSnapshotForTransport(int transport) {
         final NetworkTemplate template = (transport == TRANSPORT_CELLULAR)
                 ? NetworkTemplate.buildTemplateMobileWithRatType(
-                /*subscriptionId=*/null, NETWORK_TYPE_ALL)
+                /*subscriptionId=*/null, NETWORK_TYPE_ALL, METERED_YES)
                 : NetworkTemplate.buildTemplateWifiWildcard();
         return getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false);
     }
@@ -1380,7 +1381,8 @@
         final List<NetworkStatsExt> ret = new ArrayList<>();
         for (final int ratType : getAllCollapsedRatTypes()) {
             final NetworkTemplate template =
-                    buildTemplateMobileWithRatType(subInfo.subscriberId, ratType);
+                    buildTemplateMobileWithRatType(subInfo.subscriberId, ratType,
+                    METERED_YES);
             final NetworkStats stats =
                     getUidNetworkStatsSnapshotForTemplate(template, /*includeTags=*/false);
             if (stats != null) {
@@ -1601,7 +1603,7 @@
 
     int pullBluetoothBytesTransferLocked(int atomTag, List<StatsEvent> pulledData) {
         BluetoothActivityEnergyInfo info = fetchBluetoothData();
-        if (info == null || info.getUidTraffic() == null) {
+        if (info == null) {
             return StatsManager.PULL_SKIP;
         }
         for (UidTraffic traffic : info.getUidTraffic()) {
@@ -2059,7 +2061,7 @@
         if (info == null) {
             return StatsManager.PULL_SKIP;
         }
-        pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, info.getTimeStamp(),
+        pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag, info.getTimestampMillis(),
                 info.getBluetoothStackState(), info.getControllerTxTimeMillis(),
                 info.getControllerRxTimeMillis(), info.getControllerIdleTimeMillis(),
                 info.getControllerEnergyUsed()));
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 92e0845..f57a852 100755
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -1075,17 +1075,22 @@
             }
             if (shouldRecreateAudioPatch) {
                 mCommittedVolume = volume;
-                if (mAudioPatch != null) {
-                    mAudioManager.releaseAudioPatch(mAudioPatch);
-                }
-                mAudioManager.createAudioPatch(
+                // only recreate if  something was updated or audioPath is null
+                if (mAudioPatch == null || sinkUpdated ||sourceUpdated ) {
+                    if (mAudioPatch != null) {
+                        mAudioManager.releaseAudioPatch(mAudioPatch);
+                        audioPatchArray[0] = null;
+                    }
+                    mAudioManager.createAudioPatch(
                         audioPatchArray,
                         new AudioPortConfig[] { sourceConfig },
                         sinkConfigs.toArray(new AudioPortConfig[sinkConfigs.size()]));
-                mAudioPatch = audioPatchArray[0];
-                if (sourceGainConfig != null) {
-                    mAudioManager.setAudioPortGain(mAudioSource, sourceGainConfig);
+                    mAudioPatch = audioPatchArray[0];
                 }
+             }
+
+            if (sourceGainConfig != null) {
+                mAudioManager.setAudioPortGain(mAudioSource, sourceGainConfig);
             }
         }
 
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 7dec4e7..239a916 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -1663,8 +1663,6 @@
                             } /* validationStatusCallback */);
 
             agent.register();
-            agent.setUnderlyingNetworks(
-                    mUnderlying == null ? null : Collections.singletonList(mUnderlying.network));
             agent.markConnected();
 
             return agent;
@@ -2039,6 +2037,7 @@
                         "Unknown transport type or missing TransportInfo/NetworkSpecifier for"
                                 + " non-null underlying network");
             }
+            builder.setUnderlyingNetworks(List.of(underlying.network));
         } else {
             Slog.wtf(
                     TAG,
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 308df2f..bbea094 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1343,13 +1343,7 @@
         }
         final Task rootTask = getRootTask();
 
-        // If we reparent, make sure to remove ourselves from the old animation registry.
-        if (mAnimatingActivityRegistry != null) {
-            mAnimatingActivityRegistry.notifyFinished(this);
-        }
-        mAnimatingActivityRegistry = rootTask != null
-                ? rootTask.getAnimatingActivityRegistry()
-                : null;
+        updateAnimatingActivityRegistry();
 
         if (task == mLastParentBeforePip) {
             // Activity's reparented back from pip, clear the links once established
@@ -1373,6 +1367,20 @@
         }
     }
 
+    void updateAnimatingActivityRegistry() {
+        final Task rootTask = getRootTask();
+        final AnimatingActivityRegistry registry = rootTask != null
+                ? rootTask.getAnimatingActivityRegistry()
+                : null;
+
+        // If we reparent, make sure to remove ourselves from the old animation registry.
+        if (mAnimatingActivityRegistry != null && mAnimatingActivityRegistry != registry) {
+            mAnimatingActivityRegistry.notifyFinished(this);
+        }
+
+        mAnimatingActivityRegistry = registry;
+    }
+
     /**
      * Sets {@link #mLastParentBeforePip} to the current parent Task, it's caller's job to ensure
      * {@link #getTask()} is set before this is called.
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 516be55..9634855 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1464,6 +1464,9 @@
         adjustBoundsForDisplayChangeIfNeeded(getDisplayContent());
 
         mRootWindowContainer.updateUIDsPresentOnDisplay();
+
+        // Ensure all animations are finished at same time in split-screen mode.
+        forAllActivities(ActivityRecord::updateAnimatingActivityRegistry);
     }
 
     void cleanUpActivityReferences(ActivityRecord r) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 5540cc5..4857fb3 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -1547,7 +1547,9 @@
                 // activity as it could lead to incorrect display metrics. For ex, IME services
                 // expect their config to match the config of the display with the IME window
                 // showing.
+                // If the configuration has been overridden by previous activity, empty it.
                 mIsActivityConfigOverrideAllowed = false;
+                unregisterActivityConfigurationListener();
                 break;
             default:
                 break;
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 2722b8d..710a304 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -165,7 +165,7 @@
         "android.hardware.power@1.1",
         "android.hardware.power-V2-cpp",
         "android.hardware.power.stats@1.0",
-        "android.hardware.power.stats-V1-ndk_platform",
+        "android.hardware.power.stats-V1-ndk",
         "android.hardware.thermal@1.0",
         "android.hardware.tv.input@1.0",
         "android.hardware.vibrator-V2-cpp",
@@ -178,7 +178,7 @@
         "android.frameworks.schedulerservice@1.0",
         "android.frameworks.sensorservice@1.0",
         "android.frameworks.stats@1.0",
-        "android.frameworks.stats-V1-ndk_platform",
+        "android.frameworks.stats-V1-ndk",
         "android.system.suspend.control-V1-cpp",
         "android.system.suspend.control.internal-cpp",
         "android.system.suspend-V1-ndk",
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 09a831e..0c3f1dd 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -41,6 +41,7 @@
     sdk_version: "module_current",
     min_sdk_version: "30",
     libs: [
+        "framework-annotations-lib",
         "unsupportedappusage",
         "framework-wifi-util-lib",
         "framework-connectivity",
diff --git a/services/tests/PackageManagerServiceTests/OWNERS b/services/tests/PackageManagerServiceTests/OWNERS
index 182dfe8..86ae581 100644
--- a/services/tests/PackageManagerServiceTests/OWNERS
+++ b/services/tests/PackageManagerServiceTests/OWNERS
@@ -1,3 +1 @@
-chiuwinson@google.com
-patb@google.com
-toddke@google.com
+include /PACKAGE_MANAGER_OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/BatteryServiceTest.java b/services/tests/servicestests/src/com/android/server/BatteryServiceTest.java
index cb12ba7..a2ecbc3 100644
--- a/services/tests/servicestests/src/com/android/server/BatteryServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/BatteryServiceTest.java
@@ -47,7 +47,6 @@
     @Mock BatteryService.HealthServiceWrapper.IHealthSupplier mHealthServiceSupplier;
     BatteryService.HealthServiceWrapper mWrapper;
 
-    private static final String HEALTHD = BatteryService.HealthServiceWrapper.INSTANCE_HEALTHD;
     private static final String VENDOR = BatteryService.HealthServiceWrapper.INSTANCE_VENDOR;
 
     @Override
@@ -117,7 +116,7 @@
 
     @SmallTest
     public void testWrapPreferVendor() throws Exception {
-        initForInstances(VENDOR, HEALTHD);
+        initForInstances(VENDOR);
         mWrapper.init(mCallback, mManagerSupplier, mHealthServiceSupplier);
         waitHandlerThreadFinish();
         verify(mCallback, times(1)).onRegistration(same(null), same(mMockedHal), eq(VENDOR));
@@ -126,16 +125,6 @@
     }
 
     @SmallTest
-    public void testUseHealthd() throws Exception {
-        initForInstances(HEALTHD);
-        mWrapper.init(mCallback, mManagerSupplier, mHealthServiceSupplier);
-        waitHandlerThreadFinish();
-        verify(mCallback, times(1)).onRegistration(same(null), same(mMockedHal), eq(HEALTHD));
-        verify(mCallback, never()).onRegistration(same(mMockedHal), same(mMockedHal), anyString());
-        verify(mCallback, times(1)).onRegistration(same(mMockedHal), same(mMockedHal2), eq(HEALTHD));
-    }
-
-    @SmallTest
     public void testNoService() throws Exception {
         initForInstances("unrelated");
         try {
diff --git a/services/tests/servicestests/src/com/android/server/OWNERS b/services/tests/servicestests/src/com/android/server/OWNERS
index f1402ea..6a7d298 100644
--- a/services/tests/servicestests/src/com/android/server/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/OWNERS
@@ -3,4 +3,5 @@
 per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS
 per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS
 per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
+per-file BatteryServiceTest.java = file:platform/hardware/interfaces:/health/aidl/OWNERS
 per-file GestureLauncherServiceTest.java = file:platform/packages/apps/EmergencyInfo:/OWNERS
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 7f24c36..1579aaf 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -765,6 +765,8 @@
 
             // send a sticky broadcast containing USB accessory handshake information
             Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_HANDSHAKE)
+                    .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+                        | Intent.FLAG_RECEIVER_FOREGROUND)
                     .putExtra(UsbManager.EXTRA_ACCESSORY_UEVENT_TIME,
                             mAccessoryConnectionStartTime)
                     .putExtra(UsbManager.EXTRA_ACCESSORY_STRING_COUNT,
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 73e6c76..d11c667 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1879,6 +1879,20 @@
             "lte_plus_threshold_bandwidth_khz_int";
 
     /**
+     * The combined channel bandwidth threshold (non-inclusive) in KHz required to display the
+     * NR advanced (i.e. 5G+) data icon. It is 0 by default, meaning minimum bandwidth check is
+     * not enabled. Other factors like bands or frequency can also determine whether the NR
+     * advanced data icon is shown or not.
+     *
+     * @see #KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY
+     * @see #KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT
+     *
+     * @hide
+     */
+    public static final String KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT =
+            "nr_advanced_threshold_bandwidth_khz_int";
+
+    /**
      * The string is used to filter redundant string from PLMN Network Name that's supplied by
      * specific carrier.
      *
@@ -3543,6 +3557,17 @@
             "nr_advanced_capable_pco_id_int";
 
     /**
+     * Enabled NR advanced (i.e. 5G+) icon while roaming. The default value is {@code true}, meaming
+     * the same NR advanced logic used for home network will be used for roaming network as well.
+     * Set this to {@code false} will disable NR advanced icon while the device is roaming,
+     * regardless meeting NR advanced criteria or not.
+     *
+     * @hide
+     */
+    public static final String KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL =
+            "enable_nr_advanced_for_roaming_bool";
+
+    /**
      * This configuration allows the framework to use user data communication to detect Idle state,
      * and this is used on the 5G icon.
      *
@@ -5560,6 +5585,7 @@
         sDefaults.putString(KEY_SHOW_CARRIER_DATA_ICON_PATTERN_STRING, "");
         sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true);
         sDefaults.putInt(KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
+        sDefaults.putInt(KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT, 0);
         sDefaults.putIntArray(KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY,
                 new int[]{CARRIER_NR_AVAILABILITY_NSA, CARRIER_NR_AVAILABILITY_SA});
         sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true);
@@ -5655,6 +5681,7 @@
         sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000);
         sDefaults.putIntArray(KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY, new int[0]);
         sDefaults.putInt(KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0);
+        sDefaults.putBoolean(KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL, true);
         sDefaults.putBoolean(KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL, false);
         sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_BOOL, false);
         sDefaults.putBoolean(KEY_UNMETERED_NR_NSA_MMWAVE_BOOL, false);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 255a612..a1bed29 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2945,7 +2945,12 @@
      * currently in use on the device for data transmission.
      *
      * If this object has been created with {@link #createForSubscriptionId}, applies to the given
-     * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * subId. Otherwise, applies to {@link SubscriptionManager#getActiveDataSubscriptionId()}.
+     *
+     * Note: Before {@link SubscriptionManager#getActiveDataSubscriptionId()} was introduced in API
+     * level 30, it was applied to {@link SubscriptionManager#getDefaultDataSubscriptionId()} which
+     * may be different now from {@link SubscriptionManager#getActiveDataSubscriptionId()}, e.g.
+     * when opportunistic network is providing cellular internet connection to the user.
      *
      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index e890acb..9572154 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -36,6 +36,7 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.Executor;
 
 /**
@@ -152,16 +153,9 @@
                     throw new RuntimeException(
                         "Failed to find NetworkScanInfo with id " + message.arg2);
                 }
-                NetworkScanCallback callback = nsi.mCallback;
-                Executor executor = nsi.mExecutor;
-                if (callback == null) {
-                    throw new RuntimeException(
-                        "Failed to find NetworkScanCallback with id " + message.arg2);
-                }
-                if (executor == null) {
-                    throw new RuntimeException(
-                        "Failed to find Executor with id " + message.arg2);
-                }
+
+                final NetworkScanCallback callback = nsi.mCallback;
+                final Executor executor = nsi.mExecutor;
 
                 switch (message.what) {
                     case CALLBACK_RESTRICTED_SCAN_RESULTS:
@@ -246,17 +240,24 @@
             NetworkScanRequest request, Executor executor, NetworkScanCallback callback,
             String callingPackage, @Nullable String callingFeatureId) {
         try {
+            Objects.requireNonNull(request, "Request was null");
+            Objects.requireNonNull(callback, "Callback was null");
+            Objects.requireNonNull(executor, "Executor was null");
             final ITelephony telephony = getITelephony();
             if (telephony == null) return null;
 
-            int scanId = telephony.requestNetworkScan(
-                    subId, request, mMessenger, new Binder(), callingPackage,
-                    callingFeatureId);
-            if (scanId == INVALID_SCAN_ID) {
-                Rlog.e(TAG, "Failed to initiate network scan");
-                return null;
-            }
+            // The lock must be taken before calling requestNetworkScan because the resulting
+            // scanId can be invoked asynchronously on another thread at any time after
+            // requestNetworkScan invoked, leaving a critical section between that call and adding
+            // the record to the ScanInfo cache.
             synchronized (mScanInfo) {
+                int scanId = telephony.requestNetworkScan(
+                        subId, request, mMessenger, new Binder(), callingPackage,
+                        callingFeatureId);
+                if (scanId == INVALID_SCAN_ID) {
+                    Rlog.e(TAG, "Failed to initiate network scan");
+                    return null;
+                }
                 // We link to death whenever a scan is started to ensure that we are linked
                 // at the point that phone process death might matter.
                 // We never unlink because:
diff --git a/tests/DynamicCodeLoggerIntegrationTests/OWNERS b/tests/DynamicCodeLoggerIntegrationTests/OWNERS
new file mode 100644
index 0000000..d9eb141
--- /dev/null
+++ b/tests/DynamicCodeLoggerIntegrationTests/OWNERS
@@ -0,0 +1 @@
+file:/services/core/java/com/android/server/pm/dex/OWNERS
diff --git a/tests/SharedLibraryLoadingTest/Android.bp b/tests/SharedLibraryLoadingTest/Android.bp
new file mode 100644
index 0000000..088278d
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/Android.bp
@@ -0,0 +1,37 @@
+// Copyright (C) 2021 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_test_host {
+    name: "SharedLibraryLoadingTests",
+    libs: [
+        "tradefed",
+        "junit",
+    ],
+    test_suites: ["general-tests"],
+    data: [
+        ":SharedLibraryLoadingTests_StandardSharedLibrary",
+        ":SharedLibraryLoadingTests_SharedLibraryLoadedAfter",
+        ":SharedLibraryLoadingTests_SharedLibraryClientTests",
+        ":SharedLibraryLoadingTests_Overlay",
+    ],
+}
diff --git a/tests/SharedLibraryLoadingTest/AndroidTest.xml b/tests/SharedLibraryLoadingTest/AndroidTest.xml
new file mode 100644
index 0000000..947453d
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/AndroidTest.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<configuration description="Host-driven test module config for SharedLibraryHostTests">
+    <option name="test-tag" value="SharedLibraryLoadingTests" />
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-instrumentation" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="false" />
+        <option name="remount-system" value="true" />
+        <option name="push"
+                value="SharedLibraryLoadingTests_StandardSharedLibrary.apk->/product/app/SharedLibraryLoadingTests_StandardSharedLibrary.apk" />
+        <option name="push"
+                value="SharedLibraryLoadingTests_SharedLibraryLoadedAfter.apk->/product/app/SharedLibraryLoadingTests_SharedLibraryLoadedAfter.apk" />
+        <option name="push"
+                value="SharedLibraryLoadingTests_Overlay.apk->/product/overlay/SharedLibraryLoadingTests_Overlay.apk" />
+    </target_preparer>
+
+    <target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer" />
+
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="SharedLibraryLoadingTests_SharedLibraryClientTests.apk" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+        <option name="package" value="com.android.sharedlibloadingtest.client" />
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/SharedLibraryLoadingTest/OWNERS b/tests/SharedLibraryLoadingTest/OWNERS
new file mode 100644
index 0000000..d7b4569
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/OWNERS
@@ -0,0 +1,2 @@
+stenning@google.com
+
diff --git a/tests/SharedLibraryLoadingTest/test-apps/Overlay/Android.bp b/tests/SharedLibraryLoadingTest/test-apps/Overlay/Android.bp
new file mode 100644
index 0000000..b2f4e89
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/Overlay/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2021 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"],
+}
+
+android_test_helper_app {
+    name: "SharedLibraryLoadingTests_Overlay",
+    platform_apis: true,
+    certificate: "platform",
+    aaptflags: ["--no-resource-removal"],
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/Overlay/AndroidManifest.xml b/tests/SharedLibraryLoadingTest/test-apps/Overlay/AndroidManifest.xml
new file mode 100644
index 0000000..ae2784c
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/Overlay/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.sharedlibloadingtest.overlay">
+    <application android:hasCode="false" />
+    <overlay android:targetPackage="android"
+             android:isStatic="true"
+             android:priority="1"/>
+</manifest>
\ No newline at end of file
diff --git a/tests/SharedLibraryLoadingTest/test-apps/Overlay/res/values/config.xml b/tests/SharedLibraryLoadingTest/test-apps/Overlay/res/values/config.xml
new file mode 100644
index 0000000..15da3db
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/Overlay/res/values/config.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2020 Google Inc.
+ *
+ * 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.
+ */
+-->
+<resources>
+    <string-array name="config_sharedLibrariesLoadedAfterApp" translatable="false">
+        <item>com.android.sharedlibloadingtest.shared_library_after</item>
+    </string-array>
+</resources>
\ No newline at end of file
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/Android.bp b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/Android.bp
new file mode 100644
index 0000000..0d20497
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2021 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test_helper_app {
+    name: "SharedLibraryLoadingTests_SharedLibraryClientTests",
+    srcs: ["**/*.java"],
+    resource_dirs: ["res"],
+    libs: [
+        "SharedLibraryLoadingTests_StandardSharedLibrary",
+        "SharedLibraryLoadingTests_SharedLibraryLoadedAfter",
+        "android.test.base",
+    ],
+    static_libs: [
+        "androidx.test.ext.junit",
+        "androidx.test.rules",
+        "androidx.test.core",
+        "testng",
+    ],
+    platform_apis: true,
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/AndroidManifest.xml b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/AndroidManifest.xml
new file mode 100644
index 0000000..e3a9b9b
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.sharedlibloadingtest.client">
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <uses-library android:name="com.android.sharedlibloadingtest.shared_library"/>
+        <uses-library android:name="com.android.sharedlibloadingtest.shared_library_after"/>
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.sharedlibloadingtest.client"  />
+</manifest>
\ No newline at end of file
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/res/values/values.xml b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/res/values/values.xml
new file mode 100644
index 0000000..5e0544e
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/res/values/values.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<resources>
+    <string name="identical_resource_key">client value</string>
+</resources>
\ No newline at end of file
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/ClientClass.java b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/ClientClass.java
new file mode 100644
index 0000000..e48fb83
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/ClientClass.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sharedlibloadingtest;
+
+public class ClientClass {
+    @Override
+    public String toString() {
+        return "Client Code";
+    }
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/DuplicateClassA.java b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/DuplicateClassA.java
new file mode 100644
index 0000000..4c77155
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/DuplicateClassA.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sharedlibloadingtest;
+
+public class DuplicateClassA {
+    @Override
+    public String toString() {
+        return "Client's Version";
+    }
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/DuplicateClassB.java b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/DuplicateClassB.java
new file mode 100644
index 0000000..86aa6a1
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/DuplicateClassB.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sharedlibloadingtest;
+
+public class DuplicateClassB {
+    @Override
+    public String toString() {
+        return "Client's Version B";
+    }
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/client/SharedLibraryLoadingOrderTest.java b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/client/SharedLibraryLoadingOrderTest.java
new file mode 100644
index 0000000..43bcb1a
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryClientTests/src/com/android/sharedlibloadingtest/client/SharedLibraryLoadingOrderTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sharedlibloadingtest.client;
+
+import static org.testng.Assert.assertEquals;
+
+import android.content.Context;
+import android.content.res.Resources;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.util.Preconditions;
+import com.android.sharedlibloadingtest.ClientClass;
+import com.android.sharedlibloadingtest.DuplicateClassA;
+import com.android.sharedlibloadingtest.DuplicateClassB;
+import com.android.sharedlibloadingtest.SharedClassAfter;
+import com.android.sharedlibloadingtest.StdSharedClass;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.HashSet;
+
+@RunWith(AndroidJUnit4.class)
+public class SharedLibraryLoadingOrderTest {
+
+    @Test
+    public void testLoadingOfStdShareLibsShouldBeFirst() {
+        Preconditions.checkArgument(!getLibsLoadedAfter()
+                .contains("com.android.sharedlibloadingtest.shared_library"));
+        DuplicateClassA clazz = new DuplicateClassA();
+        assertEquals(clazz.toString(), "Standard Shared Lib's Version");
+
+        StdSharedClass stdSharedClass = new StdSharedClass();
+        assertEquals(stdSharedClass.toString(), "Nothing Special Lib");
+
+        ClientClass clientCode = new ClientClass();
+        assertEquals(clientCode.toString(), "Client Code");
+    }
+
+    @Test
+    public void testLoadingOfShareLibsIsAfter() {
+        Preconditions.checkArgument(getLibsLoadedAfter()
+                .contains("com.android.sharedlibloadingtest.shared_library_after"));
+        DuplicateClassB clazz = new DuplicateClassB();
+        assertEquals(clazz.toString(), "Client's Version B");
+
+        SharedClassAfter stdSharedClass = new SharedClassAfter();
+        assertEquals(stdSharedClass.toString(), "Also Nothing Special");
+
+        ClientClass clientCode = new ClientClass();
+        assertEquals(clientCode.toString(), "Client Code");
+    }
+
+    @Test
+    public void testLoadingOfResource() {
+        // aapt compiler gives each lib their own namespace so this test just confirming
+        // the resources can be loaded from the same context object
+        Context context = ApplicationProvider.getApplicationContext();
+        String clientString = context.getResources().getString(R.string.identical_resource_key);
+        assertEquals(clientString, "client value");
+        assertEquals(StdSharedClass.getResString(context), "std lib value");
+        assertEquals(SharedClassAfter.getResString(context), "loaded after value");
+
+    }
+
+    private HashSet<String> getLibsLoadedAfter() {
+        Resources systemR = Resources.getSystem();
+        HashSet<String> libsToLoadAfter = new HashSet<>();
+        Collections.addAll(libsToLoadAfter, systemR.getStringArray(
+                com.android.internal.R.array.config_sharedLibrariesLoadedAfterApp));
+        return libsToLoadAfter;
+    }
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/Android.bp b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/Android.bp
new file mode 100644
index 0000000..db9b3ed
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2021 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"],
+}
+
+android_test_helper_app {
+    name: "SharedLibraryLoadingTests_SharedLibraryLoadedAfter",
+    srcs: ["**/*.java"],
+    resource_dirs: ["res"],
+    sdk_version: "current",
+    aaptflags: ["--shared-lib"],
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/AndroidManifest.xml b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/AndroidManifest.xml
new file mode 100644
index 0000000..efedfcf
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.sharedlibloadingtest.shared_library_after">
+    <application>
+        <library android:name="com.android.sharedlibloadingtest.shared_library_after" />
+    </application>
+</manifest>
\ No newline at end of file
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/res/values/values.xml b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/res/values/values.xml
new file mode 100644
index 0000000..4525944
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/res/values/values.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<resources>
+    <string name="identical_resource_key">loaded after value</string>
+</resources>
\ No newline at end of file
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/src/com/android/sharedlibloadingtest/DuplicateClassB.java b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/src/com/android/sharedlibloadingtest/DuplicateClassB.java
new file mode 100644
index 0000000..1e1f5aa
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/src/com/android/sharedlibloadingtest/DuplicateClassB.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sharedlibloadingtest;
+
+public class DuplicateClassB {
+    @Override
+    public String toString() {
+        return "Loaded After Shared Lib's Version";
+    }
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/src/com/android/sharedlibloadingtest/SharedClassAfter.java b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/src/com/android/sharedlibloadingtest/SharedClassAfter.java
new file mode 100644
index 0000000..9e5b40f
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/SharedLibraryLoadedAfter/src/com/android/sharedlibloadingtest/SharedClassAfter.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sharedlibloadingtest;
+
+import android.content.Context;
+
+import com.android.sharedlibloadingtest.shared_library_after.R;
+
+public class SharedClassAfter {
+    @Override
+    public String toString() {
+        return "Also Nothing Special";
+    }
+
+    public static String getResString(Context context) {
+        return context.getResources().getString(R.string.identical_resource_key);
+    }
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/Android.bp b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/Android.bp
new file mode 100644
index 0000000..50456b0
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/Android.bp
@@ -0,0 +1,30 @@
+// Copyright (C) 2021 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"],
+}
+
+android_test_helper_app {
+    name: "SharedLibraryLoadingTests_StandardSharedLibrary",
+    srcs: ["**/*.java"],
+    resource_dirs: ["res"],
+    sdk_version: "current",
+    aaptflags: ["--shared-lib"],
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/AndroidManifest.xml b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/AndroidManifest.xml
new file mode 100644
index 0000000..f1a079f
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.sharedlibloadingtest.shared_library">
+    <application>
+        <library android:name="com.android.sharedlibloadingtest.shared_library" />
+    </application>
+</manifest>
\ No newline at end of file
diff --git a/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/res/values/values.xml b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/res/values/values.xml
new file mode 100644
index 0000000..941351a
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/res/values/values.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<resources>
+    <string name="identical_resource_key">std lib value</string>
+</resources>
\ No newline at end of file
diff --git a/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/src/com/android/sharedlibloadingtest/DuplicateClassA.java b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/src/com/android/sharedlibloadingtest/DuplicateClassA.java
new file mode 100644
index 0000000..a3874aa
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/src/com/android/sharedlibloadingtest/DuplicateClassA.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sharedlibloadingtest;
+
+public class DuplicateClassA {
+    @Override
+    public String toString() {
+        return "Standard Shared Lib's Version";
+    }
+}
diff --git a/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/src/com/android/sharedlibloadingtest/StdSharedClass.java b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/src/com/android/sharedlibloadingtest/StdSharedClass.java
new file mode 100644
index 0000000..429d65c
--- /dev/null
+++ b/tests/SharedLibraryLoadingTest/test-apps/StandardSharedLibrary/src/com/android/sharedlibloadingtest/StdSharedClass.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.sharedlibloadingtest;
+
+import android.content.Context;
+
+import com.android.sharedlibloadingtest.shared_library.R;
+
+public class StdSharedClass {
+    @Override
+    public String toString() {
+        return "Nothing Special Lib";
+    }
+
+    public static String getResString(Context context) {
+        return context.getResources().getString(R.string.identical_resource_key);
+    }
+}
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index 7a564fc..a5852b5 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -31,6 +31,7 @@
     ],
     test_suites: ["general-tests"],
     java_resources: [
+        ":apex.apexd_test_classpath",
         ":com.android.apex.apkrollback.test_v2",
         ":StagedInstallTestApexV2",
         ":StagedInstallTestApexV2_WrongSha",
@@ -54,6 +55,7 @@
         "cts-install-lib-host",
     ],
     data: [
+        ":apex.apexd_test",
         ":com.android.apex.apkrollback.test_v1",
         ":StagedInstallTestApexV2",
         ":StagedInstallTestApexV2_WrongSha",
diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
index c610641..f0ab63e 100644
--- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java
@@ -74,6 +74,11 @@
             "ApexV2", SHIM_APEX_PACKAGE_NAME, 2, /* isApex= */ true,
             "com.android.apex.cts.shim.v2.apex");
 
+    private static final String TEST_APEX_PACKAGE_NAME = "com.android.apex.test_package";
+    private static final TestApp TEST_APEX_CLASSPATH = new TestApp("TestApex",
+            TEST_APEX_PACKAGE_NAME, 1, /*isApex=*/true,
+            "apex.apexd_test_classpath.apex");
+
     private File mTestStateFile = new File(
             InstrumentationRegistry.getInstrumentation().getContext().getFilesDir(),
             "stagedinstall_state");
@@ -439,11 +444,13 @@
         StagedApexInfo result = getPackageManagerNative().getStagedApexInfo("not found");
         assertThat(result).isNull();
         // Stage an apex
-        int sessionId = Install.single(APEX_V2).setStaged().commit();
+        int sessionId = Install.single(TEST_APEX_CLASSPATH).setStaged().commit();
         waitForSessionReady(sessionId);
         // Query proper module name
-        result = getPackageManagerNative().getStagedApexInfo(SHIM_APEX_PACKAGE_NAME);
-        assertThat(result.moduleName).isEqualTo(SHIM_APEX_PACKAGE_NAME);
+        result = getPackageManagerNative().getStagedApexInfo(TEST_APEX_PACKAGE_NAME);
+        assertThat(result.moduleName).isEqualTo(TEST_APEX_PACKAGE_NAME);
+        assertThat(result.hasBootClassPathJars).isTrue();
+        assertThat(result.hasSystemServerClassPathJars).isTrue();
         InstallUtils.openPackageInstallerSession(sessionId).abandon();
     }
 
diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
index 3102103..cd00783 100644
--- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
+++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java
@@ -61,6 +61,7 @@
     private static final String APEX_WRONG_SHA = "com.android.apex.cts.shim.v2_wrong_sha.apex";
     private static final String APK_A = "TestAppAv1.apk";
     private static final String APK_IN_APEX_TESTAPEX_NAME = "com.android.apex.apkrollback.test";
+    private static final String APEXD_TEST_APEX = "apex.apexd_test.apex";
 
     private static final String TEST_VENDOR_APEX_ALLOW_LIST =
             "/vendor/etc/sysconfig/test-vendor-apex-allow-list.xml";
@@ -480,16 +481,29 @@
 
     @Test
     public void testGetStagedModuleNames() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mHostUtils.isApexUpdateSupported());
+
         runPhase("testGetStagedModuleNames");
     }
 
     @Test
+    @LargeTest
     public void testGetStagedApexInfo() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mHostUtils.isApexUpdateSupported());
+
+        pushTestApex(APEXD_TEST_APEX);
+        getDevice().reboot();
+
         runPhase("testGetStagedApexInfo");
     }
 
     @Test
     public void testStagedApexObserver() throws Exception {
+        assumeTrue("Device does not support updating APEX",
+                mHostUtils.isApexUpdateSupported());
+
         runPhase("testStagedApexObserver");
     }
 
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
index f385113..3b201f9 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
@@ -135,11 +135,12 @@
     }
 
     @Test
-    public void testEncodeRecodeParamsWithIkeOptions() throws Exception {
+    public void testEncodeDecodeParamsWithIkeOptions() throws Exception {
         final IkeSessionParams params =
                 createBuilderMinimum()
                         .addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID)
                         .addIkeOption(IkeSessionParams.IKE_OPTION_MOBIKE)
+                        .addIkeOption(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT)
                         .build();
         verifyPersistableBundleEncodeDecodeIsLossless(params);
     }
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index c9a8947a..937f9dc 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -297,8 +297,6 @@
                         any(),
                         any());
         verify(mNetworkAgent).register();
-        verify(mNetworkAgent)
-                .setUnderlyingNetworks(eq(singletonList(TEST_UNDERLYING_NETWORK_RECORD_1.network)));
         verify(mNetworkAgent).markConnected();
 
         verify(mIpSecSvc)
@@ -313,6 +311,7 @@
         final NetworkCapabilities nc = ncCaptor.getValue();
         assertTrue(nc.hasTransport(TRANSPORT_CELLULAR));
         assertFalse(nc.hasTransport(TRANSPORT_WIFI));
+        assertEquals(List.of(TEST_UNDERLYING_NETWORK_RECORD_1.network), nc.getUnderlyingNetworks());
         for (int cap : mConfig.getAllExposedCapabilities()) {
             assertTrue(nc.hasCapability(cap));
         }
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index a700171..5253c3e 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -61,6 +61,7 @@
 
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 
@@ -116,8 +117,9 @@
         capBuilder.setLinkUpstreamBandwidthKbps(TEST_UPSTREAM_BANDWIDTH);
         capBuilder.setLinkDownstreamBandwidthKbps(TEST_DOWNSTREAM_BANDWIDTH);
         capBuilder.setAdministratorUids(new int[] {TEST_UID});
+        final Network underlyingNetwork = mock(Network.class, CALLS_REAL_METHODS);
         UnderlyingNetworkRecord record = new UnderlyingNetworkRecord(
-                mock(Network.class, CALLS_REAL_METHODS),
+                underlyingNetwork,
                 capBuilder.build(), new LinkProperties(), false);
         final NetworkCapabilities vcnCaps =
                 VcnGatewayConnection.buildNetworkCapabilities(
@@ -128,6 +130,7 @@
         assertTrue(vcnCaps.hasTransport(TRANSPORT_CELLULAR));
         assertTrue(vcnCaps.hasCapability(NET_CAPABILITY_NOT_METERED));
         assertTrue(vcnCaps.hasCapability(NET_CAPABILITY_NOT_ROAMING));
+        assertTrue(vcnCaps.getUnderlyingNetworks().equals(List.of(underlyingNetwork)));
 
         for (int cap : VcnGatewayConnectionConfigTest.EXPOSED_CAPS) {
             if (cap == NET_CAPABILITY_INTERNET || cap == NET_CAPABILITY_DUN) {