Merge changes from topic "227137943"

* changes:
  Implement getInterfaceHash/Version (USB)
  Support IUsb AIDL interface
diff --git a/core/api/current.txt b/core/api/current.txt
index 641b1a3..e4fc9f3 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -29612,6 +29612,7 @@
     field public static final int S = 31; // 0x1f
     field public static final int S_V2 = 32; // 0x20
     field public static final int TIRAMISU = 10000; // 0x2710
+    field public static final int UPSIDE_DOWN_CAKE = 10000; // 0x2710
   }
 
   public final class Bundle extends android.os.BaseBundle implements java.lang.Cloneable android.os.Parcelable {
diff --git a/core/java/android/net/VpnProfileState.java b/core/java/android/net/VpnProfileState.java
index 0f21a9d..552a2c1 100644
--- a/core/java/android/net/VpnProfileState.java
+++ b/core/java/android/net/VpnProfileState.java
@@ -24,6 +24,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
 import java.util.StringJoiner;
 
 /**
@@ -176,4 +177,19 @@
         resultJoiner.add("Lockdown: " + isLockdownEnabled());
         return resultJoiner.toString();
     }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (!(obj instanceof VpnProfileState)) return false;
+        final VpnProfileState that = (VpnProfileState) obj;
+        return (getState() == that.getState()
+                && Objects.equals(getSessionId(), that.getSessionId())
+                && isAlwaysOn() == that.isAlwaysOn()
+                && isLockdownEnabled() == that.isLockdownEnabled());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getState(), getSessionId(), isAlwaysOn(), isLockdownEnabled());
+    }
 }
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 394e7c3..141b141 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1167,6 +1167,11 @@
          * Tiramisu.
          */
         public static final int TIRAMISU = CUR_DEVELOPMENT;
+
+        /**
+         * Upside Down Cake.
+         */
+        public static final int UPSIDE_DOWN_CAKE = CUR_DEVELOPMENT;
     }
 
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f2ddf52..ffa577a 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -28283,7 +28283,7 @@
      *     {@link InputDevice#SOURCE_MOUSE_RELATIVE}, and relative position changes will be
      *     available through {@link MotionEvent#getX} and {@link MotionEvent#getY}.</li>
      *
-     *     <li>Events from a touchpad will be delivered with the source
+     *     <li>Events from a touchpad or trackpad will be delivered with the source
      *     {@link InputDevice#SOURCE_TOUCHPAD}, where the absolute position of each of the pointers
      *     on the touchpad will be available through {@link MotionEvent#getX(int)} and
      *     {@link MotionEvent#getY(int)}, and their relative movements are stored in
@@ -28292,6 +28292,12 @@
      *     <li>Events from other types of devices, such as touchscreens, will not be affected.</li>
      * </ul>
      * <p>
+     * When pointer capture changes, connected mouse and trackpad devices may be reconfigured,
+     * and their properties (such as their sources or motion ranges) may change. Use an
+     * {@link android.hardware.input.InputManager.InputDeviceListener} to be notified when a device
+     * changes (which may happen after enabling or disabling pointer capture), and use
+     * {@link InputDevice#getDevice(int)} to get the updated {@link InputDevice}.
+     * <p>
      * Events captured through pointer capture will be dispatched to
      * {@link OnCapturedPointerListener#onCapturedPointer(View, MotionEvent)} if an
      * {@link OnCapturedPointerListener} is set, and otherwise to
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 51185d4..86e97d5 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1599,10 +1599,11 @@
     // since the directory is owned by root.
     if (!is_system_server && getuid() == 0) {
         const int rc = createProcessGroup(uid, getpid());
-        if (rc == -EROFS) {
-            ALOGW("createProcessGroup failed, kernel missing CONFIG_CGROUP_CPUACCT?");
-        } else if (rc != 0) {
-            ALOGE("createProcessGroup(%d, %d) failed: %s", uid, /* pid= */ 0, strerror(-rc));
+        if (rc != 0) {
+            fail_fn(rc == -EROFS ? CREATE_ERROR("createProcessGroup failed, kernel missing "
+                                                "CONFIG_CGROUP_CPUACCT?")
+                                 : CREATE_ERROR("createProcessGroup(%d, %d) failed: %s", uid,
+                                                /* pid= */ 0, strerror(-rc)));
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index dc80c4b..ca16f57 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2425,8 +2425,8 @@
             if (!regularZygote) {
                 // webview and app zygote don't have the permission to create the nodes
                 if (Process.createProcessGroup(uid, startResult.pid) < 0) {
-                    Slog.e(ActivityManagerService.TAG, "Unable to create process group for "
-                            + app.processName + " (" + startResult.pid + ")");
+                    throw new AssertionError("Unable to create process group for " + app.processName
+                            + " (" + startResult.pid + ")");
                 }
             }
 
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index d9db28a..b49654e 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -2527,7 +2527,9 @@
             super(TAG);
             mProfile = profile;
             mIpSecManager = (IpSecManager) mContext.getSystemService(Context.IPSEC_SERVICE);
-            mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this);
+            // Pass mExecutor into Ikev2VpnNetworkCallback and make sure that IkeV2VpnRunnerCallback
+            // will be called by the mExecutor thread.
+            mNetworkCallback = new VpnIkev2Utils.Ikev2VpnNetworkCallback(TAG, this, mExecutor);
             mSessionKey = UUID.randomUUID().toString();
         }
 
@@ -2682,73 +2684,68 @@
          * <p>The Ikev2VpnRunner will unconditionally switch to the new network, killing the old IKE
          * state in the process, and starting a new IkeSession instance.
          *
-         * <p>This method is called multiple times over the lifetime of the Ikev2VpnRunner, and is
-         * called on the ConnectivityService thread. Thus, the actual work MUST be proxied to the
-         * mExecutor thread in order to ensure consistency of the Ikev2VpnRunner fields.
+         * <p>This method MUST always be called on the mExecutor thread in order to ensure
+         * consistency of the Ikev2VpnRunner fields.
          */
         public void onDefaultNetworkChanged(@NonNull Network network) {
             Log.d(TAG, "Starting IKEv2/IPsec session on new network: " + network);
 
-            // Proxy to the Ikev2VpnRunner (single-thread) executor to ensure consistency in lieu
-            // of locking.
-            mExecutor.execute(() -> {
-                try {
-                    if (!mIsRunning) {
-                        Log.d(TAG, "onDefaultNetworkChanged after exit");
-                        return; // VPN has been shut down.
-                    }
-
-                    // Clear mInterface to prevent Ikev2VpnRunner being cleared when
-                    // interfaceRemoved() is called.
-                    mInterface = null;
-                    // Without MOBIKE, we have no way to seamlessly migrate. Close on old
-                    // (non-default) network, and start the new one.
-                    resetIkeState();
-                    mActiveNetwork = network;
-
-                    // Get Ike options from IkeTunnelConnectionParams if it's available in the
-                    // profile.
-                    final IkeTunnelConnectionParams ikeTunConnParams =
-                            mProfile.getIkeTunnelConnectionParams();
-                    final IkeSessionParams ikeSessionParams;
-                    final ChildSessionParams childSessionParams;
-                    if (ikeTunConnParams != null) {
-                        final IkeSessionParams.Builder builder = new IkeSessionParams.Builder(
-                                ikeTunConnParams.getIkeSessionParams()).setNetwork(network);
-                        ikeSessionParams = builder.build();
-                        childSessionParams = ikeTunConnParams.getTunnelModeChildSessionParams();
-                    } else {
-                        ikeSessionParams = VpnIkev2Utils.buildIkeSessionParams(
-                                mContext, mProfile, network);
-                        childSessionParams = VpnIkev2Utils.buildChildSessionParams(
-                                mProfile.getAllowedAlgorithms());
-                    }
-
-                    // TODO: Remove the need for adding two unused addresses with
-                    // IPsec tunnels.
-                    final InetAddress address = InetAddress.getLocalHost();
-                    mTunnelIface =
-                            mIpSecManager.createIpSecTunnelInterface(
-                                    address /* unused */,
-                                    address /* unused */,
-                                    network);
-                    NetdUtils.setInterfaceUp(mNetd, mTunnelIface.getInterfaceName());
-
-                    mSession = mIkev2SessionCreator.createIkeSession(
-                            mContext,
-                            ikeSessionParams,
-                            childSessionParams,
-                            mExecutor,
-                            new VpnIkev2Utils.IkeSessionCallbackImpl(
-                                    TAG, IkeV2VpnRunner.this, network),
-                            new VpnIkev2Utils.ChildSessionCallbackImpl(
-                                    TAG, IkeV2VpnRunner.this, network));
-                    Log.d(TAG, "Ike Session started for network " + network);
-                } catch (Exception e) {
-                    Log.i(TAG, "Setup failed for network " + network + ". Aborting", e);
-                    onSessionLost(network, e);
+            try {
+                if (!mIsRunning) {
+                    Log.d(TAG, "onDefaultNetworkChanged after exit");
+                    return; // VPN has been shut down.
                 }
-            });
+
+                // Clear mInterface to prevent Ikev2VpnRunner being cleared when
+                // interfaceRemoved() is called.
+                mInterface = null;
+                // Without MOBIKE, we have no way to seamlessly migrate. Close on old
+                // (non-default) network, and start the new one.
+                resetIkeState();
+                mActiveNetwork = network;
+
+                // Get Ike options from IkeTunnelConnectionParams if it's available in the
+                // profile.
+                final IkeTunnelConnectionParams ikeTunConnParams =
+                        mProfile.getIkeTunnelConnectionParams();
+                final IkeSessionParams ikeSessionParams;
+                final ChildSessionParams childSessionParams;
+                if (ikeTunConnParams != null) {
+                    final IkeSessionParams.Builder builder = new IkeSessionParams.Builder(
+                            ikeTunConnParams.getIkeSessionParams()).setNetwork(network);
+                    ikeSessionParams = builder.build();
+                    childSessionParams = ikeTunConnParams.getTunnelModeChildSessionParams();
+                } else {
+                    ikeSessionParams = VpnIkev2Utils.buildIkeSessionParams(
+                            mContext, mProfile, network);
+                    childSessionParams = VpnIkev2Utils.buildChildSessionParams(
+                            mProfile.getAllowedAlgorithms());
+                }
+
+                // TODO: Remove the need for adding two unused addresses with
+                // IPsec tunnels.
+                final InetAddress address = InetAddress.getLocalHost();
+                mTunnelIface =
+                        mIpSecManager.createIpSecTunnelInterface(
+                                address /* unused */,
+                                address /* unused */,
+                                network);
+                NetdUtils.setInterfaceUp(mNetd, mTunnelIface.getInterfaceName());
+
+                mSession = mIkev2SessionCreator.createIkeSession(
+                        mContext,
+                        ikeSessionParams,
+                        childSessionParams,
+                        mExecutor,
+                        new VpnIkev2Utils.IkeSessionCallbackImpl(
+                                TAG, IkeV2VpnRunner.this, network),
+                        new VpnIkev2Utils.ChildSessionCallbackImpl(
+                                TAG, IkeV2VpnRunner.this, network));
+                Log.d(TAG, "Ike Session started for network " + network);
+            } catch (Exception e) {
+                Log.i(TAG, "Setup failed for network " + network + ". Aborting", e);
+                onSessionLost(network, e);
+            }
         }
 
         /** Marks the state as FAILED, and disconnects. */
diff --git a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
index a0a596d..6982d60 100644
--- a/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
+++ b/services/core/java/com/android/server/connectivity/VpnIkev2Utils.java
@@ -86,6 +86,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
 
 /**
  * Utility class to build and convert IKEv2/IPsec parameters.
@@ -376,22 +377,25 @@
     static class Ikev2VpnNetworkCallback extends NetworkCallback {
         private final String mTag;
         private final Vpn.IkeV2VpnRunnerCallback mCallback;
+        private final ExecutorService mExecutor;
 
-        Ikev2VpnNetworkCallback(String tag, Vpn.IkeV2VpnRunnerCallback callback) {
+        Ikev2VpnNetworkCallback(String tag, Vpn.IkeV2VpnRunnerCallback callback,
+                ExecutorService executor) {
             mTag = tag;
             mCallback = callback;
+            mExecutor = executor;
         }
 
         @Override
         public void onAvailable(@NonNull Network network) {
             Log.d(mTag, "Starting IKEv2/IPsec session on new network: " + network);
-            mCallback.onDefaultNetworkChanged(network);
+            mExecutor.execute(() -> mCallback.onDefaultNetworkChanged(network));
         }
 
         @Override
         public void onLost(@NonNull Network network) {
             Log.d(mTag, "Tearing down; lost network: " + network);
-            mCallback.onSessionLost(network, null);
+            mExecutor.execute(() -> mCallback.onSessionLost(network, null));
         }
     }
 
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
index 7ea4ab1..0aca293 100644
--- a/tools/aapt2/SdkConstants.cpp
+++ b/tools/aapt2/SdkConstants.cpp
@@ -27,7 +27,7 @@
 
 static ApiVersion sDevelopmentSdkLevel = 10000;
 static const auto sDevelopmentSdkCodeNames =
-    std::unordered_set<StringPiece>({"Q", "R", "S", "Sv2", "Tiramisu"});
+    std::unordered_set<StringPiece>({"Q", "R", "S", "Sv2", "Tiramisu", "UpsideDownCake"});
 
 static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = {
     {0x021c, 1},