Merge changes from topic "revert-2382753-revert-2208281-opengl-matrix-VRTQUTHPDK-IGVJUILFUF"

* changes:
  Revert "Revert "Deprecate setRotateEulerM and replace with setRo..."
  Revert "Revert "Move Matrix operations multiplyMM and MultiplMV ..."
diff --git a/Android.bp b/Android.bp
index 67902b3..0c9b82e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -619,3 +619,12 @@
     "ProtoLibraries.bp",
     "TestProtoLibraries.bp",
 ]
+
+java_api_contribution {
+    name: "api-stubs-docs-non-updatable-public-stubs",
+    api_surface: "public",
+    api_file: "core/api/current.txt",
+    visibility: [
+        "//build/orchestrator/apis",
+    ],
+}
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 48c44c9..fc046fb 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -598,3 +598,12 @@
     ],
     visibility: ["//visibility:public"],
 }
+
+java_api_contribution {
+    name: "frameworks-base-core-api-module-lib-stubs",
+    api_surface: "module-lib",
+    api_file: "core/api/module-lib-current.txt",
+    visibility: [
+        "//build/orchestrator/apis",
+    ],
+}
diff --git a/boot/Android.bp b/boot/Android.bp
index 24ad9de..851294c 100644
--- a/boot/Android.bp
+++ b/boot/Android.bp
@@ -23,6 +23,18 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
+soong_config_module_type {
+    name: "custom_platform_bootclasspath",
+    module_type: "platform_bootclasspath",
+    config_namespace: "AUTO",
+    bool_variables: [
+        "car_bootclasspath_fragment",
+    ],
+    properties: [
+        "fragments",
+    ],
+}
+
 // This module provides access to information Soong has related to the
 // whole platform bootclasspath. Currently, that information is provided solely
 // through configuration but additional information will be added here.
@@ -41,7 +53,7 @@
 //
 // This module needs to be present in the build for the above processing to be
 // done correctly.
-platform_bootclasspath {
+custom_platform_bootclasspath {
     name: "platform-bootclasspath",
 
     // The bootclasspath_fragments that contribute to the platform
@@ -115,17 +127,24 @@
             apex: "com.android.wifi",
             module: "com.android.wifi-bootclasspath-fragment",
         },
-        // only used for auto
-        {
-            apex: "com.android.car.framework",
-            module: "com.android.car.framework-bootclasspath-fragment",
-        },
         {
             apex: "com.android.virt",
             module: "com.android.virt-bootclasspath-fragment",
         },
     ],
 
+    soong_config_variables: {
+        car_bootclasspath_fragment: {
+            fragments: [
+                // only used for auto
+                {
+                    apex: "com.android.car.framework",
+                    module: "com.android.car.framework-bootclasspath-fragment",
+                },
+            ],
+        },
+    },
+
     // Additional information needed by hidden api processing.
     hidden_api: {
         unsupported: [
diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
index 7d80493..26e20f6 100644
--- a/cmds/svc/src/com/android/commands/svc/UsbCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
@@ -29,12 +29,18 @@
 import java.util.function.Consumer;
 import java.util.concurrent.Executor;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class UsbCommand extends Svc.Command {
     public UsbCommand() {
         super("usb");
     }
 
+    /**
+     * Counter for tracking UsbOperation operations.
+     */
+    private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
+
     @Override
     public String shortHelp() {
         return "Control Usb state";
@@ -92,8 +98,10 @@
 
             if ("setFunctions".equals(args[1])) {
                 try {
+                    int operationId = sUsbOperationCount.incrementAndGet();
+                    System.out.println("setCurrentFunctions opId:" + operationId);
                     usbMgr.setCurrentFunctions(UsbManager.usbFunctionsFromString(
-                            args.length >= 3 ? args[2] : ""));
+                            args.length >= 3 ? args[2] : ""), operationId);
                 } catch (RemoteException e) {
                     System.err.println("Error communicating with UsbManager: " + e);
                 }
diff --git a/core/api/current.txt b/core/api/current.txt
index bf12804..4a8f048 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -6024,7 +6024,7 @@
   }
 
   public static class Notification.Action implements android.os.Parcelable {
-    ctor @Deprecated public Notification.Action(int, CharSequence, android.app.PendingIntent);
+    ctor @Deprecated public Notification.Action(int, CharSequence, @Nullable android.app.PendingIntent);
     method public android.app.Notification.Action clone();
     method public int describeContents();
     method public boolean getAllowGeneratedReplies();
@@ -6054,8 +6054,8 @@
   }
 
   public static final class Notification.Action.Builder {
-    ctor @Deprecated public Notification.Action.Builder(int, CharSequence, android.app.PendingIntent);
-    ctor public Notification.Action.Builder(android.graphics.drawable.Icon, CharSequence, android.app.PendingIntent);
+    ctor @Deprecated public Notification.Action.Builder(int, CharSequence, @Nullable android.app.PendingIntent);
+    ctor public Notification.Action.Builder(android.graphics.drawable.Icon, CharSequence, @Nullable android.app.PendingIntent);
     ctor public Notification.Action.Builder(android.app.Notification.Action);
     method @NonNull public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
     method @NonNull public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput);
@@ -7890,6 +7890,7 @@
     method public int getNetworkId();
     method public boolean isEnabled();
     method public boolean isFallbackToDefaultConnectionAllowed();
+    method public boolean shouldBlockNonMatchingNetworks();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.PreferentialNetworkServiceConfig> CREATOR;
     field public static final int PREFERENTIAL_NETWORK_ID_1 = 1; // 0x1
@@ -7907,6 +7908,7 @@
     method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setFallbackToDefaultConnectionAllowed(boolean);
     method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setIncludedUids(@NonNull int[]);
     method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setNetworkId(int);
+    method @NonNull public android.app.admin.PreferentialNetworkServiceConfig.Builder setShouldBlockNonMatchingNetworks(boolean);
   }
 
   public class SecurityLog {
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 8d53959..3a94198 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -120,6 +120,7 @@
     field public static final int GADGET_HAL_V1_0 = 10; // 0xa
     field public static final int GADGET_HAL_V1_1 = 11; // 0xb
     field public static final int GADGET_HAL_V1_2 = 12; // 0xc
+    field public static final int GADGET_HAL_V2_0 = 20; // 0x14
     field public static final int USB_DATA_TRANSFER_RATE_10G = 10240; // 0x2800
     field public static final int USB_DATA_TRANSFER_RATE_20G = 20480; // 0x5000
     field public static final int USB_DATA_TRANSFER_RATE_40G = 40960; // 0xa000
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f320b74..b316b19 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1783,7 +1783,7 @@
          * @deprecated Use {@link android.app.Notification.Action.Builder}.
          */
         @Deprecated
-        public Action(int icon, CharSequence title, PendingIntent intent) {
+        public Action(int icon, CharSequence title, @Nullable PendingIntent intent) {
             this(Icon.createWithResource("", icon), title, intent, new Bundle(), null, true,
                     SEMANTIC_ACTION_NONE, false /* isContextual */, false /* requireAuth */);
         }
@@ -1908,10 +1908,12 @@
              * which may display them in other contexts, for example on a wearable device.
              * @param icon icon to show for this action
              * @param title the title of the action
-             * @param intent the {@link PendingIntent} to fire when users trigger this action
+             * @param intent the {@link PendingIntent} to fire when users trigger this action. May
+             * be null, in which case the action may be rendered in a disabled presentation by the
+             * system UI.
              */
             @Deprecated
-            public Builder(int icon, CharSequence title, PendingIntent intent) {
+            public Builder(int icon, CharSequence title, @Nullable PendingIntent intent) {
                 this(Icon.createWithResource("", icon), title, intent);
             }
 
@@ -1940,9 +1942,11 @@
              *
              * @param icon icon to show for this action
              * @param title the title of the action
-             * @param intent the {@link PendingIntent} to fire when users trigger this action
+             * @param intent the {@link PendingIntent} to fire when users trigger this action. May
+             * be null, in which case the action may be rendered in a disabled presentation by the
+             * system UI.
              */
-            public Builder(Icon icon, CharSequence title, PendingIntent intent) {
+            public Builder(Icon icon, CharSequence title, @Nullable PendingIntent intent) {
                 this(icon, title, intent, new Bundle(), null, true, SEMANTIC_ACTION_NONE, false);
             }
 
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index f2eced3..20869e0 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -47,6 +47,9 @@
 # AppOps
 per-file *AppOp* = file:/core/java/android/permission/OWNERS
 
+# Backup and Restore
+per-file IBackupAgent.aidl = file:/services/backup/OWNERS
+
 # LocaleManager
 per-file *Locale* = file:/services/core/java/com/android/server/locales/OWNERS
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 34c91c3..bfab8c9 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2391,6 +2391,7 @@
      * applied (cross profile intent filters updated). Only usesd for CTS tests.
      * @hide
      */
+    @SuppressLint("ActionValue")
     @TestApi
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_DATA_SHARING_RESTRICTION_APPLIED =
@@ -2401,6 +2402,7 @@
      * has been changed.
      * @hide
      */
+    @SuppressLint("ActionValue")
     @TestApi
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     public static final String ACTION_DEVICE_POLICY_CONSTANTS_CHANGED =
diff --git a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
index 63c9839..1e0d062 100644
--- a/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
+++ b/core/java/android/app/admin/PreferentialNetworkServiceConfig.java
@@ -50,6 +50,7 @@
     final boolean mIsEnabled;
     final int mNetworkId;
     final boolean mAllowFallbackToDefaultConnection;
+    final boolean mShouldBlockNonMatchingNetworks;
     final int[] mIncludedUids;
     final int[] mExcludedUids;
 
@@ -63,6 +64,8 @@
             "preferential_network_service_network_id";
     private static final String TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION =
             "allow_fallback_to_default_connection";
+    private static final String TAG_BLOCK_NON_MATCHING_NETWORKS =
+            "block_non_matching_networks";
     private static final String TAG_INCLUDED_UIDS = "included_uids";
     private static final String TAG_EXCLUDED_UIDS = "excluded_uids";
     private static final String ATTR_VALUE = "value";
@@ -110,10 +113,12 @@
     }
 
     private PreferentialNetworkServiceConfig(boolean isEnabled,
-            boolean allowFallbackToDefaultConnection, int[] includedUids,
+            boolean allowFallbackToDefaultConnection, boolean shouldBlockNonMatchingNetworks,
+            int[] includedUids,
             int[] excludedUids, @PreferentialNetworkPreferenceId int networkId) {
         mIsEnabled = isEnabled;
         mAllowFallbackToDefaultConnection = allowFallbackToDefaultConnection;
+        mShouldBlockNonMatchingNetworks = shouldBlockNonMatchingNetworks;
         mIncludedUids = includedUids;
         mExcludedUids = excludedUids;
         mNetworkId = networkId;
@@ -122,6 +127,7 @@
     private PreferentialNetworkServiceConfig(Parcel in) {
         mIsEnabled = in.readBoolean();
         mAllowFallbackToDefaultConnection = in.readBoolean();
+        mShouldBlockNonMatchingNetworks = in.readBoolean();
         mNetworkId = in.readInt();
         mIncludedUids = in.createIntArray();
         mExcludedUids = in.createIntArray();
@@ -136,9 +142,18 @@
     }
 
     /**
-     * is fallback to default network allowed. This boolean configures whether default connection
-     * (default internet or wifi) should be used or not if a preferential network service
-     * connection is not available.
+     * Whether fallback to the device-wide default network is allowed.
+     *
+     * This boolean configures whether the default connection (e.g. general cell network or wifi)
+     * should be used if no preferential network service connection is available. If true, the
+     * default connection will be used when no preferential service is available. If false, the
+     * UIDs subject to this configuration will have no default network.
+     * Note that while this boolean determines whether the UIDs subject to this configuration have
+     * a default network in the absence of a preferential service, apps can still explicitly decide
+     * to use another network than their default network by requesting them from the system. This
+     * boolean does not determine whether the UIDs are blocked from using such other networks.
+     * See {@link #shouldBlockNonMatchingNetworks()} for that configuration.
+     *
      * @return true if fallback is allowed, else false.
      */
     public boolean isFallbackToDefaultConnectionAllowed() {
@@ -146,6 +161,21 @@
     }
 
     /**
+     * Whether to block UIDs from using other networks than the preferential service.
+     *
+     * Apps can inspect the list of available networks on the device and choose to use multiple
+     * of them concurrently for performance, privacy or other reasons.
+     * This boolean configures whether the concerned UIDs should be blocked from using
+     * networks that do not match the configured preferential network service even if these
+     * networks are otherwise open to all apps.
+     *
+     * @return true if UIDs should be blocked from using the other networks, else false.
+     */
+    public boolean shouldBlockNonMatchingNetworks() {
+        return mShouldBlockNonMatchingNetworks;
+    }
+
+    /**
      * Get the array of uids that are applicable for the profile preference.
      *
      * {@see #getExcludedUids()}
@@ -189,6 +219,7 @@
         return "PreferentialNetworkServiceConfig{"
                 + "mIsEnabled=" + isEnabled()
                 + "mAllowFallbackToDefaultConnection=" + isFallbackToDefaultConnectionAllowed()
+                + "mBlockNonMatchingNetworks=" + shouldBlockNonMatchingNetworks()
                 + "mIncludedUids=" + Arrays.toString(mIncludedUids)
                 + "mExcludedUids=" + Arrays.toString(mExcludedUids)
                 + "mNetworkId=" + mNetworkId
@@ -202,6 +233,7 @@
         final PreferentialNetworkServiceConfig that = (PreferentialNetworkServiceConfig) o;
         return mIsEnabled == that.mIsEnabled
                 && mAllowFallbackToDefaultConnection == that.mAllowFallbackToDefaultConnection
+                && mShouldBlockNonMatchingNetworks == that.mShouldBlockNonMatchingNetworks
                 && mNetworkId == that.mNetworkId
                 && Arrays.equals(mIncludedUids, that.mIncludedUids)
                 && Arrays.equals(mExcludedUids, that.mExcludedUids);
@@ -210,7 +242,8 @@
     @Override
     public int hashCode() {
         return Objects.hash(mIsEnabled, mAllowFallbackToDefaultConnection,
-                Arrays.hashCode(mIncludedUids), Arrays.hashCode(mExcludedUids), mNetworkId);
+                mShouldBlockNonMatchingNetworks, Arrays.hashCode(mIncludedUids),
+                Arrays.hashCode(mExcludedUids), mNetworkId);
     }
 
     /**
@@ -221,6 +254,7 @@
         boolean mIsEnabled = false;
         int mNetworkId = 0;
         boolean mAllowFallbackToDefaultConnection = true;
+        boolean mShouldBlockNonMatchingNetworks = false;
         int[] mIncludedUids = new int[0];
         int[] mExcludedUids = new int[0];
 
@@ -242,10 +276,21 @@
         }
 
         /**
-         * Set whether the default connection should be used as fallback.
-         * This boolean configures whether the default connection (default internet or wifi)
-         * should be used if a preferential network service connection is not available.
-         * Default value is true
+         * Set whether fallback to the device-wide default network is allowed.
+         *
+         * This boolean configures whether the default connection (e.g. general cell network or
+         * wifi) should be used if no preferential network service connection is available. If true,
+         * the default connection will be used when no preferential service is available. If false,
+         * the UIDs subject to this configuration will have no default network.
+         * Note that while this boolean determines whether the UIDs subject to this configuration
+         * have a default network in the absence of a preferential service, apps can still
+         * explicitly decide to use another network than their default network by requesting them
+         * from the system. This boolean does not determine whether the UIDs are blocked from using
+         * such other networks.
+         * Use {@link #setShouldBlockNonMatchingNetworks(boolean)} to specify this.
+         *
+         * The default value is true.
+         *
          * @param allowFallbackToDefaultConnection  true if fallback is allowed else false
          * @return The builder to facilitate chaining.
          */
@@ -258,6 +303,31 @@
         }
 
         /**
+         * Set whether to block UIDs from using other networks than the preferential service.
+         *
+         * Apps can inspect the list of available networks on the device and choose to use multiple
+         * of them concurrently for performance, privacy or other reasons.
+         * This boolean configures whether the concerned UIDs should be blocked from using
+         * networks that do not match the configured preferential network service even if these
+         * networks are otherwise open to all apps.
+         *
+         * The default value is false. This value can only be set to {@code true} if
+         * {@link #setFallbackToDefaultConnectionAllowed(boolean)} is set to {@code false}, because
+         * allowing fallback but blocking it does not make sense. Failure to comply with this
+         * constraint will throw when building the object.
+         *
+         * @param blockNonMatchingNetworks true if UIDs should be blocked from using non-matching
+         *                                 networks.
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public PreferentialNetworkServiceConfig.Builder setShouldBlockNonMatchingNetworks(
+                boolean blockNonMatchingNetworks) {
+            mShouldBlockNonMatchingNetworks = blockNonMatchingNetworks;
+            return this;
+        }
+
+        /**
          * Set the array of uids whose network access will go through this preferential
          * network service.
          * {@see #setExcludedUids(int[])}
@@ -305,8 +375,13 @@
                 throw new IllegalStateException("Both includedUids and excludedUids "
                         + "cannot be nonempty");
             }
+            if (mShouldBlockNonMatchingNetworks && mAllowFallbackToDefaultConnection) {
+                throw new IllegalStateException("A config cannot both allow fallback and "
+                        + "block non-matching networks");
+            }
             return new PreferentialNetworkServiceConfig(mIsEnabled,
-                    mAllowFallbackToDefaultConnection, mIncludedUids, mExcludedUids, mNetworkId);
+                    mAllowFallbackToDefaultConnection, mShouldBlockNonMatchingNetworks,
+                    mIncludedUids, mExcludedUids, mNetworkId);
         }
 
         /**
@@ -331,6 +406,7 @@
     public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
         dest.writeBoolean(mIsEnabled);
         dest.writeBoolean(mAllowFallbackToDefaultConnection);
+        dest.writeBoolean(mShouldBlockNonMatchingNetworks);
         dest.writeInt(mNetworkId);
         dest.writeIntArray(mIncludedUids);
         dest.writeIntArray(mExcludedUids);
@@ -422,6 +498,9 @@
             } else if (TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION.equals(tagDAM)) {
                 resultBuilder.setFallbackToDefaultConnectionAllowed(parser.getAttributeBoolean(
                         null, ATTR_VALUE, true));
+            } else if (TAG_BLOCK_NON_MATCHING_NETWORKS.equals(tagDAM)) {
+                resultBuilder.setShouldBlockNonMatchingNetworks(parser.getAttributeBoolean(
+                        null, ATTR_VALUE, false));
             } else if (TAG_INCLUDED_UIDS.equals(tagDAM)) {
                 resultBuilder.setIncludedUids(readStringListToIntArray(parser, TAG_UID));
             } else if (TAG_EXCLUDED_UIDS.equals(tagDAM)) {
@@ -442,6 +521,8 @@
         writeAttributeValueToXml(out, TAG_NETWORK_ID, getNetworkId());
         writeAttributeValueToXml(out, TAG_ALLOW_FALLBACK_TO_DEFAULT_CONNECTION,
                 isFallbackToDefaultConnectionAllowed());
+        writeAttributeValueToXml(out, TAG_BLOCK_NON_MATCHING_NETWORKS,
+                shouldBlockNonMatchingNetworks());
         writeAttributeValuesToXml(out, TAG_INCLUDED_UIDS, TAG_UID,
                 intArrayToStringList(getIncludedUids()));
         writeAttributeValuesToXml(out, TAG_EXCLUDED_UIDS, TAG_UID,
@@ -459,6 +540,8 @@
         pw.println(mIsEnabled);
         pw.print("allowFallbackToDefaultConnection=");
         pw.println(mAllowFallbackToDefaultConnection);
+        pw.print("blockNonMatchingNetworks=");
+        pw.println(mShouldBlockNonMatchingNetworks);
         pw.print("includedUids=");
         pw.println(mIncludedUids);
         pw.print("excludedUids=");
diff --git a/core/java/android/app/admin/Provisioning_OWNERS b/core/java/android/app/admin/Provisioning_OWNERS
index c59a9dc..2e5c2df 100644
--- a/core/java/android/app/admin/Provisioning_OWNERS
+++ b/core/java/android/app/admin/Provisioning_OWNERS
@@ -1,5 +1,5 @@
 # Assign bugs to android-enterprise-triage@google.com
-petuska@google.com
-nupursn@google.com
-shreyacsingh@google.com
-alexkershaw@google.com #{LAST_RESORT_SUGGESTION}
\ No newline at end of file
+mdb.ae-provisioning-reviews@google.com
+petuska@google.com #{LAST_RESORT_SUGGESTION}
+nupursn@google.com #{LAST_RESORT_SUGGESTION}
+shreyacsingh@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 5a44244..1e147ec 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -111,10 +111,10 @@
     boolean isFunctionEnabled(String function);
 
     /* Sets the current USB function. */
-    void setCurrentFunctions(long functions);
+    void setCurrentFunctions(long functions, int operationId);
 
     /* Compatibility version of setCurrentFunctions(long). */
-    void setCurrentFunction(String function, boolean usbDataUnlocked);
+    void setCurrentFunction(String function, boolean usbDataUnlocked, int operationId);
 
     /* Gets the current USB functions. */
     long getCurrentFunctions();
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 2c38f70..9d672bb 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -38,6 +38,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.hardware.usb.gadget.V1_0.GadgetFunction;
 import android.hardware.usb.gadget.V1_2.UsbSpeed;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
@@ -52,6 +53,7 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.StringJoiner;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * This class allows you to access the state of USB and communicate with USB devices.
@@ -95,7 +97,7 @@
      * If the sticky intent has not been found, that indicates USB is disconnected,
      * USB is not configued, MTP function is enabled, and all the other functions are disabled.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final String ACTION_USB_STATE =
@@ -172,7 +174,7 @@
      * <p>For more information about communicating with USB accessory handshake, refer to
      * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p>
      *
-     * {@hide}
+     * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @SystemApi
@@ -184,7 +186,7 @@
      * Boolean extra indicating whether USB is connected or disconnected.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final String USB_CONNECTED = "connected";
@@ -193,7 +195,7 @@
      * Boolean extra indicating whether USB is connected or disconnected as host.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
      *
-     * {@hide}
+     * @hide
      */
     public static final String USB_HOST_CONNECTED = "host_connected";
 
@@ -201,7 +203,7 @@
      * Boolean extra indicating whether USB is configured.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final String USB_CONFIGURED = "configured";
@@ -212,7 +214,7 @@
      * has explicitly asked for this data to be unlocked.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast.
      *
-     * {@hide}
+     * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public static final String USB_DATA_UNLOCKED = "unlocked";
@@ -221,7 +223,7 @@
      * A placeholder indicating that no USB function is being specified.
      * Used for compatibility with old init scripts to indicate no functions vs. charging function.
      *
-     * {@hide}
+     * @hide
      */
     @UnsupportedAppUsage
     public static final String USB_FUNCTION_NONE = "none";
@@ -230,7 +232,7 @@
      * Name of the adb USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
-     * {@hide}
+     * @hide
      */
     public static final String USB_FUNCTION_ADB = "adb";
 
@@ -238,7 +240,7 @@
      * Name of the RNDIS ethernet USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final String USB_FUNCTION_RNDIS = "rndis";
@@ -247,7 +249,7 @@
      * Name of the MTP USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
-     * {@hide}
+     * @hide
      */
     public static final String USB_FUNCTION_MTP = "mtp";
 
@@ -255,7 +257,7 @@
      * Name of the PTP USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
-     * {@hide}
+     * @hide
      */
     public static final String USB_FUNCTION_PTP = "ptp";
 
@@ -263,7 +265,7 @@
      * Name of the audio source USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
-     * {@hide}
+     * @hide
      */
     public static final String USB_FUNCTION_AUDIO_SOURCE = "audio_source";
 
@@ -271,7 +273,7 @@
      * Name of the MIDI USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
-     * {@hide}
+     * @hide
      */
     public static final String USB_FUNCTION_MIDI = "midi";
 
@@ -279,7 +281,7 @@
      * Name of the Accessory USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
-     * {@hide}
+     * @hide
      */
     public static final String USB_FUNCTION_ACCESSORY = "accessory";
 
@@ -287,7 +289,7 @@
      * Name of the NCM USB function.
      * Used in extras for the {@link #ACTION_USB_STATE} broadcast
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final String USB_FUNCTION_NCM = "ncm";
@@ -295,32 +297,39 @@
     /**
      * Name of Gadget Hal Not Present;
      *
-     * {@hide}
+     * @hide
      */
     public static final String GADGET_HAL_UNKNOWN = "unknown";
 
     /**
      * Name of the USB Gadget Hal Version v1.0;
      *
-     * {@hide}
+     * @hide
      */
     public static final String GADGET_HAL_VERSION_1_0 = "V1_0";
 
     /**
      * Name of the USB Gadget Hal Version v1.1;
      *
-     * {@hide}
+     * @hide
      */
     public static final String GADGET_HAL_VERSION_1_1 = "V1_1";
 
     /**
      * Name of the USB Gadget Hal Version v1.2;
      *
-     * {@hide}
+     * @hide
      */
     public static final String GADGET_HAL_VERSION_1_2 = "V1_2";
 
     /**
+     * Name of the USB Gadget Hal Version v2.0;
+     *
+     * @hide
+     */
+    public static final String GADGET_HAL_VERSION_2_0 = "V2_0";
+
+    /**
      * Name of extra for {@link #ACTION_USB_PORT_CHANGED}
      * containing the {@link UsbPort} object for the port.
      *
@@ -356,7 +365,7 @@
      * This is obtained with SystemClock.elapsedRealtime()
      * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final String EXTRA_ACCESSORY_UEVENT_TIME =
@@ -370,7 +379,7 @@
      * between communicating with USB accessory handshake, refer to
      * <a href="https://source.android.com/devices/accessories/aoa">AOA</a> developer guide.</p>
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final String EXTRA_ACCESSORY_STRING_COUNT =
@@ -380,7 +389,7 @@
      * Boolean extra indicating whether got start accessory or not
      * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final String EXTRA_ACCESSORY_START =
@@ -392,7 +401,7 @@
      * sending {@link #ACTION_USB_ACCESSORY_HANDSHAKE}.
      * Used in extras for {@link #ACTION_USB_ACCESSORY_HANDSHAKE} broadcasts.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final String EXTRA_ACCESSORY_HANDSHAKE_END =
@@ -426,7 +435,7 @@
     /**
      * The Value for USB gadget hal is not presented.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int GADGET_HAL_NOT_SUPPORTED = -1;
@@ -434,7 +443,7 @@
     /**
      * Value for Gadget Hal Version v1.0.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int GADGET_HAL_V1_0 = 10;
@@ -442,7 +451,7 @@
     /**
      * Value for Gadget Hal Version v1.1.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int GADGET_HAL_V1_1 = 11;
@@ -450,15 +459,23 @@
     /**
      * Value for Gadget Hal Version v1.2.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int GADGET_HAL_V1_2 = 12;
 
     /**
+     * Value for Gadget Hal Version v2.0.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int GADGET_HAL_V2_0 = 20;
+
+    /**
      * Value for USB_STATE is not configured.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_DATA_TRANSFER_RATE_UNKNOWN = -1;
@@ -466,7 +483,7 @@
     /**
      * Value for USB Transfer Rate of Low Speed in Mbps (real value is 1.5Mbps).
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_DATA_TRANSFER_RATE_LOW_SPEED = 2;
@@ -474,7 +491,7 @@
     /**
      * Value for USB Transfer Rate of Full Speed in Mbps.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_DATA_TRANSFER_RATE_FULL_SPEED = 12;
@@ -482,7 +499,7 @@
     /**
      * Value for USB Transfer Rate of High Speed in Mbps.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_DATA_TRANSFER_RATE_HIGH_SPEED = 480;
@@ -490,7 +507,7 @@
     /**
      * Value for USB Transfer Rate of Super Speed in Mbps.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_DATA_TRANSFER_RATE_5G = 5 * 1024;
@@ -498,7 +515,7 @@
     /**
      * Value for USB Transfer Rate of 10G.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_DATA_TRANSFER_RATE_10G = 10 * 1024;
@@ -506,7 +523,7 @@
     /**
      * Value for USB Transfer Rate of 20G.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_DATA_TRANSFER_RATE_20G = 20 * 1024;
@@ -514,7 +531,7 @@
     /**
      * Value for USB Transfer Rate of 40G.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_DATA_TRANSFER_RATE_40G = 40 * 1024;
@@ -530,7 +547,7 @@
     /**
      * The Value for USB hal is not presented.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_HAL_NOT_SUPPORTED = -1;
@@ -538,7 +555,7 @@
     /**
      * Value for USB Hal Version v1.0.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_HAL_V1_0 = 10;
@@ -546,7 +563,7 @@
     /**
      * Value for USB Hal Version v1.1.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_HAL_V1_1 = 11;
@@ -554,7 +571,7 @@
     /**
      * Value for USB Hal Version v1.2.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_HAL_V1_2 = 12;
@@ -562,7 +579,7 @@
     /**
      * Value for USB Hal Version v1.3.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final int USB_HAL_V1_3 = 13;
@@ -577,63 +594,63 @@
 
     /**
      * Code for the charging usb function. Passed into {@link #setCurrentFunctions(long)}
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final long FUNCTION_NONE = 0;
 
     /**
      * Code for the mtp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final long FUNCTION_MTP = GadgetFunction.MTP;
 
     /**
      * Code for the ptp usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final long FUNCTION_PTP = GadgetFunction.PTP;
 
     /**
      * Code for the rndis usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final long FUNCTION_RNDIS = GadgetFunction.RNDIS;
 
     /**
      * Code for the midi usb function. Passed as a mask into {@link #setCurrentFunctions(long)}
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final long FUNCTION_MIDI = GadgetFunction.MIDI;
 
     /**
      * Code for the accessory usb function.
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final long FUNCTION_ACCESSORY = GadgetFunction.ACCESSORY;
 
     /**
      * Code for the audio source usb function.
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final long FUNCTION_AUDIO_SOURCE = GadgetFunction.AUDIO_SOURCE;
 
     /**
      * Code for the adb usb function.
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final long FUNCTION_ADB = GadgetFunction.ADB;
 
     /**
      * Code for the ncm source usb function.
-     * {@hide}
+     * @hide
      */
     @SystemApi
     public static final long FUNCTION_NCM = 1 << 10;
@@ -643,6 +660,11 @@
 
     private static final Map<String, Long> FUNCTION_NAME_TO_CODE = new HashMap<>();
 
+    /**
+     * Counter for tracking UsbOperation operations.
+     */
+    private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
+
     static {
         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_MTP, FUNCTION_MTP);
         FUNCTION_NAME_TO_CODE.put(UsbManager.USB_FUNCTION_PTP, FUNCTION_PTP);
@@ -674,6 +696,7 @@
             GADGET_HAL_V1_0,
             GADGET_HAL_V1_1,
             GADGET_HAL_V1_2,
+            GADGET_HAL_V2_0,
     })
     public @interface UsbGadgetHalVersion {}
 
@@ -692,7 +715,7 @@
     private final IUsbManager mService;
 
     /**
-     * {@hide}
+     * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public UsbManager(Context context, IUsbManager service) {
@@ -803,7 +826,7 @@
      * {@link #FUNCTION_PTP} are supported.
      * @return A ParcelFileDescriptor holding the valid fd, or null if the fd was not found.
      *
-     * {@hide}
+     * @hide
      */
     public ParcelFileDescriptor getControlFd(long function) {
         try {
@@ -921,7 +944,7 @@
      * Only system components can call this function.
      * @param device to request permissions for
      *
-     * {@hide}
+     * @hide
      */
     public void grantPermission(UsbDevice device) {
         grantPermission(device, Process.myUid());
@@ -933,7 +956,7 @@
      * @param device to request permissions for
      * @uid uid to give permission
      *
-     * {@hide}
+     * @hide
      */
     public void grantPermission(UsbDevice device, int uid) {
         try {
@@ -949,7 +972,7 @@
      * @param device to request permissions for
      * @param packageName of package to grant permissions
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -974,7 +997,7 @@
      * @param function name of the USB function
      * @return true if the USB function is enabled
      *
-     * {@hide}
+     * @hide
      */
     @Deprecated
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -1006,14 +1029,17 @@
      * @param functions the USB function(s) to set, as a bitwise mask.
      *                  Must satisfy {@link UsbManager#areSettableFunctions}
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.MANAGE_USB)
     public void setCurrentFunctions(@UsbFunctionMode long functions) {
+        int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
         try {
-            mService.setCurrentFunctions(functions);
+            mService.setCurrentFunctions(functions, operationId);
         } catch (RemoteException e) {
+            Log.e(TAG, "setCurrentFunctions: failed to call setCurrentFunctions. functions:"
+                        + functions + ", opId:" + operationId, e);
             throw e.rethrowFromSystemServer();
         }
     }
@@ -1025,14 +1051,17 @@
      * @param functions the USB function(s) to set.
      * @param usbDataUnlocked unused
 
-     * {@hide}
+     * @hide
      */
     @Deprecated
     @UnsupportedAppUsage
     public void setCurrentFunction(String functions, boolean usbDataUnlocked) {
+        int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
         try {
-            mService.setCurrentFunction(functions, usbDataUnlocked);
+            mService.setCurrentFunction(functions, usbDataUnlocked, operationId);
         } catch (RemoteException e) {
+            Log.e(TAG, "setCurrentFunction: failed to call setCurrentFunction. functions:"
+                        + functions + ", opId:" + operationId, e);
             throw e.rethrowFromSystemServer();
         }
     }
@@ -1047,7 +1076,7 @@
      * @return The currently enabled functions, in a bitwise mask.
      * A zero mask indicates that the current function is the charging function.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -1073,7 +1102,7 @@
      * @param functions functions to set, in a bitwise mask.
      *                  Must satisfy {@link UsbManager#areSettableFunctions}
      *
-     * {@hide}
+     * @hide
      */
     public void setScreenUnlockedFunctions(long functions) {
         try {
@@ -1089,7 +1118,7 @@
      * @return The currently set screen enabled functions.
      * A zero mask indicates that the screen unlocked functions feature is not enabled.
      *
-     * {@hide}
+     * @hide
      */
     public long getScreenUnlockedFunctions() {
         try {
@@ -1111,19 +1140,17 @@
      *
      * @return The value of currently USB Bandwidth.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @RequiresPermission(Manifest.permission.MANAGE_USB)
     public int getUsbBandwidthMbps() {
         int usbSpeed;
-
         try {
             usbSpeed = mService.getCurrentUsbSpeed();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
-
         return usbSpeedToBandwidth(usbSpeed);
     }
 
@@ -1135,7 +1162,7 @@
      *
      * @return a integer {@code GADGET_HAL_*} represent hal version.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -1155,7 +1182,7 @@
      *
      * @return a integer {@code USB_HAL_*} represent hal version.
      *
-     * {@hide}
+     * @hide
      */
     @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @RequiresPermission(Manifest.permission.MANAGE_USB)
@@ -1451,7 +1478,7 @@
      * @param usbDeviceConnectionHandler The component to handle usb connections,
      * {@code null} to unset.
      *
-     * {@hide}
+     * @hide
      */
     public void setUsbDeviceConnectionHandler(@Nullable ComponentName usbDeviceConnectionHandler) {
         try {
@@ -1470,7 +1497,7 @@
      *
      * @return Whether the mask is settable.
      *
-     * {@hide}
+     * @hide
      */
     public static boolean areSettableFunctions(long functions) {
         return functions == FUNCTION_NONE
@@ -1484,7 +1511,7 @@
      *
      * @return String representation of given mask
      *
-     * {@hide}
+     * @hide
      */
     public static String usbFunctionsToString(long functions) {
         StringJoiner joiner = new StringJoiner(",");
@@ -1520,7 +1547,7 @@
      *
      * @return A mask of all valid functions in the string
      *
-     * {@hide}
+     * @hide
      */
     public static long usbFunctionsFromString(String functions) {
         if (functions == null || functions.equals(USB_FUNCTION_NONE)) {
@@ -1542,7 +1569,7 @@
      *
      * @return a value of USB bandwidth
      *
-     * {@hide}
+     * @hide
      */
     public static int usbSpeedToBandwidth(int speed) {
         switch (speed) {
@@ -1576,12 +1603,14 @@
      *
      * @return String representation of Usb Gadget Hal Version
      *
-     * {@hide}
+     * @hide
      */
     public static @NonNull String usbGadgetHalVersionToString(int version) {
         String halVersion;
 
-        if (version == GADGET_HAL_V1_2) {
+        if (version == GADGET_HAL_V2_0) {
+            halVersion = GADGET_HAL_VERSION_2_0;
+        } else if (version == GADGET_HAL_V1_2) {
             halVersion = GADGET_HAL_VERSION_1_2;
         } else if (version == GADGET_HAL_V1_1) {
             halVersion = GADGET_HAL_VERSION_1_1;
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index aa56105..0cb7df7 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -358,16 +358,16 @@
      * Return the Linux UID assigned to the process that sent the transaction
      * currently being processed.
      *
-     * Logs WTF if the current thread is not currently
+     * Slog.wtf if the current thread is not currently
      * executing an incoming transaction and the calling identity has not been
      * explicitly set with {@link #clearCallingIdentity()}
      *
      * @hide
      */
-    public static final int getCallingUidOrWtf() {
+    public static final int getCallingUidOrWtf(String message) {
         if (!isDirectlyHandlingTransaction() && !hasExplicitIdentity()) {
-            Log.wtfStack(TAG,
-                    "Thread is not in a binder transaction, "
+            Slog.wtf(TAG,
+                    message + ": Thread is not in a binder transaction, "
                             + "and the calling identity has not been "
                             + "explicitly set with clearCallingIdentity");
         }
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index ac46be7..0c9eaa4 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -4815,5 +4815,12 @@
          * @hide
          */
         public static final String COLUMN_USAGE_SETTING = "usage_setting";
+
+        /**
+         * TelephonyProvider column name for user handle associated with this sim.
+         *
+         * @hide
+         */
+        public static final String COLUMN_USER_HANDLE = "user_handle";
     }
 }
diff --git a/core/java/android/security/net/config/SystemCertificateSource.java b/core/java/android/security/net/config/SystemCertificateSource.java
index 4892312..13f7e5d 100644
--- a/core/java/android/security/net/config/SystemCertificateSource.java
+++ b/core/java/android/security/net/config/SystemCertificateSource.java
@@ -41,7 +41,7 @@
     private static File getDirectory() {
         // TODO(miguelaranda): figure out correct code path.
         File updatable_dir = new File("/apex/com.android.conscrypt/cacerts");
-        if (updatable_dir.exists()) {
+        if (updatable_dir.exists() && !(updatable_dir.list().length == 0)) {
             return updatable_dir;
         }
         return new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts");
diff --git a/core/java/android/security/rkp/IRegistration.aidl b/core/java/android/security/rkp/IRegistration.aidl
index 6522a45..8ec13b9 100644
--- a/core/java/android/security/rkp/IRegistration.aidl
+++ b/core/java/android/security/rkp/IRegistration.aidl
@@ -17,6 +17,7 @@
 package android.security.rkp;
 
 import android.security.rkp.IGetKeyCallback;
+import android.security.rkp.IStoreUpgradedKeyCallback;
 
 /**
  * This interface is associated with the registration of an
@@ -70,16 +71,18 @@
      * mechanism, see the documentation for IKeyMintDevice.upgradeKey.
      *
      * Once a key has been upgraded, the IRegistration where the key is stored
-     * needs to be told about the new blob. After calling storeUpgradedKey,
+     * needs to be told about the new blob. After calling storeUpgradedKeyAsync,
      * getKey will return the new key blob instead of the old one.
      *
      * Note that this function does NOT extend the lifetime of key blobs. The
      * certificate for the key is unchanged, and the key will still expire at
-     * the same time it would have if storeUpgradedKey had never been called.
+     * the same time it would have if storeUpgradedKeyAsync had never been called.
      *
      * @param oldKeyBlob The old key blob to be replaced by {@code newKeyBlob}.
-     *
      * @param newKeyblob The new blob to replace {@code oldKeyBlob}.
+     * @param callback Receives the result of the call. A callback must only
+     * be used with one {@code storeUpgradedKeyAsync} call at a time.
      */
-    void storeUpgradedKey(in byte[] oldKeyBlob, in byte[] newKeyBlob);
+    void storeUpgradedKeyAsync(
+            in byte[] oldKeyBlob, in byte[] newKeyBlob, IStoreUpgradedKeyCallback callback);
 }
diff --git a/core/java/android/security/rkp/IStoreUpgradedKeyCallback.aidl b/core/java/android/security/rkp/IStoreUpgradedKeyCallback.aidl
new file mode 100644
index 0000000..7f72fa0
--- /dev/null
+++ b/core/java/android/security/rkp/IStoreUpgradedKeyCallback.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security.rkp;
+
+/**
+ * Callback interface for storing an upgraded remotely provisioned key blob.
+ * {@link IRegistration}.
+ *
+ * @hide
+ */
+oneway interface IStoreUpgradedKeyCallback {
+    /**
+     * Called in response to {@link IRegistration.storeUpgradedKeyAsync}, indicating
+     * a remotely-provisioned key is available.
+     */
+    void onSuccess();
+
+    /**
+     * Called when an error has occurred while trying to store an upgraded
+     * remotely provisioned key.
+     *
+     * @param error A description of what failed, suitable for logging.
+     */
+    void onError(String error);
+}
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 00b0105..088c001 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -1521,6 +1521,8 @@
             addFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0);
         }
 
+        enableIpSecTunnelMigrationOnVsrUAndAbove();
+
         if (isErofsSupported()) {
             if (isKernelVersionAtLeast(5, 10)) {
                 addFeature(PackageManager.FEATURE_EROFS, 0);
@@ -1534,6 +1536,18 @@
         }
     }
 
+    // This method only enables a new Android feature added in U and will not have impact on app
+    // compatibility
+    @SuppressWarnings("AndroidFrameworkCompatChange")
+    private void enableIpSecTunnelMigrationOnVsrUAndAbove() {
+        final int vsrApi =
+                SystemProperties.getInt(
+                        "ro.vendor.api_level", Build.VERSION.DEVICE_INITIAL_SDK_INT);
+        if (vsrApi > Build.VERSION_CODES.TIRAMISU) {
+            addFeature(PackageManager.FEATURE_IPSEC_TUNNEL_MIGRATION, 0);
+        }
+    }
+
     private void addFeature(String name, int version) {
         FeatureInfo fi = mAvailableFeatures.get(name);
         if (fi == null) {
diff --git a/core/java/com/android/server/backup/OWNERS b/core/java/com/android/server/backup/OWNERS
new file mode 100644
index 0000000..d99779e
--- /dev/null
+++ b/core/java/com/android/server/backup/OWNERS
@@ -0,0 +1 @@
+include /services/backup/OWNERS
diff --git a/core/res/OWNERS b/core/res/OWNERS
index b878189..bce500c 100644
--- a/core/res/OWNERS
+++ b/core/res/OWNERS
@@ -23,8 +23,8 @@
 
 # WindowManager team
 # TODO(262451702): Move WindowManager configs out of config.xml in a separate file
-per-file core/res/res/values/config.xml = file:/services/core/java/com/android/server/wm/OWNERS
-per-file core/res/res/values/symbols.xml = file:/services/core/java/com/android/server/wm/OWNERS
+per-file res/values/config.xml = file:/services/core/java/com/android/server/wm/OWNERS
+per-file res/values/symbols.xml = file:/services/core/java/com/android/server/wm/OWNERS
 
 # Resources finalization
 per-file res/xml/public-staging.xml = file:/tools/aapt2/OWNERS
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 2800e31..404d00a 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -214,6 +214,15 @@
     path: "apex/java",
 }
 
+java_api_contribution {
+    name: "framework-graphics-public-stubs",
+    api_surface: "public",
+    api_file: "api/current.txt",
+    visibility: [
+        "//build/orchestrator/apis",
+    ],
+}
+
 // ------------------------
 // APEX
 // ------------------------
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index d8705a7..5b0c2a2 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -2432,13 +2432,12 @@
             throwExceptionAsNecessary(env, BAD_VALUE);
             return;
         }
-        NativeCryptoInfo cryptoInfo = [env, cryptoInfoObj, size]{
-            if (cryptoInfoObj == nullptr) {
-                return NativeCryptoInfo{size};
-            } else {
-                return NativeCryptoInfo{env, cryptoInfoObj};
-            }
-        }();
+        auto cryptoInfo =
+                cryptoInfoObj ? NativeCryptoInfo{size} : NativeCryptoInfo{env, cryptoInfoObj};
+        if (env->ExceptionCheck()) {
+            // Creation of cryptoInfo failed. Let the exception bubble up.
+            return;
+        }
         err = codec->queueEncryptedLinearBlock(
                 index,
                 memory,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
index 1f72609..a80061e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java
@@ -53,8 +53,8 @@
     static final String PREFIX_BT_SYNC_INTERVAL = "SI:";
     static final String PREFIX_BT_IS_ENCRYPTED = "E:";
     static final String PREFIX_BT_BROADCAST_CODE = "C:";
-    static final String PREFIX_BT_PRESENTATION_DELAY = "D:";
-    static final String PREFIX_BT_SUBGROUPS = "G:";
+    static final String PREFIX_BT_PRESENTATION_DELAY = "PD:";
+    static final String PREFIX_BT_SUBGROUPS = "SG:";
     static final String PREFIX_BT_ANDROID_VERSION = "V:";
 
     // BluetoothLeBroadcastSubgroup
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
index aff9a6e..c61ebc0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
@@ -28,7 +28,9 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -38,6 +40,43 @@
     private static final String METADATA_START = "<";
     private static final String METADATA_END = ">";
     private static final String PATTERN_REGEX = "<(.*?)>";
+    private static final String PATTERN_BT_BROADCAST_METADATA =
+            "T:<(.*?)>;+D:<(.*?)>;+AS:<(.*?)>;+B:<(.*?)>;+SI:<(.*?)>;+E:<(.*?)>;+C:<(.*?)>;"
+                + "+PD:<(.*?)>;+SG:(.*)";
+    private static final String PATTERN_BT_SUBGROUP =
+            "CID:<(.*?)>;+CC:<(.*?);>;+AC:<(.*?);>;+CP:<(.*?)>;+BC:<(.*)>;>;";
+    private static final String PATTERN_BT_CHANNEL = "CI:<(.*?)>;+BCCM:<(.*?);>;";
+
+    /* Index for BluetoothLeBroadcastMetadata */
+    private static int MATCH_INDEX_ADDRESS_TYPE = 1;
+    private static int MATCH_INDEX_DEVICE = 2;
+    private static int MATCH_INDEX_ADVERTISING_SID = 3;
+    private static int MATCH_INDEX_BROADCAST_ID = 4;
+    private static int MATCH_INDEX_SYNC_INTERVAL = 5;
+    private static int MATCH_INDEX_IS_ENCRYPTED = 6;
+    private static int MATCH_INDEX_BROADCAST_CODE = 7;
+    private static int MATCH_INDEX_PRESENTATION_DELAY = 8;
+    private static int MATCH_INDEX_SUBGROUPS = 9;
+
+    /* Index for BluetoothLeBroadcastSubgroup */
+    private static int MATCH_INDEX_CODEC_ID = 1;
+    private static int MATCH_INDEX_CODEC_CONFIG = 2;
+    private static int MATCH_INDEX_AUDIO_CONTENT = 3;
+    private static int MATCH_INDEX_CHANNEL_PREF = 4;
+    private static int MATCH_INDEX_BROADCAST_CHANNEL = 5;
+
+    /* Index for BluetoothLeAudioCodecConfigMetadata */
+    private static int LIST_INDEX_AUDIO_LOCATION = 0;
+    private static int LIST_INDEX_CODEC_CONFIG_RAW_METADATA = 1;
+
+    /* Index for BluetoothLeAudioContentMetadata */
+    private static int LIST_INDEX_PROGRAM_INFO = 0;
+    private static int LIST_INDEX_LANGUAGE = 1;
+    private static int LIST_INDEX_AUDIO_CONTENT_RAW_METADATA = 2;
+
+    /* Index for BluetoothLeBroadcastChannel */
+    private static int MATCH_INDEX_CHANNEL_INDEX = 1;
+    private static int MATCH_INDEX_CHANNEL_CODEC_CONFIG = 2;
 
     private BluetoothLeBroadcastSubgroup mSubgroup;
     private List<BluetoothLeBroadcastSubgroup> mSubgroupList;
@@ -55,17 +94,20 @@
     private byte[] mBroadcastCode;
 
     // BluetoothLeBroadcastSubgroup
-    private long mCodecId;
+    private int mCodecId;
     private BluetoothLeAudioContentMetadata mContentMetadata;
     private BluetoothLeAudioCodecConfigMetadata mConfigMetadata;
-    private BluetoothLeBroadcastChannel mChannel;
+    private Boolean mNoChannelPreference;
+    private List<BluetoothLeBroadcastChannel> mChannel;
 
     // BluetoothLeAudioCodecConfigMetadata
     private long mAudioLocation;
+    private byte[] mCodecConfigMetadata;
 
     // BluetoothLeAudioContentMetadata
     private String mLanguage;
     private String mProgramInfo;
+    private byte[] mAudioContentMetadata;
 
     // BluetoothLeBroadcastChannel
     private boolean mIsSelected;
@@ -135,6 +177,7 @@
         for (BluetoothLeBroadcastSubgroup subgroup: subgroupList) {
             String audioCodec = convertAudioCodecConfigToString(subgroup.getCodecSpecificConfig());
             String audioContent = convertAudioContentToString(subgroup.getContentMetadata());
+            boolean hasChannelPreference = subgroup.hasChannelPreference();
             String channels = convertChannelToString(subgroup.getChannels());
             subgroupString = new StringBuilder()
                     .append(BluetoothBroadcastUtils.PREFIX_BTSG_CODEC_ID)
@@ -146,6 +189,9 @@
                     .append(BluetoothBroadcastUtils.PREFIX_BTSG_AUDIO_CONTENT)
                     .append(METADATA_START).append(audioContent).append(METADATA_END)
                     .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
+                    .append(BluetoothBroadcastUtils.PREFIX_BTSG_CHANNEL_PREF)
+                    .append(METADATA_START).append(hasChannelPreference).append(METADATA_END)
+                    .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
                     .append(BluetoothBroadcastUtils.PREFIX_BTSG_BROADCAST_CHANNEL)
                     .append(METADATA_START).append(channels).append(METADATA_END)
                     .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE)
@@ -211,26 +257,35 @@
         if (DEBUG) {
             Log.d(TAG, "Convert " + qrCodeString + "to BluetoothLeBroadcastMetadata");
         }
-        Pattern pattern = Pattern.compile(PATTERN_REGEX);
+
+        Pattern pattern = Pattern.compile(PATTERN_BT_BROADCAST_METADATA);
         Matcher match = pattern.matcher(qrCodeString);
         if (match.find()) {
-            ArrayList<String> resultList = new ArrayList<>();
-            resultList.add(match.group(1));
-            mSourceAddressType = Integer.parseInt(resultList.get(0));
+            mSourceAddressType = Integer.parseInt(match.group(MATCH_INDEX_ADDRESS_TYPE));
             mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
-                    resultList.get(1));
-            mSourceAdvertisingSid = Integer.parseInt(resultList.get(2));
-            mBroadcastId = Integer.parseInt(resultList.get(3));
-            mPaSyncInterval = Integer.parseInt(resultList.get(4));
-            mIsEncrypted = Boolean.valueOf(resultList.get(5));
-            mBroadcastCode = resultList.get(6).getBytes();
-            mPresentationDelayMicros = Integer.parseInt(resultList.get(7));
-            mSubgroup = convertToSubgroup(resultList.get(8));
+                    match.group(MATCH_INDEX_DEVICE));
+            mSourceAdvertisingSid = Integer.parseInt(match.group(MATCH_INDEX_ADVERTISING_SID));
+            mBroadcastId = Integer.parseInt(match.group(MATCH_INDEX_BROADCAST_ID));
+            mPaSyncInterval = Integer.parseInt(match.group(MATCH_INDEX_SYNC_INTERVAL));
+            mIsEncrypted = Boolean.valueOf(match.group(MATCH_INDEX_IS_ENCRYPTED));
+            mBroadcastCode = match.group(MATCH_INDEX_BROADCAST_CODE).getBytes();
+            mPresentationDelayMicros =
+                  Integer.parseInt(match.group(MATCH_INDEX_PRESENTATION_DELAY));
 
             if (DEBUG) {
-                Log.d(TAG, "Converted qrCodeString result: " + match.group());
+                Log.d(TAG, "Converted qrCodeString result: "
+                        + " ,Type = " + mSourceAddressType
+                        + " ,Device = " + mSourceDevice
+                        + " ,AdSid = " + mSourceAdvertisingSid
+                        + " ,BroadcastId = " + mBroadcastId
+                        + " ,paSync = " + mPaSyncInterval
+                        + " ,encrypted = " + mIsEncrypted
+                        + " ,BroadcastCode = " + Arrays.toString(mBroadcastCode)
+                        + " ,delay = " + mPresentationDelayMicros);
             }
 
+            mSubgroup = convertToSubgroup(match.group(MATCH_INDEX_SUBGROUPS));
+
             return new BluetoothLeBroadcastMetadata.Builder()
                     .setSourceDevice(mSourceDevice, mSourceAddressType)
                     .setSourceAdvertisingSid(mSourceAdvertisingSid)
@@ -254,26 +309,26 @@
         if (DEBUG) {
             Log.d(TAG, "Convert " + subgroupString + "to BluetoothLeBroadcastSubgroup");
         }
-        Pattern pattern = Pattern.compile(PATTERN_REGEX);
+        Pattern pattern = Pattern.compile(PATTERN_BT_SUBGROUP);
         Matcher match = pattern.matcher(subgroupString);
         if (match.find()) {
-            ArrayList<String> resultList = new ArrayList<>();
-            resultList.add(match.group(1));
-            mCodecId = Long.getLong(resultList.get(0));
-            mConfigMetadata = convertToConfigMetadata(resultList.get(1));
-            mContentMetadata = convertToContentMetadata(resultList.get(2));
-            mChannel = convertToChannel(resultList.get(3), mConfigMetadata);
+            mCodecId = Integer.parseInt(match.group(MATCH_INDEX_CODEC_ID));
+            mConfigMetadata = convertToConfigMetadata(match.group(MATCH_INDEX_CODEC_CONFIG));
+            mContentMetadata = convertToContentMetadata(match.group(MATCH_INDEX_AUDIO_CONTENT));
+            mNoChannelPreference = Boolean.valueOf(match.group(MATCH_INDEX_CHANNEL_PREF));
+            mChannel =
+                  convertToChannel(match.group(MATCH_INDEX_BROADCAST_CHANNEL), mConfigMetadata);
 
-            if (DEBUG) {
-                Log.d(TAG, "Converted subgroupString result: " + match.group());
+            BluetoothLeBroadcastSubgroup.Builder subgroupBuilder =
+                    new BluetoothLeBroadcastSubgroup.Builder();
+            subgroupBuilder.setCodecId(mCodecId);
+            subgroupBuilder.setCodecSpecificConfig(mConfigMetadata);
+            subgroupBuilder.setContentMetadata(mContentMetadata);
+
+            for (BluetoothLeBroadcastChannel channel : mChannel) {
+                subgroupBuilder.addChannel(channel);
             }
-
-            return new BluetoothLeBroadcastSubgroup.Builder()
-                    .setCodecId(mCodecId)
-                    .setCodecSpecificConfig(mConfigMetadata)
-                    .setContentMetadata(mContentMetadata)
-                    .addChannel(mChannel)
-                    .build();
+            return subgroupBuilder.build();
         } else {
             if (DEBUG) {
                 Log.d(TAG,
@@ -291,15 +346,17 @@
         }
         Pattern pattern = Pattern.compile(PATTERN_REGEX);
         Matcher match = pattern.matcher(configMetadataString);
-        if (match.find()) {
-            ArrayList<String> resultList = new ArrayList<>();
+        ArrayList<String> resultList = new ArrayList<>();
+        while (match.find()) {
             resultList.add(match.group(1));
-            mAudioLocation = Long.getLong(resultList.get(0));
-
-            if (DEBUG) {
-                Log.d(TAG, "Converted configMetadataString result: " + match.group());
-            }
-
+            Log.d(TAG, "Codec Config match : " + match.group(1));
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Converted configMetadataString result: " + resultList.size());
+        }
+        if (resultList.size() > 0) {
+            mAudioLocation = Long.parseLong(resultList.get(LIST_INDEX_AUDIO_LOCATION));
+            mCodecConfigMetadata = resultList.get(LIST_INDEX_CODEC_CONFIG_RAW_METADATA).getBytes();
             return new BluetoothLeAudioCodecConfigMetadata.Builder()
                     .setAudioLocation(mAudioLocation)
                     .build();
@@ -319,14 +376,25 @@
         }
         Pattern pattern = Pattern.compile(PATTERN_REGEX);
         Matcher match = pattern.matcher(contentMetadataString);
-        if (match.find()) {
-            ArrayList<String> resultList = new ArrayList<>();
+        ArrayList<String> resultList = new ArrayList<>();
+        while (match.find()) {
+            Log.d(TAG, "Audio Content match : " + match.group(1));
             resultList.add(match.group(1));
-            mProgramInfo = resultList.get(0);
-            mLanguage = resultList.get(1);
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Converted contentMetadataString result: " + resultList.size());
+        }
+        if (resultList.size() > 0) {
+            mProgramInfo = resultList.get(LIST_INDEX_PROGRAM_INFO);
+            mLanguage = resultList.get(LIST_INDEX_LANGUAGE);
+            mAudioContentMetadata =
+                  resultList.get(LIST_INDEX_AUDIO_CONTENT_RAW_METADATA).getBytes();
 
-            if (DEBUG) {
-                Log.d(TAG, "Converted contentMetadataString result: " + match.group());
+            /* TODO(b/265253566) : Need to set the default value for language when the user starts
+            *  the broadcast.
+            */
+            if (mLanguage.equals("null")) {
+                mLanguage = "eng";
             }
 
             return new BluetoothLeAudioContentMetadata.Builder()
@@ -342,28 +410,34 @@
         }
     }
 
-    private BluetoothLeBroadcastChannel convertToChannel(String channelString,
+    private List<BluetoothLeBroadcastChannel> convertToChannel(String channelString,
             BluetoothLeAudioCodecConfigMetadata configMetadata) {
         if (DEBUG) {
             Log.d(TAG, "Convert " + channelString + "to BluetoothLeBroadcastChannel");
         }
-        Pattern pattern = Pattern.compile(PATTERN_REGEX);
+        Pattern pattern = Pattern.compile(PATTERN_BT_CHANNEL);
         Matcher match = pattern.matcher(channelString);
-        if (match.find()) {
-            ArrayList<String> resultList = new ArrayList<>();
-            resultList.add(match.group(1));
-            mIsSelected = Boolean.valueOf(resultList.get(0));
-            mChannelIndex = Integer.parseInt(resultList.get(1));
+        Map<Integer, BluetoothLeAudioCodecConfigMetadata> channel =
+                new HashMap<Integer, BluetoothLeAudioCodecConfigMetadata>();
+        while (match.find()) {
+            channel.put(Integer.parseInt(match.group(MATCH_INDEX_CHANNEL_INDEX)),
+                    convertToConfigMetadata(match.group(MATCH_INDEX_CHANNEL_CODEC_CONFIG)));
+        }
 
-            if (DEBUG) {
-                Log.d(TAG, "Converted channelString result: " + match.group());
+        if (channel.size() > 0) {
+            mIsSelected = false;
+            ArrayList<BluetoothLeBroadcastChannel> broadcastChannelList = new ArrayList<>();
+            for (Map.Entry<Integer, BluetoothLeAudioCodecConfigMetadata> entry :
+                    channel.entrySet()) {
+
+                broadcastChannelList.add(
+                        new BluetoothLeBroadcastChannel.Builder()
+                            .setSelected(mIsSelected)
+                            .setChannelIndex(entry.getKey())
+                            .setCodecMetadata(entry.getValue())
+                            .build());
             }
-
-            return new BluetoothLeBroadcastChannel.Builder()
-                    .setSelected(mIsSelected)
-                    .setChannelIndex(mChannelIndex)
-                    .setCodecMetadata(configMetadata)
-                    .build();
+            return broadcastChannelList;
         } else {
             if (DEBUG) {
                 Log.d(TAG,
diff --git a/packages/SystemUI/checks/Android.bp b/packages/SystemUI/checks/Android.bp
index 9671add..29668d1 100644
--- a/packages/SystemUI/checks/Android.bp
+++ b/packages/SystemUI/checks/Android.bp
@@ -37,12 +37,6 @@
 
 java_test_host {
     name: "SystemUILintCheckerTest",
-    // TODO(b/239881504): Since this test was written, Android
-    // Lint was updated, and now includes classes that were
-    // compiled for java 15. The soong build doesn't support
-    // java 15 yet, so we can't compile against "lint". Disable
-    // the test until java 15 is supported.
-    enabled: false,
     srcs: [
         "tests/**/*.kt",
         "tests/**/*.java",
@@ -55,5 +49,19 @@
     ],
     test_options: {
         unit_test: true,
+        tradefed_options: [
+            {
+                // lint bundles in some classes that were built with older versions
+                // of libraries, and no longer load. Since tradefed tries to load
+                // all classes in the jar to look for tests, it crashes loading them.
+                // Exclude these classes from tradefed's search.
+                name: "exclude-paths",
+                value: "org/apache",
+            },
+            {
+                name: "exclude-paths",
+                value: "META-INF",
+            },
+        ],
     },
 }
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 8886f0a..b8ff26e 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -98,7 +98,6 @@
         DeviceConfig.NAMESPACE_STORAGE_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_SURFACE_FLINGER_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_SWCODEC_NATIVE,
-        DeviceConfig.NAMESPACE_TETHERING,
         DeviceConfig.NAMESPACE_VENDOR_SYSTEM_NATIVE,
         DeviceConfig.NAMESPACE_VENDOR_SYSTEM_NATIVE_BOOT,
         DeviceConfig.NAMESPACE_VIRTUALIZATION_FRAMEWORK_NATIVE,
diff --git a/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java b/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
index 868f34b..0e92709 100644
--- a/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
+++ b/services/core/java/com/android/server/security/rkp/RemoteProvisioningRegistration.java
@@ -21,10 +21,12 @@
 import android.os.OutcomeReceiver;
 import android.security.rkp.IGetKeyCallback;
 import android.security.rkp.IRegistration;
+import android.security.rkp.IStoreUpgradedKeyCallback;
 import android.security.rkp.service.RegistrationProxy;
 import android.security.rkp.service.RemotelyProvisionedKey;
 import android.util.Log;
 
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 
@@ -36,8 +38,10 @@
  */
 final class RemoteProvisioningRegistration extends IRegistration.Stub {
     static final String TAG = RemoteProvisioningService.TAG;
-    private final ConcurrentHashMap<IGetKeyCallback, CancellationSignal> mOperations =
+    private final ConcurrentHashMap<IGetKeyCallback, CancellationSignal> mGetKeyOperations =
             new ConcurrentHashMap<>();
+    private final Set<IStoreUpgradedKeyCallback> mStoreUpgradedKeyOperations =
+            ConcurrentHashMap.newKeySet();
     private final RegistrationProxy mRegistration;
     private final Executor mExecutor;
 
@@ -49,7 +53,7 @@
 
         @Override
         public void onResult(RemotelyProvisionedKey result) {
-            mOperations.remove(mCallback);
+            mGetKeyOperations.remove(mCallback);
             Log.i(TAG, "Successfully fetched key for client " + mCallback.hashCode());
             android.security.rkp.RemotelyProvisionedKey parcelable =
                     new android.security.rkp.RemotelyProvisionedKey();
@@ -60,7 +64,7 @@
 
         @Override
         public void onError(Exception e) {
-            mOperations.remove(mCallback);
+            mGetKeyOperations.remove(mCallback);
             if (e instanceof OperationCanceledException) {
                 Log.i(TAG, "Operation cancelled for client " + mCallback.hashCode());
                 wrapCallback(mCallback::onCancel);
@@ -79,7 +83,7 @@
     @Override
     public void getKey(int keyId, IGetKeyCallback callback) {
         CancellationSignal cancellationSignal = new CancellationSignal();
-        if (mOperations.putIfAbsent(callback, cancellationSignal) != null) {
+        if (mGetKeyOperations.putIfAbsent(callback, cancellationSignal) != null) {
             Log.e(TAG, "Client can only request one call at a time " + callback.hashCode());
             throw new IllegalArgumentException(
                     "Callback is already associated with an existing operation: "
@@ -92,14 +96,14 @@
                     new GetKeyReceiver(callback));
         } catch (Exception e) {
             Log.e(TAG, "getKeyAsync threw an exception for client " + callback.hashCode(), e);
-            mOperations.remove(callback);
+            mGetKeyOperations.remove(callback);
             wrapCallback(() -> callback.onError(e.getMessage()));
         }
     }
 
     @Override
     public void cancelGetKey(IGetKeyCallback callback) {
-        CancellationSignal cancellationSignal = mOperations.remove(callback);
+        CancellationSignal cancellationSignal = mGetKeyOperations.remove(callback);
         if (cancellationSignal == null) {
             throw new IllegalArgumentException(
                     "Invalid client in cancelGetKey: " + callback.hashCode());
@@ -110,9 +114,35 @@
     }
 
     @Override
-    public void storeUpgradedKey(byte[] oldKeyBlob, byte[] newKeyBlob) {
-        // TODO(b/262748535)
-        Log.e(TAG, "RegistrationBinder.storeUpgradedKey NOT YET IMPLEMENTED");
+    public void storeUpgradedKeyAsync(byte[] oldKeyBlob, byte[] newKeyBlob,
+            IStoreUpgradedKeyCallback callback) {
+        if (!mStoreUpgradedKeyOperations.add(callback)) {
+            throw new IllegalArgumentException(
+                    "Callback is already associated with an existing operation: "
+                            + callback.hashCode());
+        }
+
+        try {
+            mRegistration.storeUpgradedKeyAsync(oldKeyBlob, newKeyBlob, mExecutor,
+                    new OutcomeReceiver<>() {
+                        @Override
+                        public void onResult(Void result) {
+                            mStoreUpgradedKeyOperations.remove(callback);
+                            wrapCallback(callback::onSuccess);
+                        }
+
+                        @Override
+                        public void onError(Exception e) {
+                            mStoreUpgradedKeyOperations.remove(callback);
+                            wrapCallback(() -> callback.onError(e.getMessage()));
+                        }
+                    });
+        } catch (Exception e) {
+            Log.e(TAG, "storeUpgradedKeyAsync threw an exception for client "
+                    + callback.hashCode(), e);
+            mStoreUpgradedKeyOperations.remove(callback);
+            wrapCallback(() -> callback.onError(e.getMessage()));
+        }
     }
 
     interface CallbackRunner {
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index ec67414..1a3e7d1 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1904,7 +1904,8 @@
     }
 
     boolean shouldSleepActivities() {
-        return false;
+        final Task task = getRootTask();
+        return task != null && task.shouldSleepActivities();
     }
 
     @Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 20d9cce..55fb599 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -136,6 +136,7 @@
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_DEFAULT;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE;
+import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING;
 import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
 import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
 import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
@@ -18330,6 +18331,9 @@
             if (preferentialNetworkServiceConfig.isEnabled()) {
                 if (preferentialNetworkServiceConfig.isFallbackToDefaultConnectionAllowed()) {
                     preferenceBuilder.setPreference(PROFILE_NETWORK_PREFERENCE_ENTERPRISE);
+                } else if (preferentialNetworkServiceConfig.shouldBlockNonMatchingNetworks()) {
+                    preferenceBuilder.setPreference(
+                            PROFILE_NETWORK_PREFERENCE_ENTERPRISE_BLOCKING);
                 } else {
                     preferenceBuilder.setPreference(
                             PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK);
diff --git a/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java b/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
index 470f2be..7b361d3 100644
--- a/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
+++ b/services/tests/RemoteProvisioningServiceTests/src/com/android/server/security/rkp/RemoteProvisioningRegistrationTest.java
@@ -34,7 +34,9 @@
 import android.os.CancellationSignal;
 import android.os.OperationCanceledException;
 import android.os.OutcomeReceiver;
+import android.os.RemoteException;
 import android.security.rkp.IGetKeyCallback;
+import android.security.rkp.IStoreUpgradedKeyCallback;
 import android.security.rkp.service.RegistrationProxy;
 import android.security.rkp.service.RemotelyProvisionedKey;
 
@@ -72,6 +74,12 @@
         return answerVoid(answer);
     }
 
+    // answerVoid wrapper for mocking storeUpgradeKeyAsync.
+    static Answer<Void> answerStoreUpgradedKeyAsync(
+            VoidAnswer4<byte[], byte[], Executor, OutcomeReceiver<Void, Exception>> answer) {
+        return answerVoid(answer);
+    }
+
     // matcher helper, making it easier to match the different key types
     private android.security.rkp.RemotelyProvisionedKey matches(
             RemotelyProvisionedKey expectedKey) {
@@ -178,16 +186,63 @@
 
     @Test
     public void storeUpgradedKeySuccess() throws Exception {
-        // TODO(b/262748535)
+        doAnswer(
+                answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) ->
+                        executor.execute(() -> receiver.onResult(null))))
+                .when(mRegistrationProxy)
+                .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+        IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+        mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+        verify(callback).onSuccess();
+        verifyNoMoreInteractions(callback);
     }
 
     @Test
     public void storeUpgradedKeyFails() throws Exception {
-        // TODO(b/262748535)
+        final String errorString = "this is a failure";
+        doAnswer(
+                answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) ->
+                        executor.execute(() -> receiver.onError(new RemoteException(errorString)))))
+                .when(mRegistrationProxy)
+                .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+        IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+        mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+        verify(callback).onError(errorString);
+        verifyNoMoreInteractions(callback);
     }
 
     @Test
-    public void storeUpgradedCatchesExceptionFromProxy() throws Exception {
-        // TODO(b/262748535)
+    public void storeUpgradedKeyHandlesException() throws Exception {
+        final String errorString = "all aboard the failboat, toot toot";
+        doThrow(new IllegalArgumentException(errorString))
+                .when(mRegistrationProxy)
+                .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+        IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+        mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+        verify(callback).onError(errorString);
+        verifyNoMoreInteractions(callback);
     }
+
+    @Test
+    public void storeUpgradedKeyDuplicateCallback() throws Exception {
+        IStoreUpgradedKeyCallback callback = mock(IStoreUpgradedKeyCallback.class);
+
+        doAnswer(
+                answerStoreUpgradedKeyAsync((oldBlob, newBlob, executor, receiver) -> {
+                    assertThrows(IllegalArgumentException.class,
+                            () -> mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0],
+                                    callback));
+                    executor.execute(() -> receiver.onResult(null));
+                }))
+                .when(mRegistrationProxy)
+                .storeUpgradedKeyAsync(any(), any(), any(), any());
+
+        mRegistration.storeUpgradedKeyAsync(new byte[0], new byte[0], callback);
+        verify(callback).onSuccess();
+        verifyNoMoreInteractions(callback);
+    }
+
 }
diff --git a/services/usb/Android.bp b/services/usb/Android.bp
index 3b50fa4..5716b66 100644
--- a/services/usb/Android.bp
+++ b/services/usb/Android.bp
@@ -29,9 +29,10 @@
         "android.hardware.usb-V1.1-java",
         "android.hardware.usb-V1.2-java",
         "android.hardware.usb-V1.3-java",
-	"android.hardware.usb-V1-java",
+        "android.hardware.usb-V1-java",
         "android.hardware.usb.gadget-V1.0-java",
         "android.hardware.usb.gadget-V1.1-java",
         "android.hardware.usb.gadget-V1.2-java",
+        "android.hardware.usb.gadget-V1-java",
     ],
 }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index d580995..1b92699 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -44,6 +44,7 @@
 import android.debug.AdbNotifications;
 import android.debug.AdbTransportType;
 import android.debug.IAdbTransport;
+import android.hardware.usb.IUsbOperationInternal;
 import android.hardware.usb.ParcelableUsbPort;
 import android.hardware.usb.UsbAccessory;
 import android.hardware.usb.UsbConfiguration;
@@ -54,9 +55,7 @@
 import android.hardware.usb.UsbPort;
 import android.hardware.usb.UsbPortStatus;
 import android.hardware.usb.gadget.V1_0.GadgetFunction;
-import android.hardware.usb.gadget.V1_0.IUsbGadget;
 import android.hardware.usb.gadget.V1_0.Status;
-import android.hardware.usb.gadget.V1_2.IUsbGadgetCallback;
 import android.hardware.usb.gadget.V1_2.UsbSpeed;
 import android.hidl.manager.V1_0.IServiceManager;
 import android.hidl.manager.V1_0.IServiceNotification;
@@ -88,9 +87,12 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.dump.DualDumpOutputStream;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
+import com.android.server.usb.hal.gadget.UsbGadgetHal;
+import com.android.server.usb.hal.gadget.UsbGadgetHalInstance;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
 import java.io.File;
@@ -105,6 +107,7 @@
 import java.util.NoSuchElementException;
 import java.util.Scanner;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * UsbDeviceManager manages USB state in device mode.
@@ -215,6 +218,13 @@
 
     private static UsbDeviceLogger sEventLogger;
 
+    private UsbGadgetHal mUsbGadgetHal;
+
+    /**
+     * Counter for tracking UsbOperation operations.
+     */
+    private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
+
     static {
         sDenyInterfaces = new HashSet<>();
         sDenyInterfaces.add(UsbConstants.USB_CLASS_AUDIO);
@@ -297,15 +307,11 @@
         mHasUsbAccessory = pm.hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
         initRndisAddress();
 
+        int operationId = sUsbOperationCount.incrementAndGet();
         boolean halNotPresent = false;
-        try {
-            IUsbGadget.getService(true);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "USB GADGET HAL present but exception thrown", e);
-        } catch (NoSuchElementException e) {
-            halNotPresent = true;
-            Slog.i(TAG, "USB GADGET HAL not present in the device", e);
-        }
+
+        mUsbGadgetHal = UsbGadgetHalInstance.getInstance(this, null);
+        Slog.d(TAG, "getInstance done");
 
         mControlFds = new HashMap<>();
         FileDescriptor mtpFd = nativeOpenControl(UsbManager.USB_FUNCTION_MTP);
@@ -319,7 +325,7 @@
         }
         mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd);
 
-        if (halNotPresent) {
+        if (mUsbGadgetHal == null) {
             /**
              * Initialze the legacy UsbHandler
              */
@@ -333,6 +339,8 @@
                     alsaManager, permissionManager);
         }
 
+        mHandler.handlerInitDone(operationId);
+
         if (nativeIsStartRequested()) {
             if (DEBUG) Slog.d(TAG, "accessory attached at boot");
             startAccessoryMode();
@@ -454,6 +462,8 @@
     private void startAccessoryMode() {
         if (!mHasUsbAccessory) return;
 
+        int operationId = sUsbOperationCount.incrementAndGet();
+
         mAccessoryStrings = nativeGetAccessoryStrings();
         boolean enableAudio = (nativeGetAudioMode() == AUDIO_MODE_SOURCE);
         // don't start accessory mode if our mandatory strings have not been set
@@ -474,7 +484,7 @@
                     ACCESSORY_REQUEST_TIMEOUT);
             mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_ACCESSORY_HANDSHAKE_TIMEOUT),
                     ACCESSORY_HANDSHAKE_TIMEOUT);
-            setCurrentFunctions(functions);
+            setCurrentFunctions(functions, operationId);
         }
     }
 
@@ -503,6 +513,20 @@
         }
     }
 
+    public static void logAndPrint(int priority, IndentingPrintWriter pw, String msg) {
+        Slog.println(priority, TAG, msg);
+        if (pw != null) {
+            pw.println(msg);
+        }
+    }
+
+    public static void logAndPrintException(IndentingPrintWriter pw, String msg, Exception e) {
+        Slog.e(TAG, msg, e);
+        if (pw != null) {
+            pw.println(msg + e);
+        }
+    }
+
     abstract static class UsbHandler extends Handler {
 
         // current USB state
@@ -605,6 +629,19 @@
             sendMessage(m);
         }
 
+        public boolean sendMessage(int what) {
+            removeMessages(what);
+            Message m = Message.obtain(this, what);
+            return sendMessageDelayed(m,0);
+        }
+
+        public void sendMessage(int what, int operationId) {
+            removeMessages(what);
+            Message m = Message.obtain(this, what);
+            m.arg1 = operationId;
+            sendMessage(m);
+        }
+
         public void sendMessage(int what, Object arg) {
             removeMessages(what);
             Message m = Message.obtain(this, what);
@@ -612,6 +649,22 @@
             sendMessage(m);
         }
 
+        public void sendMessage(int what, Object arg, int operationId) {
+            removeMessages(what);
+            Message m = Message.obtain(this, what);
+            m.obj = arg;
+            m.arg1 = operationId;
+            sendMessage(m);
+        }
+
+        public void sendMessage(int what, boolean arg, int operationId) {
+            removeMessages(what);
+            Message m = Message.obtain(this, what);
+            m.arg1 = (arg ? 1 : 0);
+            m.arg2 = operationId;
+            sendMessage(m);
+        }
+
         public void sendMessage(int what, Object arg, boolean arg1) {
             removeMessages(what);
             Message m = Message.obtain(this, what);
@@ -620,6 +673,15 @@
             sendMessage(m);
         }
 
+        public void sendMessage(int what, long arg, boolean arg1, int operationId) {
+            removeMessages(what);
+            Message m = Message.obtain(this, what);
+            m.obj = arg;
+            m.arg1 = (arg1 ? 1 : 0);
+            m.arg2 = operationId;
+            sendMessage(m);
+        }
+
         public void sendMessage(int what, boolean arg1, boolean arg2) {
             removeMessages(what);
             Message m = Message.obtain(this, what);
@@ -677,7 +739,7 @@
             sendMessageDelayed(msg, HOST_STATE_UPDATE_DELAY);
         }
 
-        private void setAdbEnabled(boolean enable) {
+        private void setAdbEnabled(boolean enable, int operationId) {
             if (DEBUG) Slog.d(TAG, "setAdbEnabled: " + enable);
 
             if (enable) {
@@ -686,7 +748,7 @@
                 setSystemProperty(USB_PERSISTENT_CONFIG_PROPERTY, "");
             }
 
-            setEnabledFunctions(mCurrentFunctions, true);
+            setEnabledFunctions(mCurrentFunctions, true, operationId);
             updateAdbNotification(false);
         }
 
@@ -698,6 +760,8 @@
         private void updateCurrentAccessory() {
             // We are entering accessory mode if we have received a request from the host
             // and the request has not timed out yet.
+            int operationId = sUsbOperationCount.incrementAndGet();
+
             boolean enteringAccessoryMode = hasMessages(MSG_ACCESSORY_MODE_ENTER_TIMEOUT);
 
             if (mConfigured && enteringAccessoryMode) {
@@ -729,18 +793,18 @@
                 }
             } else {
                 if (!enteringAccessoryMode) {
-                    notifyAccessoryModeExit();
+                    notifyAccessoryModeExit(operationId);
                 } else if (DEBUG) {
                     Slog.v(TAG, "Debouncing accessory mode exit");
                 }
             }
         }
 
-        private void notifyAccessoryModeExit() {
+        private void notifyAccessoryModeExit(int operationId) {
             // make sure accessory mode is off
             // and restore default functions
             Slog.d(TAG, "exited USB accessory mode");
-            setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+            setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
 
             if (mCurrentAccessory != null) {
                 if (mBootCompleted) {
@@ -866,8 +930,8 @@
                     mMidiEnabled && mConfigured, mMidiCard, mMidiDevice);
         }
 
-        private void setScreenUnlockedFunctions() {
-            setEnabledFunctions(mScreenUnlockedFunctions, false);
+        private void setScreenUnlockedFunctions(int operationId) {
+            setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
         }
 
         private static class AdbTransport extends IAdbTransport.Stub {
@@ -880,7 +944,8 @@
             @Override
             public void onAdbEnabled(boolean enabled, byte transportType) {
                 if (transportType == AdbTransportType.USB) {
-                    mHandler.sendMessage(MSG_ENABLE_ADB, enabled);
+                    int operationId = sUsbOperationCount.incrementAndGet();
+                    mHandler.sendMessage(MSG_ENABLE_ADB, enabled, operationId);
                 }
             }
         }
@@ -903,6 +968,7 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_UPDATE_STATE:
+                    int operationId = sUsbOperationCount.incrementAndGet();
                     mConnected = (msg.arg1 == 1);
                     mConfigured = (msg.arg2 == 1);
 
@@ -920,9 +986,9 @@
                             // restore defaults when USB is disconnected
                             if (!mScreenLocked
                                     && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
-                                setScreenUnlockedFunctions();
+                                setScreenUnlockedFunctions(operationId);
                             } else {
-                                setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+                                setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
                             }
                         }
                         updateUsbFunctions();
@@ -1026,13 +1092,15 @@
                     updateUsbNotification(false);
                     break;
                 case MSG_ENABLE_ADB:
-                    setAdbEnabled(msg.arg1 == 1);
+                    setAdbEnabled(msg.arg1 == 1, msg.arg2);
                     break;
                 case MSG_SET_CURRENT_FUNCTIONS:
                     long functions = (Long) msg.obj;
-                    setEnabledFunctions(functions, false);
+                    operationId = (int) msg.arg1;
+                    setEnabledFunctions(functions, false, operationId);
                     break;
                 case MSG_SET_SCREEN_UNLOCKED_FUNCTIONS:
+                    operationId = sUsbOperationCount.incrementAndGet();
                     mScreenUnlockedFunctions = (Long) msg.obj;
                     if (mSettings != null) {
                         SharedPreferences.Editor editor = mSettings.edit();
@@ -1043,12 +1111,13 @@
                     }
                     if (!mScreenLocked && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
                         // If the screen is unlocked, also set current functions.
-                        setScreenUnlockedFunctions();
+                        setScreenUnlockedFunctions(operationId);
                     } else {
-                        setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+                        setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
                     }
                     break;
                 case MSG_UPDATE_SCREEN_LOCK:
+                    operationId = sUsbOperationCount.incrementAndGet();
                     if (msg.arg1 == 1 == mScreenLocked) {
                         break;
                     }
@@ -1058,23 +1127,25 @@
                     }
                     if (mScreenLocked) {
                         if (!mConnected) {
-                            setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+                            setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
                         }
                     } else {
                         if (mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE
                                 && mCurrentFunctions == UsbManager.FUNCTION_NONE) {
                             // Set the screen unlocked functions if current function is charging.
-                            setScreenUnlockedFunctions();
+                            setScreenUnlockedFunctions(operationId);
                         }
                     }
                     break;
                 case MSG_UPDATE_USER_RESTRICTIONS:
+                    operationId = sUsbOperationCount.incrementAndGet();
                     // Restart the USB stack if USB transfer is enabled but no longer allowed.
                     if (isUsbDataTransferActive(mCurrentFunctions) && !isUsbTransferAllowed()) {
-                        setEnabledFunctions(UsbManager.FUNCTION_NONE, true);
+                        setEnabledFunctions(UsbManager.FUNCTION_NONE, true, operationId);
                     }
                     break;
                 case MSG_SYSTEM_READY:
+                    operationId = sUsbOperationCount.incrementAndGet();
                     mNotificationManager = (NotificationManager)
                             mContext.getSystemService(Context.NOTIFICATION_SERVICE);
 
@@ -1092,17 +1163,19 @@
                                         NotificationManager.IMPORTANCE_HIGH));
                     }
                     mSystemReady = true;
-                    finishBoot();
+                    finishBoot(operationId);
                     break;
                 case MSG_LOCALE_CHANGED:
                     updateAdbNotification(true);
                     updateUsbNotification(true);
                     break;
                 case MSG_BOOT_COMPLETED:
+                    operationId = sUsbOperationCount.incrementAndGet();
                     mBootCompleted = true;
-                    finishBoot();
+                    finishBoot(operationId);
                     break;
                 case MSG_USER_SWITCHED: {
+                    operationId = sUsbOperationCount.incrementAndGet();
                     if (mCurrentUser != msg.arg1) {
                         if (DEBUG) {
                             Slog.v(TAG, "Current user switched to " + msg.arg1);
@@ -1115,16 +1188,18 @@
                                     mSettings.getString(String.format(Locale.ENGLISH,
                                             UNLOCKED_CONFIG_PREF, mCurrentUser), ""));
                         }
-                        setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+                        setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
                     }
                     break;
                 }
                 case MSG_ACCESSORY_MODE_ENTER_TIMEOUT: {
+                    operationId = sUsbOperationCount.incrementAndGet();
                     if (DEBUG) {
-                        Slog.v(TAG, "Accessory mode enter timeout: " + mConnected);
+                        Slog.v(TAG, "Accessory mode enter timeout: " + mConnected
+                                    + " ,operationId: " + operationId);
                     }
                     if (!mConnected || (mCurrentFunctions & UsbManager.FUNCTION_ACCESSORY) == 0) {
-                        notifyAccessoryModeExit();
+                        notifyAccessoryModeExit(operationId);
                     }
                     break;
                 }
@@ -1147,7 +1222,9 @@
             }
         }
 
-        protected void finishBoot() {
+        public abstract void handlerInitDone(int operationId);
+
+        protected void finishBoot(int operationId) {
             if (mBootCompleted && mCurrentUsbFunctionsReceived && mSystemReady) {
                 if (mPendingBootBroadcast) {
                     updateUsbStateBroadcastIfNeeded(getAppliedFunctions(mCurrentFunctions));
@@ -1155,9 +1232,9 @@
                 }
                 if (!mScreenLocked
                         && mScreenUnlockedFunctions != UsbManager.FUNCTION_NONE) {
-                    setScreenUnlockedFunctions();
+                    setScreenUnlockedFunctions(operationId);
                 } else {
-                    setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+                    setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
                 }
                 if (mCurrentAccessory != null) {
                     mUsbDeviceManager.getCurrentSettings().accessoryAttached(mCurrentAccessory);
@@ -1491,7 +1568,8 @@
         /**
          * Evaluates USB function policies and applies the change accordingly.
          */
-        protected abstract void setEnabledFunctions(long functions, boolean forceRestart);
+        protected abstract void setEnabledFunctions(long functions,
+                boolean forceRestart, int operationId);
 
         public void setAccessoryUEventTime(long accessoryConnectionStartTime) {
             mAccessoryConnectionStartTime = accessoryConnectionStartTime;
@@ -1506,6 +1584,11 @@
             mSendStringCount = 0;
             mStartAccessory = false;
         }
+
+        public abstract void setCurrentUsbFunctionsCb(long functions,
+                    int status, int mRequest, long mFunctions, boolean mChargingFunctions);
+
+        public abstract void getUsbSpeedCb(int speed);
     }
 
     private static final class UsbHandlerLegacy extends UsbHandler {
@@ -1524,6 +1607,11 @@
         private String mCurrentFunctionsStr;
         private boolean mUsbDataUnlocked;
 
+        /**
+         * Keeps track of the latest setCurrentUsbFunctions request number.
+         */
+        private int mCurrentRequest = 0;
+
         UsbHandlerLegacy(Looper looper, Context context, UsbDeviceManager deviceManager,
                 UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) {
             super(looper, context, deviceManager, alsaManager, permissionManager);
@@ -1557,6 +1645,10 @@
             }
         }
 
+        @Override
+        public void handlerInitDone(int operationId) {
+        }
+
         private void readOemUsbOverrideConfig(Context context) {
             String[] configList = context.getResources().getStringArray(
                     com.android.internal.R.array.config_oemUsbModeOverride);
@@ -1659,11 +1751,14 @@
         }
 
         @Override
-        protected void setEnabledFunctions(long usbFunctions, boolean forceRestart) {
+        protected void setEnabledFunctions(long usbFunctions,
+                boolean forceRestart, int operationId) {
             boolean usbDataUnlocked = isUsbDataTransferActive(usbFunctions);
             if (DEBUG) {
-                Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions + ", "
-                        + "forceRestart=" + forceRestart + ", usbDataUnlocked=" + usbDataUnlocked);
+                Slog.d(TAG, "setEnabledFunctions functions=" + usbFunctions +
+                        " ,forceRestart=" + forceRestart +
+                        " ,usbDataUnlocked=" + usbDataUnlocked +
+                        " ,operationId=" + operationId);
             }
 
             if (usbDataUnlocked != mUsbDataUnlocked) {
@@ -1759,7 +1854,6 @@
                     || !mCurrentFunctionsStr.equals(functions)
                     || !mCurrentFunctionsApplied
                     || forceRestart) {
-                Slog.i(TAG, "Setting USB config to " + functions);
                 mCurrentFunctionsStr = functions;
                 mCurrentOemFunctions = oemFunctions;
                 mCurrentFunctionsApplied = false;
@@ -1855,15 +1949,18 @@
             if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
             return true;
         }
+
+        @Override
+        public void setCurrentUsbFunctionsCb(long functions,
+                    int status, int mRequest, long mFunctions, boolean mChargingFunctions){
+        }
+
+        @Override
+        public void getUsbSpeedCb(int speed){
+        }
     }
 
-    private static final class UsbHandlerHal extends UsbHandler {
-
-        /**
-         * Proxy object for the usb gadget hal daemon.
-         */
-        @GuardedBy("mGadgetProxyLock")
-        private IUsbGadget mGadgetProxy;
+    private final class UsbHandlerHal extends UsbHandler {
 
         private final Object mGadgetProxyLock = new Object();
 
@@ -1910,33 +2007,20 @@
         UsbHandlerHal(Looper looper, Context context, UsbDeviceManager deviceManager,
                 UsbAlsaManager alsaManager, UsbPermissionManager permissionManager) {
             super(looper, context, deviceManager, alsaManager, permissionManager);
+            int operationId = sUsbOperationCount.incrementAndGet();
             try {
-                ServiceNotification serviceNotification = new ServiceNotification();
-
-                boolean ret = IServiceManager.getService()
-                        .registerForNotifications(GADGET_HAL_FQ_NAME, "", serviceNotification);
-                if (!ret) {
-                    Slog.e(TAG, "Failed to register usb gadget service start notification");
-                    return;
-                }
 
                 synchronized (mGadgetProxyLock) {
-                    mGadgetProxy = IUsbGadget.getService(true);
-                    mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
-                            USB_GADGET_HAL_DEATH_COOKIE);
                     mCurrentFunctions = UsbManager.FUNCTION_NONE;
                     mCurrentUsbFunctionsRequested = true;
                     mUsbSpeed = UsbSpeed.UNKNOWN;
                     mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_0;
-                    mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback());
+                    updateUsbGadgetHalVersion();
                 }
                 String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim();
                 updateState(state);
-                updateUsbGadgetHalVersion();
             } catch (NoSuchElementException e) {
                 Slog.e(TAG, "Usb gadget hal not found", e);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Usb Gadget hal not responding", e);
             } catch (Exception e) {
                 Slog.e(TAG, "Error initializing UsbHandler", e);
             }
@@ -1949,7 +2033,7 @@
                 if (cookie == USB_GADGET_HAL_DEATH_COOKIE) {
                     Slog.e(TAG, "Usb Gadget hal service died cookie: " + cookie);
                     synchronized (mGadgetProxyLock) {
-                        mGadgetProxy = null;
+                        mUsbGadgetHal = null;
                     }
                 }
             }
@@ -1972,18 +2056,22 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_SET_CHARGING_FUNCTIONS:
-                    setEnabledFunctions(UsbManager.FUNCTION_NONE, false);
+                    int operationId = sUsbOperationCount.incrementAndGet();
+                    setEnabledFunctions(UsbManager.FUNCTION_NONE, false, operationId);
                     break;
                 case MSG_SET_FUNCTIONS_TIMEOUT:
-                    Slog.e(TAG, "Set functions timed out! no reply from usb hal");
+                    operationId = sUsbOperationCount.incrementAndGet();
+                    Slog.e(TAG, "Set functions timed out! no reply from usb hal"
+                                + " ,operationId:" + operationId);
                     if (msg.arg1 != 1) {
                         // Set this since default function may be selected from Developer options
-                        setEnabledFunctions(mScreenUnlockedFunctions, false);
+                        setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
                     }
                     break;
                 case MSG_GET_CURRENT_USB_FUNCTIONS:
                     Slog.i(TAG, "processing MSG_GET_CURRENT_USB_FUNCTIONS");
                     mCurrentUsbFunctionsReceived = true;
+                    operationId = msg.arg2;
 
                     if (mCurrentUsbFunctionsRequested) {
                         Slog.i(TAG, "updating mCurrentFunctions");
@@ -1993,91 +2081,71 @@
                                 "mCurrentFunctions:" + mCurrentFunctions + "applied:" + msg.arg1);
                         mCurrentFunctionsApplied = msg.arg1 == 1;
                     }
-                    finishBoot();
+                    finishBoot(operationId);
                     break;
                 case MSG_FUNCTION_SWITCH_TIMEOUT:
                     /**
                      * Dont force to default when the configuration is already set to default.
                      */
+                    operationId = sUsbOperationCount.incrementAndGet();
                     if (msg.arg1 != 1) {
                         // Set this since default function may be selected from Developer options
-                        setEnabledFunctions(mScreenUnlockedFunctions, false);
+                        setEnabledFunctions(mScreenUnlockedFunctions, false, operationId);
                     }
                     break;
                 case MSG_GADGET_HAL_REGISTERED:
                     boolean preexisting = msg.arg1 == 1;
+                    operationId = sUsbOperationCount.incrementAndGet();
                     synchronized (mGadgetProxyLock) {
                         try {
-                            mGadgetProxy = IUsbGadget.getService();
-                            mGadgetProxy.linkToDeath(new UsbGadgetDeathRecipient(),
-                                    USB_GADGET_HAL_DEATH_COOKIE);
+                            mUsbGadgetHal = UsbGadgetHalInstance.getInstance(mUsbDeviceManager,
+                                    null);
                             if (!mCurrentFunctionsApplied && !preexisting) {
-                                setEnabledFunctions(mCurrentFunctions, false);
+                                setEnabledFunctions(mCurrentFunctions, false, operationId);
                             }
                         } catch (NoSuchElementException e) {
                             Slog.e(TAG, "Usb gadget hal not found", e);
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Usb Gadget hal not responding", e);
                         }
                     }
                     break;
                 case MSG_RESET_USB_GADGET:
                     synchronized (mGadgetProxyLock) {
-                        if (mGadgetProxy == null) {
-                            Slog.e(TAG, "reset Usb Gadget mGadgetProxy is null");
+                        if (mUsbGadgetHal == null) {
+                            Slog.e(TAG, "reset Usb Gadget mUsbGadgetHal is null");
                             break;
                         }
 
                         try {
-                            android.hardware.usb.gadget.V1_1.IUsbGadget gadgetProxy =
-                                    android.hardware.usb.gadget.V1_1.IUsbGadget
-                                            .castFrom(mGadgetProxy);
-                            gadgetProxy.reset();
-                        } catch (RemoteException e) {
+                            mUsbGadgetHal.reset();
+                        } catch (Exception e) {
                             Slog.e(TAG, "reset Usb Gadget failed", e);
                         }
                     }
                     break;
                 case MSG_UPDATE_USB_SPEED:
-                    synchronized (mGadgetProxyLock) {
-                        if (mGadgetProxy == null) {
-                            Slog.e(TAG, "mGadgetProxy is null");
-                            break;
-                        }
+                    operationId = sUsbOperationCount.incrementAndGet();
+                    if (mUsbGadgetHal == null) {
+                        Slog.e(TAG, "mGadgetHal is null, operationId:" + operationId);
+                        break;
+                    }
 
-                        try {
-                            android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy =
-                                    android.hardware.usb.gadget.V1_2.IUsbGadget
-                                            .castFrom(mGadgetProxy);
-                            if (gadgetProxy != null) {
-                                gadgetProxy.getUsbSpeed(new UsbGadgetCallback());
-                            }
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "get UsbSpeed failed", e);
-                        }
+                    try {
+                        mUsbGadgetHal.getUsbSpeed(operationId);
+                    } catch (Exception e) {
+                        Slog.e(TAG, "get UsbSpeed failed", e);
                     }
                     break;
                 case MSG_UPDATE_HAL_VERSION:
-                    synchronized (mGadgetProxyLock) {
-                        if (mGadgetProxy == null) {
-                            Slog.e(TAG, "mGadgetProxy is null");
-                            break;
+                    if (mUsbGadgetHal == null) {
+                        Slog.e(TAG, "mUsbGadgetHal is null");
+                        break;
+                    }
+                    else {
+                        try {
+                            mCurrentGadgetHalVersion = mUsbGadgetHal.getGadgetHalVersion();
+                        } catch (RemoteException e) {
+                            Slog.e(TAG, "update Usb gadget version failed", e);
                         }
-
-                        android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy =
-                                android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy);
-                        if (gadgetProxy == null) {
-                            android.hardware.usb.gadget.V1_1.IUsbGadget gadgetProxyV1By1 =
-                                    android.hardware.usb.gadget.V1_1.IUsbGadget
-                                            .castFrom(mGadgetProxy);
-                            if (gadgetProxyV1By1 == null) {
-                                mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_0;
-                                break;
-                            }
-                            mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_1;
-                            break;
-                        }
-                        mCurrentGadgetHalVersion = UsbManager.GADGET_HAL_V1_2;
                     }
                     break;
                 default:
@@ -2085,56 +2153,31 @@
             }
         }
 
-        private class UsbGadgetCallback extends IUsbGadgetCallback.Stub {
-            int mRequest;
-            long mFunctions;
-            boolean mChargingFunctions;
+        @Override
+        public void setCurrentUsbFunctionsCb(long functions,
+                    int status, int mRequest, long mFunctions, boolean mChargingFunctions) {
 
-            UsbGadgetCallback() {
+            if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT)
+                  || (mFunctions != functions)) {
+                return;
             }
 
-            UsbGadgetCallback(int request, long functions,
-                    boolean chargingFunctions) {
-                mRequest = request;
-                mFunctions = functions;
-                mChargingFunctions = chargingFunctions;
-            }
-
-            @Override
-            public void setCurrentUsbFunctionsCb(long functions,
-                    int status) {
-                /**
-                 * Callback called for a previous setCurrenUsbFunction
-                 */
-                if ((mCurrentRequest != mRequest) || !hasMessages(MSG_SET_FUNCTIONS_TIMEOUT)
-                        || (mFunctions != functions)) {
-                    return;
-                }
-
-                removeMessages(MSG_SET_FUNCTIONS_TIMEOUT);
-                Slog.e(TAG, "notifyCurrentFunction request:" + mRequest + " status:" + status);
-                if (status == Status.SUCCESS) {
-                    mCurrentFunctionsApplied = true;
-                } else if (!mChargingFunctions) {
-                    Slog.e(TAG, "Setting default fuctions");
-                    sendEmptyMessage(MSG_SET_CHARGING_FUNCTIONS);
-                }
-            }
-
-            @Override
-            public void getCurrentUsbFunctionsCb(long functions,
-                    int status) {
-                sendMessage(MSG_GET_CURRENT_USB_FUNCTIONS, functions,
-                        status == Status.FUNCTIONS_APPLIED);
-            }
-
-            @Override
-            public void getUsbSpeedCb(int speed) {
-                mUsbSpeed = speed;
+            removeMessages(MSG_SET_FUNCTIONS_TIMEOUT);
+            Slog.i(TAG, "notifyCurrentFunction request:" + mRequest + " status:" + status);
+            if (status == Status.SUCCESS) {
+                mCurrentFunctionsApplied = true;
+            } else if (!mChargingFunctions) {
+                Slog.e(TAG, "Setting default fuctions");
+                sendEmptyMessage(MSG_SET_CHARGING_FUNCTIONS);
             }
         }
 
-        private void setUsbConfig(long config, boolean chargingFunctions) {
+        @Override
+        public void getUsbSpeedCb(int speed) {
+            mUsbSpeed = speed;
+        }
+
+        private void setUsbConfig(long config, boolean chargingFunctions, int operationId) {
             if (true) Slog.d(TAG, "setUsbConfig(" + config + ") request:" + ++mCurrentRequest);
             /**
              * Cancel any ongoing requests, if present.
@@ -2144,8 +2187,8 @@
             removeMessages(MSG_SET_CHARGING_FUNCTIONS);
 
             synchronized (mGadgetProxyLock) {
-                if (mGadgetProxy == null) {
-                    Slog.e(TAG, "setUsbConfig mGadgetProxy is null");
+                if (mUsbGadgetHal == null) {
+                    Slog.e(TAG, "setUsbConfig mUsbGadgetHal is null");
                     return;
                 }
                 try {
@@ -2162,10 +2205,9 @@
                         LocalServices.getService(AdbManagerInternal.class)
                                 .stopAdbdForTransport(AdbTransportType.USB);
                     }
-                    UsbGadgetCallback usbGadgetCallback = new UsbGadgetCallback(mCurrentRequest,
-                            config, chargingFunctions);
-                    mGadgetProxy.setCurrentUsbFunctions(config, usbGadgetCallback,
-                            SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS);
+                    mUsbGadgetHal.setCurrentUsbFunctions(mCurrentRequest,
+                            config, chargingFunctions,
+                            SET_FUNCTIONS_TIMEOUT_MS - SET_FUNCTIONS_LEEWAY_MS, operationId);
                     sendMessageDelayed(MSG_SET_FUNCTIONS_TIMEOUT, chargingFunctions,
                             SET_FUNCTIONS_TIMEOUT_MS);
                     if (mConnected) {
@@ -2174,17 +2216,19 @@
                                 SET_FUNCTIONS_TIMEOUT_MS + ENUMERATION_TIME_OUT_MS);
                     }
                     if (DEBUG) Slog.d(TAG, "timeout message queued");
-                } catch (RemoteException e) {
+                } catch (Exception e) {//RemoteException e) {
                     Slog.e(TAG, "Remoteexception while calling setCurrentUsbFunctions", e);
                 }
             }
         }
 
         @Override
-        protected void setEnabledFunctions(long functions, boolean forceRestart) {
+        protected void setEnabledFunctions(long functions, boolean forceRestart, int operationId) {
             if (DEBUG) {
-                Slog.d(TAG, "setEnabledFunctions functions=" + functions + ", "
-                        + "forceRestart=" + forceRestart);
+                Slog.d(TAG, "setEnabledFunctionsi " +
+                        "functions=" + functions +
+                        ", forceRestart=" + forceRestart +
+                        ", operationId=" + operationId);
             }
             if (mCurrentGadgetHalVersion < UsbManager.GADGET_HAL_V1_2) {
                 if ((functions & UsbManager.FUNCTION_NCM) != 0) {
@@ -2205,7 +2249,7 @@
                 functions = getAppliedFunctions(functions);
 
                 // Set the new USB configuration.
-                setUsbConfig(functions, chargingFunctions);
+                setUsbConfig(functions, chargingFunctions, operationId);
 
                 if (mBootCompleted && isUsbDataTransferActive(functions)) {
                     // Start up dependent services.
@@ -2213,6 +2257,11 @@
                 }
             }
         }
+
+        @Override
+        public void handlerInitDone(int operationId) {
+            mUsbGadgetHal.getCurrentUsbFunctions(operationId);
+        }
     }
 
     /* returns the currently attached USB accessory */
@@ -2254,6 +2303,21 @@
         return mHandler.getGadgetHalVersion();
     }
 
+    public void setCurrentUsbFunctionsCb(long functions,
+                    int status, int mRequest, long mFunctions, boolean mChargingFunctions) {
+        mHandler.setCurrentUsbFunctionsCb(functions, status,
+                    mRequest, mFunctions, mChargingFunctions);
+    }
+
+    public void getCurrentUsbFunctionsCb(long functions, int status) {
+        mHandler.sendMessage(MSG_GET_CURRENT_USB_FUNCTIONS, functions,
+                    status == Status.FUNCTIONS_APPLIED);
+    }
+
+    public void getUsbSpeedCb(int speed) {
+        mHandler.getUsbSpeedCb(speed);
+    }
+
     /**
      * Returns a dup of the control file descriptor for the given function.
      */
@@ -2279,7 +2343,7 @@
      *
      * @param functions The functions to set, or empty to set the charging function.
      */
-    public void setCurrentFunctions(long functions) {
+    public void setCurrentFunctions(long functions, int operationId) {
         if (DEBUG) {
             Slog.d(TAG, "setCurrentFunctions(" + UsbManager.usbFunctionsToString(functions) + ")");
         }
@@ -2296,7 +2360,7 @@
         } else if (functions == UsbManager.FUNCTION_ACCESSORY) {
             MetricsLogger.action(mContext, MetricsEvent.ACTION_USB_CONFIG_ACCESSORY);
         }
-        mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions);
+        mHandler.sendMessage(MSG_SET_CURRENT_FUNCTIONS, functions, operationId);
     }
 
     /**
@@ -2324,7 +2388,8 @@
     }
 
     private void onAdbEnabled(boolean enabled) {
-        mHandler.sendMessage(MSG_ENABLE_ADB, enabled);
+        int operationId = sUsbOperationCount.incrementAndGet();
+        mHandler.sendMessage(MSG_ENABLE_ADB, enabled, operationId);
     }
 
     /**
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 86f877f..6e0d799 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -605,16 +605,16 @@
     }
 
     @Override
-    public void setCurrentFunctions(long functions) {
+    public void setCurrentFunctions(long functions, int operationId) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
         Preconditions.checkArgument(UsbManager.areSettableFunctions(functions));
         Preconditions.checkState(mDeviceManager != null);
-        mDeviceManager.setCurrentFunctions(functions);
+        mDeviceManager.setCurrentFunctions(functions, operationId);
     }
 
     @Override
-    public void setCurrentFunction(String functions, boolean usbDataUnlocked) {
-        setCurrentFunctions(UsbManager.usbFunctionsFromString(functions));
+    public void setCurrentFunction(String functions, boolean usbDataUnlocked, int operationId) {
+        setCurrentFunctions(UsbManager.usbFunctionsFromString(functions), operationId);
     }
 
     @Override
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
new file mode 100644
index 0000000..bdfe60a
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetAidl.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.hal.gadget;
+
+import static android.hardware.usb.UsbManager.GADGET_HAL_V2_0;
+
+import static com.android.server.usb.UsbDeviceManager.logAndPrint;
+import static com.android.server.usb.UsbDeviceManager.logAndPrintException;
+
+import android.annotation.Nullable;
+import android.hardware.usb.gadget.IUsbGadget;
+import android.hardware.usb.gadget.IUsbGadgetCallback;
+import android.hardware.usb.UsbManager.UsbGadgetHalVersion;
+import android.os.ServiceManager;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.UsbDeviceManager;
+
+import java.util.ArrayList;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+
+/**
+ * Implements the methods to interact with AIDL USB HAL.
+ */
+public final class UsbGadgetAidl implements UsbGadgetHal {
+    private static final String TAG = UsbGadgetAidl.class.getSimpleName();
+    private static final String USB_GADGET_AIDL_SERVICE = IUsbGadget.DESCRIPTOR + "/default";
+    // Proxy object for the usb gadget hal daemon.
+    @GuardedBy("mGadgetProxyLock")
+    private IUsbGadget mGadgetProxy;
+    private final UsbDeviceManager mDeviceManager;
+    public final IndentingPrintWriter mPw;
+    // Mutex for all mutable shared state.
+    private final Object mGadgetProxyLock = new Object();
+    // Callback when the UsbDevice status is changed by the kernel.
+    private UsbGadgetCallback mUsbGadgetCallback;
+
+    public @UsbGadgetHalVersion int getGadgetHalVersion() throws RemoteException {
+        synchronized (mGadgetProxyLock) {
+            if (mGadgetProxy == null) {
+                throw new RemoteException("IUsb not initialized yet");
+            }
+        }
+        Slog.i(TAG, "USB Gadget HAL AIDL version: GADGET_HAL_V2_0");
+        return GADGET_HAL_V2_0;
+    }
+
+    @Override
+    public void systemReady() {
+    }
+
+    public void serviceDied() {
+        logAndPrint(Log.ERROR, mPw, "Usb Gadget AIDL hal service died");
+        synchronized (mGadgetProxyLock) {
+            mGadgetProxy = null;
+        }
+        connectToProxy(null);
+    }
+
+    private void connectToProxy(IndentingPrintWriter pw) {
+        synchronized (mGadgetProxyLock) {
+            if (mGadgetProxy != null) {
+                return;
+            }
+
+            try {
+                mGadgetProxy = IUsbGadget.Stub.asInterface(
+                        ServiceManager.waitForService(USB_GADGET_AIDL_SERVICE));
+            } catch (NoSuchElementException e) {
+                logAndPrintException(pw, "connectToProxy: usb gadget hal service not found."
+                        + " Did the service fail to start?", e);
+            }
+        }
+    }
+
+    static boolean isServicePresent(IndentingPrintWriter pw) {
+        try {
+            return ServiceManager.isDeclared(USB_GADGET_AIDL_SERVICE);
+        } catch (NoSuchElementException e) {
+            logAndPrintException(pw, "connectToProxy: usb gadget Aidl hal service not found.", e);
+        }
+
+        return false;
+    }
+
+    public UsbGadgetAidl(UsbDeviceManager deviceManager, IndentingPrintWriter pw) {
+        mDeviceManager = Objects.requireNonNull(deviceManager);
+        mPw = pw;
+        connectToProxy(mPw);
+    }
+
+    @Override
+    public void getCurrentUsbFunctions(long operationId) {
+        synchronized (mGadgetProxyLock) {
+            try {
+                mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback(), operationId);
+            } catch (RemoteException e) {
+                logAndPrintException(mPw,
+                        "RemoteException while calling getCurrentUsbFunctions"
+                        + ", opID:" + operationId, e);
+                return;
+            }
+        }
+    }
+
+    @Override
+    public void getUsbSpeed(long operationId) {
+        try {
+            synchronized (mGadgetProxyLock) {
+                mGadgetProxy.getUsbSpeed(new UsbGadgetCallback(), operationId);
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(mPw,
+                    "RemoteException while calling getUsbSpeed"
+                    + ", opID:" + operationId, e);
+            return;
+        }
+    }
+
+    @Override
+    public void reset() {
+        try {
+            synchronized (mGadgetProxyLock) {
+                mGadgetProxy.reset();
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(mPw,
+                    "RemoteException while calling getUsbSpeed", e);
+            return;
+        }
+    }
+
+    @Override
+    public void setCurrentUsbFunctions(int mRequest, long mFunctions,
+            boolean mChargingFunctions, int timeout, long operationId) {
+        try {
+            mUsbGadgetCallback = new UsbGadgetCallback(mRequest,
+                                      mFunctions, mChargingFunctions);
+            synchronized (mGadgetProxyLock) {
+                mGadgetProxy.setCurrentUsbFunctions(mFunctions, mUsbGadgetCallback,
+                        timeout, operationId);
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(mPw,
+                    "RemoteException while calling setCurrentUsbFunctions: "
+                    + "mRequest=" + mRequest
+                    + ", mFunctions=" + mFunctions
+                    + ", mChargingFunctions=" + mChargingFunctions
+                    + ", timeout=" + timeout
+                    + ", opID:" + operationId, e);
+            return;
+        }
+    }
+
+    private class UsbGadgetCallback extends IUsbGadgetCallback.Stub {
+        public int mRequest;
+        public long mFunctions;
+        public boolean mChargingFunctions;
+
+        UsbGadgetCallback() {
+        }
+
+        UsbGadgetCallback(int request, long functions,
+                boolean chargingFunctions) {
+            mRequest = request;
+            mFunctions = functions;
+            mChargingFunctions = chargingFunctions;
+        }
+
+        @Override
+        public void setCurrentUsbFunctionsCb(long functions,
+                int status, long transactionId) {
+            mDeviceManager.setCurrentUsbFunctionsCb(functions, status,
+                    mRequest, mFunctions, mChargingFunctions);
+        }
+
+        @Override
+        public void getCurrentUsbFunctionsCb(long functions,
+                int status, long transactionId) {
+            mDeviceManager.getCurrentUsbFunctionsCb(functions, status);
+        }
+
+        @Override
+        public void getUsbSpeedCb(int speed, long transactionId) {
+            mDeviceManager.getUsbSpeedCb(speed);
+        }
+
+        @Override
+        public String getInterfaceHash() {
+            return IUsbGadgetCallback.HASH;
+        }
+
+        @Override
+        public int getInterfaceVersion() {
+            return IUsbGadgetCallback.VERSION;
+        }
+    }
+}
+
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
new file mode 100644
index 0000000..267247b
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHal.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.hal.gadget;
+
+import android.annotation.IntDef;
+import android.hardware.usb.gadget.IUsbGadgetCallback;
+import android.hardware.usb.IUsbOperationInternal;
+import android.hardware.usb.UsbManager.UsbHalVersion;
+import android.os.RemoteException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.String;
+
+/**
+ * @hide
+ */
+public interface UsbGadgetHal {
+    /**
+     * Power role: This USB port can act as a source (provide power).
+     * @hide
+     */
+    public static final int HAL_POWER_ROLE_SOURCE = 1;
+
+    /**
+     * Power role: This USB port can act as a sink (receive power).
+     * @hide
+     */
+    public static final int HAL_POWER_ROLE_SINK = 2;
+
+    @IntDef(prefix = { "HAL_POWER_ROLE_" }, value = {
+            HAL_POWER_ROLE_SOURCE,
+            HAL_POWER_ROLE_SINK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface HalUsbPowerRole{}
+
+    /**
+     * Data role: This USB port can act as a host (access data services).
+     * @hide
+     */
+    public static final int HAL_DATA_ROLE_HOST = 1;
+
+    /**
+     * Data role: This USB port can act as a device (offer data services).
+     * @hide
+     */
+    public static final int HAL_DATA_ROLE_DEVICE = 2;
+
+    @IntDef(prefix = { "HAL_DATA_ROLE_" }, value = {
+            HAL_DATA_ROLE_HOST,
+            HAL_DATA_ROLE_DEVICE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface HalUsbDataRole{}
+
+    /**
+     * This USB port can act as a downstream facing port (host).
+     *
+     * @hide
+     */
+    public static final int HAL_MODE_DFP = 1;
+
+    /**
+     * This USB port can act as an upstream facing port (device).
+     *
+     * @hide
+     */
+    public static final int HAL_MODE_UFP = 2;
+    @IntDef(prefix = { "HAL_MODE_" }, value = {
+            HAL_MODE_DFP,
+            HAL_MODE_UFP,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface HalUsbPortMode{}
+
+    /**
+     * UsbPortManager would call this when the system is done booting.
+     */
+    public void systemReady();
+
+    /**
+     * This function is used to query the USB functions included in the
+     * current USB configuration.
+     *
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
+     */
+    public void getCurrentUsbFunctions(long transactionId);
+
+    /**
+     * The function is used to query current USB speed.
+     *
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
+     */
+    public void getUsbSpeed(long transactionId);
+
+    /**
+     * This function is used to reset USB gadget driver.
+     * Performs USB data connection reset. The connection will disconnect and
+     * reconnect.
+     */
+    public void reset();
+
+    /**
+     * Invoked to query the version of current gadget hal implementation.
+     */
+    public @UsbHalVersion int getGadgetHalVersion() throws RemoteException;
+
+    /**
+     * This function is used to set the current USB gadget configuration.
+     * The USB gadget needs to be torn down if a USB configuration is already
+     * active.
+     *
+     * @param functions list of functions defined by GadgetFunction to be
+     *                  included in the gadget composition.
+     * @param timeout The maximum time (in milliseconds) within which the
+     *                IUsbGadgetCallback needs to be returned.
+     * @param transactionId Used for tracking the current request and is passed down to the HAL
+     *                      implementation as needed.
+     */
+    public void setCurrentUsbFunctions(int request, long functions,
+        boolean chargingFunctions, int timeout, long transactionId);
+}
+
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHalInstance.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHalInstance.java
new file mode 100644
index 0000000..d268315
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHalInstance.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.hal.gadget;
+
+import static com.android.server.usb.UsbPortManager.logAndPrint;
+
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.hal.gadget.UsbGadgetHidl;
+import com.android.server.usb.hal.gadget.UsbGadgetAidl;
+import com.android.server.usb.UsbDeviceManager;
+
+import android.util.Log;
+/**
+ * Helper class that queries the underlying hal layer to populate UsbPortHal instance.
+ */
+public final class UsbGadgetHalInstance {
+
+    public static UsbGadgetHal getInstance(UsbDeviceManager deviceManager,
+            IndentingPrintWriter pw) {
+
+        logAndPrint(Log.DEBUG, pw, "Querying USB Gadget HAL version");
+        if (UsbGadgetAidl.isServicePresent(null)) {
+            logAndPrint(Log.INFO, pw, "USB Gadget HAL AIDL present");
+            return new UsbGadgetAidl(deviceManager, pw);
+        }
+        if (UsbGadgetHidl.isServicePresent(null)) {
+            logAndPrint(Log.INFO, pw, "USB Gadget HAL HIDL present");
+            return new UsbGadgetHidl(deviceManager, pw);
+        }
+
+        logAndPrint(Log.ERROR, pw, "USB Gadget HAL AIDL/HIDL not present");
+        return null;
+    }
+}
+
diff --git a/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
new file mode 100644
index 0000000..3e5ecc5
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/hal/gadget/UsbGadgetHidl.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.usb.hal.gadget;
+
+import static android.hardware.usb.UsbManager.GADGET_HAL_NOT_SUPPORTED;
+import static android.hardware.usb.UsbManager.GADGET_HAL_V1_0;
+import static android.hardware.usb.UsbManager.GADGET_HAL_V1_1;
+import static android.hardware.usb.UsbManager.GADGET_HAL_V1_2;
+
+import static com.android.server.usb.UsbDeviceManager.logAndPrint;
+import static com.android.server.usb.UsbDeviceManager.logAndPrintException;
+
+import android.annotation.Nullable;
+import android.hardware.usb.gadget.V1_0.Status;
+import android.hardware.usb.gadget.V1_0.IUsbGadget;
+import android.hardware.usb.gadget.V1_2.IUsbGadgetCallback;
+import android.hardware.usb.gadget.V1_2.UsbSpeed;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbManager.UsbGadgetHalVersion;
+import android.hardware.usb.UsbManager.UsbHalVersion;
+import android.hidl.manager.V1_0.IServiceManager;
+import android.hidl.manager.V1_0.IServiceNotification;
+import android.os.IHwBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.usb.UsbDeviceManager;
+
+import java.util.ArrayList;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+/**
+ *
+ */
+public final class UsbGadgetHidl implements UsbGadgetHal {
+    // Cookie sent for usb gadget hal death notification.
+    private static final int USB_GADGET_HAL_DEATH_COOKIE = 2000;
+    // Proxy object for the usb gadget hal daemon.
+    @GuardedBy("mGadgetProxyLock")
+    private IUsbGadget mGadgetProxy;
+    private UsbDeviceManager mDeviceManager;
+    private final IndentingPrintWriter mPw;
+    // Mutex for all mutable shared state.
+    private final Object mGadgetProxyLock = new Object();
+    private UsbGadgetCallback mUsbGadgetCallback;
+
+    public @UsbGadgetHalVersion int getGadgetHalVersion() throws RemoteException {
+        int version;
+        synchronized(mGadgetProxyLock) {
+            if (mGadgetProxy == null) {
+                throw new RemoteException("IUsbGadget not initialized yet");
+            }
+            if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) {
+                version = UsbManager.GADGET_HAL_V1_2;
+            } else if (android.hardware.usb.gadget.V1_1.IUsbGadget.castFrom(mGadgetProxy) != null) {
+                version = UsbManager.GADGET_HAL_V1_1;
+            } else {
+                version = UsbManager.GADGET_HAL_V1_0;
+            }
+            logAndPrint(Log.INFO, mPw, "USB Gadget HAL HIDL version: " + version);
+            return version;
+        }
+    }
+
+    final class DeathRecipient implements IHwBinder.DeathRecipient {
+        private final IndentingPrintWriter mPw;
+
+        DeathRecipient(IndentingPrintWriter pw) {
+            mPw = pw;
+        }
+
+        @Override
+        public void serviceDied(long cookie) {
+            if (cookie == USB_GADGET_HAL_DEATH_COOKIE) {
+                logAndPrint(Log.ERROR, mPw, "Usb Gadget hal service died cookie: " + cookie);
+                synchronized (mGadgetProxyLock) {
+                    mGadgetProxy = null;
+                }
+            }
+        }
+    }
+
+    final class ServiceNotification extends IServiceNotification.Stub {
+        @Override
+        public void onRegistration(String fqName, String name, boolean preexisting) {
+            logAndPrint(Log.INFO, mPw, "Usb gadget hal service started " + fqName + " " + name);
+            connectToProxy(null);
+        }
+    }
+
+    private void connectToProxy(IndentingPrintWriter pw) {
+        synchronized (mGadgetProxyLock) {
+            if (mGadgetProxy != null) {
+                return;
+            }
+
+            try {
+                mGadgetProxy = IUsbGadget.getService();
+                mGadgetProxy.linkToDeath(new DeathRecipient(pw), USB_GADGET_HAL_DEATH_COOKIE);
+            } catch (NoSuchElementException e) {
+                logAndPrintException(pw, "connectToProxy: usb gadget hal service not found."
+                        + " Did the service fail to start?", e);
+            } catch (RemoteException e) {
+                logAndPrintException(pw, "connectToProxy: usb gadget hal service not responding"
+                        , e);
+            }
+        }
+    }
+
+    @Override
+    public void systemReady() {
+    }
+
+    static boolean isServicePresent(IndentingPrintWriter pw) {
+        try {
+            IUsbGadget.getService(true);
+        } catch (NoSuchElementException e) {
+            logAndPrintException(pw, "connectToProxy: usb gadget hidl hal service not found.", e);
+            return false;
+        } catch (RemoteException e) {
+            logAndPrintException(pw, "IUSBGadget hal service present but failed to get service", e);
+        }
+
+        return true;
+    }
+
+    public UsbGadgetHidl(UsbDeviceManager deviceManager, IndentingPrintWriter pw) {
+        mDeviceManager = Objects.requireNonNull(deviceManager);
+        mPw = pw;
+        try {
+            ServiceNotification serviceNotification = new ServiceNotification();
+
+            boolean ret = IServiceManager.getService()
+                    .registerForNotifications("android.hardware.usb.gadget@1.0::IUsbGadget",
+                            "", serviceNotification);
+            if (!ret) {
+                logAndPrint(Log.ERROR, pw, "Failed to register service start notification");
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(pw, "Failed to register service start notification", e);
+            return;
+        }
+        connectToProxy(mPw);
+    }
+
+    @Override
+    public void getCurrentUsbFunctions(long transactionId) {
+        try {
+            synchronized(mGadgetProxyLock) {
+                mGadgetProxy.getCurrentUsbFunctions(new UsbGadgetCallback());
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(mPw,
+                    "RemoteException while calling getCurrentUsbFunctions", e);
+            return;
+        }
+    }
+
+    @Override
+    public void getUsbSpeed(long transactionId) {
+        try {
+            synchronized(mGadgetProxyLock) {
+                if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) {
+                    android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy =
+                    android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy);
+                    gadgetProxy.getUsbSpeed(new UsbGadgetCallback());
+                }
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(mPw, "get UsbSpeed failed", e);
+        }
+    }
+
+    @Override
+    public void reset() {
+        try {
+            synchronized(mGadgetProxyLock) {
+                if (android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy) != null) {
+                    android.hardware.usb.gadget.V1_2.IUsbGadget gadgetProxy =
+                    android.hardware.usb.gadget.V1_2.IUsbGadget.castFrom(mGadgetProxy);
+                    gadgetProxy.reset();
+                }
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(mPw,
+                    "RemoteException while calling getUsbSpeed", e);
+            return;
+        }
+    }
+
+    @Override
+    public void setCurrentUsbFunctions(int mRequest, long mFunctions,
+            boolean mChargingFunctions, int timeout, long operationId) {
+        try {
+            mUsbGadgetCallback = new UsbGadgetCallback(null, mRequest,
+                                      mFunctions, mChargingFunctions);
+            synchronized(mGadgetProxyLock) {
+                mGadgetProxy.setCurrentUsbFunctions(mFunctions, mUsbGadgetCallback, timeout);
+            }
+        } catch (RemoteException e) {
+            logAndPrintException(mPw,
+                    "RemoteException while calling setCurrentUsbFunctions"
+                    + " mRequest = " + mRequest
+                    + ", mFunctions = " + mFunctions
+                    + ", timeout = " + timeout
+                    + ", mChargingFunctions = " + mChargingFunctions
+                    + ", operationId =" + operationId, e);
+            return;
+        }
+    }
+
+    private class UsbGadgetCallback extends IUsbGadgetCallback.Stub {
+        public int mRequest;
+        public long mFunctions;
+        public boolean mChargingFunctions;
+
+        UsbGadgetCallback() {
+        }
+        UsbGadgetCallback(IndentingPrintWriter pw, int request,
+                long functions, boolean chargingFunctions) {
+            mRequest = request;
+            mFunctions = functions;
+            mChargingFunctions = chargingFunctions;
+        }
+
+        @Override
+        public void setCurrentUsbFunctionsCb(long functions,
+                int status) {
+            mDeviceManager.setCurrentUsbFunctionsCb(functions, status,
+                    mRequest, mFunctions, mChargingFunctions);
+        }
+
+        @Override
+        public void getCurrentUsbFunctionsCb(long functions,
+                int status) {
+            mDeviceManager.getCurrentUsbFunctionsCb(functions, status);
+        }
+
+        @Override
+        public void getUsbSpeedCb(int speed) {
+            mDeviceManager.getUsbSpeedCb(speed);
+        }
+    }
+}
+
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index c2b65f8..845449e 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -1020,6 +1020,26 @@
     }
 
     /**
+     * Return the encoding type of a received SMS message, which is specified using ENCODING_*
+     * GSM: defined in android.telephony.SmsConstants
+     * CDMA: defined in android.telephony.cdma.UserData
+     *
+     * @hide
+     */
+    public int getReceivedEncodingType() {
+        return mWrappedSmsMessage.getReceivedEncodingType();
+    }
+
+    /**
+     * Check if format of the message is 3GPP.
+     *
+     * @hide
+     */
+    public boolean is3gpp() {
+        return (mWrappedSmsMessage instanceof com.android.internal.telephony.gsm.SmsMessage);
+    }
+
+    /**
      * Determines whether or not to use CDMA format for MO SMS.
      * If SMS over IMS is supported, then format is based on IMS SMS format,
      * otherwise format is based on current phone type.
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index f373f6e..ac148e7 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1048,6 +1048,13 @@
     public static final String ALLOWED_NETWORK_TYPES =
             SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS;
 
+    /**
+     * TelephonyProvider column name for user handle associated with a sim.
+     * <P>Type: INTEGER (int)</P>
+     * @hide
+     */
+    public static final String USER_HANDLE = SimInfo.COLUMN_USER_HANDLE;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"USAGE_SETTING_"},
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 6d46ed3..0cc1e98 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static com.android.internal.telephony.SmsConstants.ENCODING_UNKNOWN;
+
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.telephony.SmsMessage;
@@ -94,6 +96,15 @@
     protected boolean mMwiDontStore;
 
     /**
+     * The encoding type of a received SMS message, which is specified using ENCODING_*
+     * GSM: defined in android.telephony.SmsConstants
+     * CDMA: defined in android.telephony.cdma.UserData
+     *
+     * @hide
+     */
+    protected int mReceivedEncodingType = ENCODING_UNKNOWN;
+
+    /**
      * Indicates status for messages stored on the ICC.
      */
     protected int mStatusOnIcc = -1;
@@ -512,4 +523,8 @@
 
         return mRecipientAddress.getAddressString();
     }
+
+    public int getReceivedEncodingType() {
+        return mReceivedEncodingType;
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index f636276..b51ba31 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -780,6 +780,7 @@
             mUserData = mBearerData.userData.payload;
             mUserDataHeader = mBearerData.userData.userDataHeader;
             mMessageBody = mBearerData.userData.payloadStr;
+            mReceivedEncodingType = mBearerData.userData.msgEncoding;
         }
 
         if (mOriginatingAddress != null) {
@@ -860,6 +861,9 @@
             Rlog.w(LOG_TAG, "BearerData.decode() returned null");
             return null;
         }
+        if (bData.userData != null) {
+            mReceivedEncodingType = bData.userData.msgEncoding;
+        }
 
         if (Rlog.isLoggable(LOGGABLE_TAG, Log.VERBOSE)) {
             Rlog.d(LOG_TAG, "MT raw BearerData = " + HexDump.toHexString(mEnvelope.bearerData));
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 7a5bf06..09ead31 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -1462,28 +1462,28 @@
             } else {
                 switch ((mDataCodingScheme >> 2) & 0x3) {
                 case 0: // GSM 7 bit default alphabet
-                    encodingType = ENCODING_7BIT;
-                    break;
+                        encodingType = ENCODING_7BIT;
+                        break;
 
                 case 2: // UCS 2 (16bit)
-                    encodingType = ENCODING_16BIT;
-                    break;
+                        encodingType = ENCODING_16BIT;
+                        break;
 
                 case 1: // 8 bit data
-                    //Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet string
-                    //that's stored in 8-bit unpacked format) characters.
-                    if (r.getBoolean(com.android.internal.
-                            R.bool.config_sms_decode_gsm_8bit_data)) {
-                        encodingType = ENCODING_8BIT;
-                        break;
-                    }
+                        // Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet
+                        // string that's stored in 8-bit unpacked format) characters.
+                        if (r.getBoolean(com.android.internal
+                                .R.bool.config_sms_decode_gsm_8bit_data)) {
+                            encodingType = ENCODING_8BIT;
+                            break;
+                        }
 
                 case 3: // reserved
-                    Rlog.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
-                            + (mDataCodingScheme & 0xff));
-                    encodingType = r.getInteger(
-                            com.android.internal.R.integer.default_reserved_data_coding_scheme);
-                    break;
+                        Rlog.w(LOG_TAG, "1 - Unsupported SMS data coding scheme "
+                                + (mDataCodingScheme & 0xff));
+                        encodingType = r.getInteger(
+                                com.android.internal.R.integer.default_reserved_data_coding_scheme);
+                        break;
                 }
             }
         } else if ((mDataCodingScheme & 0xf0) == 0xf0) {
@@ -1558,6 +1558,7 @@
                 encodingType == ENCODING_7BIT);
         this.mUserData = p.getUserData();
         this.mUserDataHeader = p.getUserDataHeader();
+        this.mReceivedEncodingType = encodingType;
 
         /*
          * Look for voice mail indication in TP_UDH TS23.040 9.2.3.24
diff --git a/tests/Internal/src/com/android/internal/app/OWNERS b/tests/Internal/src/com/android/internal/app/OWNERS
new file mode 100644
index 0000000..d55dc78
--- /dev/null
+++ b/tests/Internal/src/com/android/internal/app/OWNERS
@@ -0,0 +1,2 @@
+# Locale related test
+per-file *Locale* = file:/services/core/java/com/android/server/locales/OWNERS
diff --git a/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java b/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java
index 782439f..98bf541 100644
--- a/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java
+++ b/tests/UsbManagerTests/lib/src/com/android/server/usblib/UsbManagerTestLib.java
@@ -24,12 +24,15 @@
 
 import android.content.Context;
 import android.hardware.usb.UsbManager;
+import android.os.Binder;
 import android.os.RemoteException;
 import android.util.Log;
 
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 /**
  * Unit tests lib for {@link android.hardware.usb.UsbManager}.
  */
@@ -42,6 +45,11 @@
     private UsbManager mUsbManagerMock;
     @Mock private android.hardware.usb.IUsbManager mMockUsbService;
 
+    /**
+     * Counter for tracking UsbOperation operations.
+     */
+    private static final AtomicInteger sUsbOperationCount = new AtomicInteger();
+
     public UsbManagerTestLib(Context context) {
         MockitoAnnotations.initMocks(this);
         mContext = context;
@@ -82,10 +90,11 @@
     }
 
     private void testSetCurrentFunctionsMock_Matched(long functions) {
+        int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
         try {
             setCurrentFunctions(functions);
 
-            verify(mMockUsbService).setCurrentFunctions(eq(functions));
+            verify(mMockUsbService).setCurrentFunctions(eq(functions), operationId);
         } catch (RemoteException remEx) {
             Log.w(TAG, "RemoteException");
         }
@@ -106,9 +115,10 @@
     }
 
     public void testSetCurrentFunctionsEx(long functions) throws Exception {
+        int operationId = sUsbOperationCount.incrementAndGet() + Binder.getCallingUid();
         setCurrentFunctions(functions);
 
-        verify(mMockUsbService).setCurrentFunctions(eq(functions));
+        verify(mMockUsbService).setCurrentFunctions(eq(functions), operationId);
     }
 
     public void testGetCurrentFunctions_shouldMatched() {
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
index 861d221..e06a4cb 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbHandlerTest.java
@@ -98,7 +98,7 @@
         }
 
         @Override
-        protected void setEnabledFunctions(long functions, boolean force) {
+        protected void setEnabledFunctions(long functions, boolean force, int operationId) {
             mCurrentFunctions = functions;
         }
 
@@ -134,6 +134,20 @@
         protected void sendStickyBroadcast(Intent intent) {
             mBroadcastedIntent = intent;
         }
+
+        @Override
+        public void handlerInitDone(int operationId) {
+        }
+
+        @Override
+        public void setCurrentUsbFunctionsCb(long functions,
+                    int status, int mRequest, long mFunctions, boolean mChargingFunctions){
+        }
+
+        @Override
+        public void getUsbSpeedCb(int speed){
+        }
+
     }
 
     @Before