Merge "Update preloaded-classes-denylist.txt" into main
diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java
index 41585b3..7d6e7ad 100644
--- a/core/java/android/database/BulkCursorNative.java
+++ b/core/java/android/database/BulkCursorNative.java
@@ -215,7 +215,7 @@
             // If close() is being called from the finalizer thread, do not wait for a reply from
             // the remote side.
             final boolean fromFinalizer =
-                    android.database.sqlite.Flags.onewayFinalizerClose()
+                    android.database.sqlite.Flags.onewayFinalizerCloseFixed()
                     && "FinalizerDaemon".equals(Thread.currentThread().getName());
             mRemote.transact(CLOSE_TRANSACTION, data, reply,
                     fromFinalizer ? IBinder.FLAG_ONEWAY: 0);
diff --git a/core/java/android/database/sqlite/flags.aconfig b/core/java/android/database/sqlite/flags.aconfig
index c597895..c2cc9d1 100644
--- a/core/java/android/database/sqlite/flags.aconfig
+++ b/core/java/android/database/sqlite/flags.aconfig
@@ -2,8 +2,9 @@
 container: "system"
 
 flag {
-     name: "oneway_finalizer_close"
+     name: "oneway_finalizer_close_fixed"
      namespace: "system_performance"
+     is_fixed_read_only: true
      description: "Make BuildCursorNative.close oneway if in the the finalizer"
      bug: "368221351"
 }
diff --git a/core/java/android/hardware/usb/OWNERS b/core/java/android/hardware/usb/OWNERS
index a753f96..37604bc 100644
--- a/core/java/android/hardware/usb/OWNERS
+++ b/core/java/android/hardware/usb/OWNERS
@@ -1,7 +1,7 @@
 # Bug component: 175220
 
-aprasath@google.com
-kumarashishg@google.com
-sarup@google.com
 anothermark@google.com
+febinthattil@google.com
+aprasath@google.com
 badhri@google.com
+kumarashishg@google.com
\ No newline at end of file
diff --git a/media/java/android/media/flags/editing.aconfig b/media/java/android/media/flags/editing.aconfig
index 185f579..0adc478 100644
--- a/media/java/android/media/flags/editing.aconfig
+++ b/media/java/android/media/flags/editing.aconfig
@@ -15,3 +15,10 @@
   description: "Enable B frames for Stagefright recorder."
   bug: "341121900"
 }
+
+flag {
+  name: "muxer_mp4_enable_apv"
+  namespace: "media_solutions"
+  description: "Enable APV support in mp4 writer."
+  bug: "370061501"
+}
diff --git a/media/java/android/mtp/OWNERS b/media/java/android/mtp/OWNERS
index 6b5336e..77ed08b 100644
--- a/media/java/android/mtp/OWNERS
+++ b/media/java/android/mtp/OWNERS
@@ -1,10 +1,9 @@
 set noparent
 
-aprasath@google.com
 anothermark@google.com
-kumarashishg@google.com
-sarup@google.com
+febinthattil@google.com
+aprasath@google.com
 jsharkey@android.com
 jameswei@google.com
 rmojumder@google.com
-
+kumarashishg@google.com
diff --git a/media/tests/MtpTests/OWNERS b/media/tests/MtpTests/OWNERS
index 6b5336e..bdb6cdb 100644
--- a/media/tests/MtpTests/OWNERS
+++ b/media/tests/MtpTests/OWNERS
@@ -1,10 +1,9 @@
 set noparent
 
-aprasath@google.com
 anothermark@google.com
-kumarashishg@google.com
-sarup@google.com
+febinthattil@google.com
+aprasath@google.com
 jsharkey@android.com
 jameswei@google.com
 rmojumder@google.com
-
+kumarashishg@google.com
\ No newline at end of file
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 96b7c13..00812042 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -207,6 +207,7 @@
     method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
     method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public boolean isEuiccSupported();
     method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>);
+    method @FlaggedApi("android.nfc.nfc_event_listener") public void registerNfcEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener);
     method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
     method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
     method public boolean removeAidsForService(android.content.ComponentName, String);
@@ -216,6 +217,7 @@
     method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
     method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setShouldDefaultToObserveModeForService(@NonNull android.content.ComponentName, boolean);
     method public boolean supportsAidPrefixRegistration();
+    method @FlaggedApi("android.nfc.nfc_event_listener") public void unregisterNfcEventListener(@NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener);
     method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName);
     method public boolean unsetPreferredService(android.app.Activity);
     field @Deprecated public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
@@ -233,13 +235,16 @@
     field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0
   }
 
+  @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventListener {
+    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onObserveModeStateChanged(boolean);
+    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onPreferredServiceChanged(boolean);
+  }
+
   public abstract class HostApduService extends android.app.Service {
     ctor public HostApduService();
     method public final void notifyUnhandled();
     method public final android.os.IBinder onBind(android.content.Intent);
     method public abstract void onDeactivated(int);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public void onObserveModeStateChanged(boolean);
-    method @FlaggedApi("android.nfc.nfc_event_listener") public void onPreferredServiceChanged(boolean);
     method public abstract byte[] processCommandApdu(byte[], android.os.Bundle);
     method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.nfc.cardemulation.PollingFrame>);
     method public final void sendResponseApdu(byte[]);
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 24e14e6..6aa8a2b 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -91,6 +91,7 @@
     method public void onDisable(@NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onDisableFinished(int);
     method public void onDisableStarted();
+    method public void onEeListenActivated(boolean);
     method public void onEnable(@NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onEnableFinished(int);
     method public void onEnableStarted();
@@ -105,7 +106,7 @@
     method public void onRfFieldActivated(boolean);
     method public void onRoutingChanged();
     method public void onStateUpdated(int);
-    method public void onTagConnected(boolean, @NonNull android.nfc.Tag);
+    method public void onTagConnected(boolean);
     method public void onTagDispatch(@NonNull java.util.function.Consumer<java.lang.Boolean>);
   }
 
diff --git a/nfc/java/android/nfc/ComponentNameAndUser.aidl b/nfc/java/android/nfc/ComponentNameAndUser.aidl
new file mode 100644
index 0000000..e677998
--- /dev/null
+++ b/nfc/java/android/nfc/ComponentNameAndUser.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 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.nfc;
+
+parcelable ComponentNameAndUser;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/ComponentNameAndUser.java b/nfc/java/android/nfc/ComponentNameAndUser.java
new file mode 100644
index 0000000..59e6c62
--- /dev/null
+++ b/nfc/java/android/nfc/ComponentNameAndUser.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2024 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.nfc;
+
+import android.annotation.UserIdInt;
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+public class ComponentNameAndUser implements Parcelable {
+    @UserIdInt private final int mUserId;
+    private ComponentName mComponentName;
+
+    public ComponentNameAndUser(@UserIdInt int userId, ComponentName componentName) {
+        mUserId = userId;
+        mComponentName = componentName;
+    }
+
+    /**
+     * @hide
+     */
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * @hide
+     */
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(mUserId);
+        out.writeParcelable(mComponentName, flags);
+    }
+
+    public static final Parcelable.Creator<ComponentNameAndUser> CREATOR =
+            new Parcelable.Creator<ComponentNameAndUser>() {
+                public ComponentNameAndUser createFromParcel(Parcel in) {
+                    return new ComponentNameAndUser(in);
+                }
+
+                public ComponentNameAndUser[] newArray(int size) {
+                    return new ComponentNameAndUser[size];
+                }
+            };
+
+    private ComponentNameAndUser(Parcel in) {
+        mUserId = in.readInt();
+        mComponentName = in.readParcelable(null, ComponentName.class);
+    }
+
+    @UserIdInt
+    public int getUserId() {
+        return mUserId;
+    }
+
+    public ComponentName getComponentName() {
+        return mComponentName;
+    }
+
+    @Override
+    public String toString() {
+        return mComponentName + " for user id: " + mUserId;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj != null && obj instanceof ComponentNameAndUser) {
+            ComponentNameAndUser other = (ComponentNameAndUser) obj;
+            return other.getUserId() == mUserId
+                    && Objects.equals(other.getComponentName(), mComponentName);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        if (mComponentName == null) {
+            return mUserId;
+        }
+        return mComponentName.hashCode() + mUserId;
+    }
+}
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
index 8535e4a..5e2e92d 100644
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ b/nfc/java/android/nfc/INfcCardEmulation.aidl
@@ -17,6 +17,8 @@
 package android.nfc;
 
 import android.content.ComponentName;
+import android.nfc.INfcEventListener;
+
 import android.nfc.cardemulation.AidGroup;
 import android.nfc.cardemulation.ApduServiceInfo;
 import android.os.RemoteCallback;
@@ -55,4 +57,7 @@
     boolean isAutoChangeEnabled();
     List<String> getRoutingStatus();
     void overwriteRoutingTable(int userHandle, String emptyAid, String protocol, String tech, String sc);
+
+    void registerNfcEventListener(in INfcEventListener listener);
+    void unregisterNfcEventListener(in INfcEventListener listener);
 }
diff --git a/nfc/java/android/nfc/INfcEventListener.aidl b/nfc/java/android/nfc/INfcEventListener.aidl
new file mode 100644
index 0000000..5162c26
--- /dev/null
+++ b/nfc/java/android/nfc/INfcEventListener.aidl
@@ -0,0 +1,11 @@
+package android.nfc;
+
+import android.nfc.ComponentNameAndUser;
+
+/**
+ * @hide
+ */
+oneway interface INfcEventListener {
+    void onPreferredServiceChanged(in ComponentNameAndUser ComponentNameAndUser);
+    void onObserveModeStateChanged(boolean isEnabled);
+}
\ No newline at end of file
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
index 48c7ee6..7f1fd15 100644
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -27,7 +27,7 @@
  * @hide
  */
 interface INfcOemExtensionCallback {
-   void onTagConnected(boolean connected, in Tag tag);
+   void onTagConnected(boolean connected);
    void onStateUpdated(int state);
    void onApplyRouting(in ResultReceiver isSkipped);
    void onNdefRead(in ResultReceiver isSkipped);
@@ -46,6 +46,7 @@
    void onCardEmulationActivated(boolean isActivated);
    void onRfFieldActivated(boolean isActivated);
    void onRfDiscoveryStarted(boolean isDiscoveryStarted);
+   void onEeListenActivated(boolean isActivated);
    void onGetOemAppSearchIntent(in List<String> firstPackage, in ResultReceiver intentConsumer);
    void onNdefMessage(in Tag tag, in NdefMessage message, in ResultReceiver hasOemExecutableContent);
    void onLaunchHceAppChooserActivity(in String selectedAid, in List<ApduServiceInfo> services, in ComponentName failedComponent, in String category);
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 474ff8c..1d2085c 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -80,6 +80,7 @@
     private boolean mCardEmulationActivated = false;
     private boolean mRfFieldActivated = false;
     private boolean mRfDiscoveryStarted = false;
+    private boolean mEeListenActivated = false;
 
     /**
      * Broadcast Action: Sent on NFC stack initialization when NFC OEM extensions are enabled.
@@ -195,9 +196,8 @@
          * ex - if tag is connected  notify cover and Nfctest app if app is in testing mode
          *
          * @param connected status of the tag true if tag is connected otherwise false
-         * @param tag Tag details
          */
-        void onTagConnected(boolean connected, @NonNull Tag tag);
+        void onTagConnected(boolean connected);
 
         /**
          * Update the Nfc Adapter State
@@ -327,6 +327,13 @@
         void onRfDiscoveryStarted(boolean isDiscoveryStarted);
 
         /**
+        * Notifies the NFCEE (NFC Execution Environment) Listen has been activated.
+        *
+        * @param isActivated true, if EE Listen is ON, else EE Listen is OFF.
+        */
+        void onEeListenActivated(boolean isActivated);
+
+        /**
          * Gets the intent to find the OEM package in the OEM App market. If the consumer returns
          * {@code null} or a timeout occurs, the intent from the first available package will be
          * used instead.
@@ -437,6 +444,7 @@
                 callback.onCardEmulationActivated(mCardEmulationActivated);
                 callback.onRfFieldActivated(mRfFieldActivated);
                 callback.onRfDiscoveryStarted(mRfDiscoveryStarted);
+                callback.onEeListenActivated(mEeListenActivated);
             });
         }
     }
@@ -684,9 +692,9 @@
     private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
 
         @Override
-        public void onTagConnected(boolean connected, Tag tag) throws RemoteException {
+        public void onTagConnected(boolean connected) throws RemoteException {
             mCallbackMap.forEach((cb, ex) ->
-                    handleVoid2ArgCallback(connected, tag, cb::onTagConnected, ex));
+                    handleVoidCallback(connected, cb::onTagConnected, ex));
         }
 
         @Override
@@ -711,6 +719,13 @@
         }
 
         @Override
+        public void onEeListenActivated(boolean isActivated) throws RemoteException {
+            mEeListenActivated = isActivated;
+            mCallbackMap.forEach((cb, ex) ->
+                    handleVoidCallback(isActivated, cb::onEeListenActivated, ex));
+        }
+
+        @Override
         public void onStateUpdated(int state) throws RemoteException {
             mCallbackMap.forEach((cb, ex) ->
                     handleVoidCallback(state, cb::onStateUpdated, ex));
diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
index 5727f99..3d293f7 100644
--- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -52,10 +52,12 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.TreeMap;
 import java.util.regex.Pattern;
 
 /**
@@ -181,7 +183,8 @@
         this(info, onHost, description, staticAidGroups, dynamicAidGroups,
                 requiresUnlock, requiresScreenOn, bannerResource, uid,
                 settingsActivityName, offHost, staticOffHost, isEnabled,
-                new HashMap<String, Boolean>(), new HashMap<Pattern, Boolean>());
+                new HashMap<String, Boolean>(), new TreeMap<>(
+                        Comparator.comparing(Pattern::toString)));
     }
 
     /**
@@ -317,7 +320,8 @@
             mStaticAidGroups = new HashMap<String, AidGroup>();
             mDynamicAidGroups = new HashMap<String, AidGroup>();
             mAutoTransact = new HashMap<String, Boolean>();
-            mAutoTransactPatterns = new HashMap<Pattern, Boolean>();
+            mAutoTransactPatterns = new TreeMap<Pattern, Boolean>(
+                    Comparator.comparing(Pattern::toString));
             mOnHost = onHost;
 
             final int depth = parser.getDepth();
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index d8f04c5..eb28c3b 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -17,6 +17,7 @@
 package android.nfc.cardemulation;
 
 import android.Manifest;
+import android.annotation.CallbackExecutor;
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -33,15 +34,18 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.nfc.ComponentNameAndUser;
 import android.nfc.Constants;
 import android.nfc.Flags;
 import android.nfc.INfcCardEmulation;
+import android.nfc.INfcEventListener;
 import android.nfc.NfcAdapter;
 import android.os.Build;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.util.ArrayMap;
 import android.util.Log;
 
 import java.lang.annotation.Retention;
@@ -50,6 +54,8 @@
 import java.util.HexFormat;
 import java.util.List;
 import java.util.Locale;
+import java.util.Objects;
+import java.util.concurrent.Executor;
 import java.util.regex.Pattern;
 
 /**
@@ -1076,4 +1082,107 @@
             default -> throw new IllegalStateException("Unexpected value: " + route);
         };
     }
+
+    /** Listener for preferred service state changes. */
+    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+    public interface NfcEventListener {
+        /**
+         * This method is called when this package gains or loses preferred Nfc service status,
+         * either the Default Wallet Role holder (see {@link
+         * android.app.role.RoleManager#ROLE_WALLET}) or the preferred service of the foreground
+         * activity set with {@link #setPreferredService(Activity, ComponentName)}
+         *
+         * @param isPreferred true is this service has become the preferred Nfc service, false if it
+         *     is no longer the preferred service
+         */
+        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+        default void onPreferredServiceChanged(boolean isPreferred) {}
+
+        /**
+         * This method is called when observe mode has been enabled or disabled.
+         *
+         * @param isEnabled true if observe mode has been enabled, false if it has been disabled
+         */
+        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+        default void onObserveModeStateChanged(boolean isEnabled) {}
+    }
+
+    private final ArrayMap<NfcEventListener, Executor> mNfcEventListeners = new ArrayMap<>();
+
+    final INfcEventListener mINfcEventListener =
+            new INfcEventListener.Stub() {
+                public void onPreferredServiceChanged(ComponentNameAndUser componentNameAndUser) {
+                    if (!android.nfc.Flags.nfcEventListener()) {
+                        return;
+                    }
+                    boolean isPreferred =
+                            componentNameAndUser != null
+                                    && componentNameAndUser.getUserId()
+                                            == mContext.getUser().getIdentifier()
+                                    && componentNameAndUser.getComponentName() != null
+                                    && Objects.equals(
+                                            mContext.getPackageName(),
+                                            componentNameAndUser.getComponentName()
+                                                    .getPackageName());
+                    synchronized (mNfcEventListeners) {
+                        mNfcEventListeners.forEach(
+                                (listener, executor) -> {
+                                    executor.execute(
+                                            () -> listener.onPreferredServiceChanged(isPreferred));
+                                });
+                    }
+                }
+
+                public void onObserveModeStateChanged(boolean isEnabled) {
+                    if (!android.nfc.Flags.nfcEventListener()) {
+                        return;
+                    }
+                    synchronized (mNfcEventListeners) {
+                        mNfcEventListeners.forEach(
+                                (listener, executor) -> {
+                                    executor.execute(
+                                            () -> listener.onObserveModeStateChanged(isEnabled));
+                                });
+                    }
+                }
+            };
+
+    /**
+     * Register a listener for NFC Events.
+     *
+     * @param executor The Executor to run the call back with
+     * @param listener The listener to register
+     */
+    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+    public void registerNfcEventListener(
+            @NonNull @CallbackExecutor Executor executor, @NonNull NfcEventListener listener) {
+        if (!android.nfc.Flags.nfcEventListener()) {
+            return;
+        }
+        synchronized (mNfcEventListeners) {
+            mNfcEventListeners.put(listener, executor);
+            if (mNfcEventListeners.size() == 1) {
+                callService(() -> sService.registerNfcEventListener(mINfcEventListener));
+            }
+        }
+    }
+
+    /**
+     * Unregister a preferred service listener that was previously registered with {@link
+     * #registerNfcEventListener(Executor, NfcEventListener)}
+     *
+     * @param listener The previously registered listener to unregister
+     */
+    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+    public void unregisterNfcEventListener(@NonNull NfcEventListener listener) {
+        if (!android.nfc.Flags.nfcEventListener()) {
+            return;
+        }
+        synchronized (mNfcEventListeners) {
+            mNfcEventListeners.remove(listener);
+            if (mNfcEventListeners.size() == 0) {
+                callService(() -> sService.unregisterNfcEventListener(mINfcEventListener));
+            }
+        }
+    }
 }
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
index cd8e19c..4f601f0 100644
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ b/nfc/java/android/nfc/cardemulation/HostApduService.java
@@ -239,15 +239,6 @@
      */
     public static final int MSG_POLLING_LOOP = 4;
 
-    /**
-     * @hide
-     */
-    public static final int MSG_OBSERVE_MODE_CHANGE = 5;
-
-    /**
-     * @hide
-     */
-    public static final int MSG_PREFERRED_SERVICE_CHANGED = 6;
 
     /**
      * @hide
@@ -343,16 +334,6 @@
                         processPollingFrames(pollingFrames);
                     }
                     break;
-                case MSG_OBSERVE_MODE_CHANGE:
-                    if (android.nfc.Flags.nfcEventListener()) {
-                        onObserveModeStateChanged(msg.arg1 == 1);
-                    }
-                    break;
-                case MSG_PREFERRED_SERVICE_CHANGED:
-                    if (android.nfc.Flags.nfcEventListener()) {
-                        onPreferredServiceChanged(msg.arg1 == 1);
-                    }
-                    break;
                 default:
                 super.handleMessage(msg);
             }
@@ -462,25 +443,4 @@
      */
     public abstract void onDeactivated(int reason);
 
-
-    /**
-     * This method is called when this service is the preferred Nfc service and
-     * Observe mode has been enabled or disabled.
-     *
-     * @param isEnabled true if observe mode has been enabled, false if it has been disabled
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public void onObserveModeStateChanged(boolean isEnabled) {
-
-    }
-
-    /**
-     * This method is called when this service gains or loses preferred Nfc service status.
-     *
-     * @param isPreferred true is this service has become the preferred Nfc service,
-     * false if it is no longer the preferred service
-     */
-    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
-    public void onPreferredServiceChanged(boolean isPreferred) {
-    }
 }
diff --git a/services/core/java/com/android/server/SerialService.java b/services/core/java/com/android/server/SerialService.java
index 82c2038..71885fd 100644
--- a/services/core/java/com/android/server/SerialService.java
+++ b/services/core/java/com/android/server/SerialService.java
@@ -18,22 +18,30 @@
 
 import android.annotation.EnforcePermission;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.hardware.ISerialManager;
 import android.hardware.SerialManagerInternal;
 import android.os.ParcelFileDescriptor;
 import android.os.PermissionEnforcer;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 
 import java.io.File;
+import java.io.FileDescriptor;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.function.Supplier;
 
 @android.ravenwood.annotation.RavenwoodKeepWholeClass
 public class SerialService extends ISerialManager.Stub {
+    private static final String TAG = "SerialService";
+
     private final Context mContext;
 
     @GuardedBy("mSerialPorts")
@@ -50,7 +58,7 @@
             final String[] serialPorts = getSerialPorts(context);
             for (String serialPort : serialPorts) {
                 mSerialPorts.put(serialPort, () -> {
-                    return native_open(serialPort);
+                    return tryOpen(serialPort);
                 });
             }
         }
@@ -135,5 +143,14 @@
         }
     };
 
-    private native ParcelFileDescriptor native_open(String path);
+    private static @Nullable ParcelFileDescriptor tryOpen(String path) {
+        try {
+            FileDescriptor fd = Os.open(path, OsConstants.O_RDWR | OsConstants.O_NOCTTY, 0);
+            return new ParcelFileDescriptor(fd);
+        } catch (ErrnoException e) {
+            Slog.e(TAG, "Could not open: " + path, e);
+            // We return null to preserve API semantics from earlier implementation variants.
+            return null;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index 97c32b9..4993412 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -255,17 +255,6 @@
         }
     }
 
-    private static boolean isCompatibleLocale(Locale systemLocale, Locale keyboardLocale) {
-        // Different languages are never compatible
-        if (!systemLocale.getLanguage().equals(keyboardLocale.getLanguage())) {
-            return false;
-        }
-        // If both the system and the keyboard layout have a country specifier, they must be equal.
-        return TextUtils.isEmpty(systemLocale.getCountry())
-                || TextUtils.isEmpty(keyboardLocale.getCountry())
-                || systemLocale.getCountry().equals(keyboardLocale.getCountry());
-    }
-
     @MainThread
     private void updateKeyboardLayouts() {
         // Scan all input devices state for keyboard layouts that have been uninstalled.
@@ -953,21 +942,33 @@
             return;
         }
 
+        List<String> layoutNames = new ArrayList<>();
+        for (String layoutDesc : config.getConfiguredLayouts()) {
+            KeyboardLayout kl = getKeyboardLayout(layoutDesc);
+            if (kl == null) {
+                // b/349033234: Weird state with stale keyboard layout configured.
+                // Possibly due to race condition between KCM providing package being removed and
+                // corresponding layouts being removed from Datastore and cache.
+                // {@see updateKeyboardLayouts()}
+                //
+                // Ideally notification will be correctly shown after the keyboard layouts are
+                // configured again with the new package state.
+                return;
+            }
+            layoutNames.add(kl.getLabel());
+        }
         showKeyboardLayoutNotification(
                 r.getString(
                         R.string.keyboard_layout_notification_selected_title,
                         inputDevice.getName()),
-                createConfiguredNotificationText(mContext, config.getConfiguredLayouts()),
+                createConfiguredNotificationText(mContext, layoutNames),
                 inputDevice);
     }
 
     @MainThread
     private String createConfiguredNotificationText(@NonNull Context context,
-            @NonNull Set<String> selectedLayouts) {
+            @NonNull List<String> layoutNames) {
         final Resources r = context.getResources();
-        List<String> layoutNames = new ArrayList<>();
-        selectedLayouts.forEach(
-                (layoutDesc) -> layoutNames.add(getKeyboardLayout(layoutDesc).getLabel()));
         Collections.sort(layoutNames);
         switch (layoutNames.size()) {
             case 1:
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 7a710dc..662f916 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -55,7 +55,6 @@
         "com_android_server_powerstats_PowerStatsService.cpp",
         "com_android_server_power_stats_CpuPowerStatsCollector.cpp",
         "com_android_server_hint_HintManagerService.cpp",
-        "com_android_server_SerialService.cpp",
         "com_android_server_soundtrigger_middleware_AudioSessionProviderImpl.cpp",
         "com_android_server_soundtrigger_middleware_ExternalCaptureStateTracker.cpp",
         "com_android_server_stats_pull_StatsPullAtomService.cpp",
diff --git a/services/core/jni/com_android_server_SerialService.cpp b/services/core/jni/com_android_server_SerialService.cpp
deleted file mode 100644
index 6600c98..0000000
--- a/services/core/jni/com_android_server_SerialService.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#define LOG_TAG "SerialServiceJNI"
-#include "utils/Log.h"
-
-#include "jni.h"
-#include <nativehelper/JNIPlatformHelp.h>
-#include "android_runtime/AndroidRuntime.h"
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-namespace android
-{
-
-static struct parcel_file_descriptor_offsets_t
-{
-    jclass mClass;
-    jmethodID mConstructor;
-} gParcelFileDescriptorOffsets;
-
-static jobject android_server_SerialService_open(JNIEnv *env, jobject /* thiz */, jstring path)
-{
-    const char *pathStr = env->GetStringUTFChars(path, NULL);
-
-    int fd = open(pathStr, O_RDWR | O_NOCTTY);
-    if (fd < 0) {
-        ALOGE("could not open %s", pathStr);
-        env->ReleaseStringUTFChars(path, pathStr);
-        return NULL;
-    }
-    env->ReleaseStringUTFChars(path, pathStr);
-
-    jobject fileDescriptor = jniCreateFileDescriptor(env, fd);
-    if (fileDescriptor == NULL) {
-        close(fd);
-        return NULL;
-    }
-    return env->NewObject(gParcelFileDescriptorOffsets.mClass,
-        gParcelFileDescriptorOffsets.mConstructor, fileDescriptor);
-}
-
-
-static const JNINativeMethod method_table[] = {
-    { "native_open",                "(Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;",
-                                    (void*)android_server_SerialService_open },
-};
-
-int register_android_server_SerialService(JNIEnv *env)
-{
-    jclass clazz = env->FindClass("com/android/server/SerialService");
-    if (clazz == NULL) {
-        ALOGE("Can't find com/android/server/SerialService");
-        return -1;
-    }
-
-    clazz = env->FindClass("android/os/ParcelFileDescriptor");
-    LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.ParcelFileDescriptor");
-    gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
-    gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
-    LOG_FATAL_IF(gParcelFileDescriptorOffsets.mConstructor == NULL,
-                 "Unable to find constructor for android.os.ParcelFileDescriptor");
-
-    return jniRegisterNativeMethods(env, "com/android/server/SerialService",
-            method_table, NELEM(method_table));
-}
-
-};
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index 6464081..f9633e2 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -33,7 +33,6 @@
 int register_android_server_power_stats_CpuPowerStatsCollector(JNIEnv* env);
 int register_android_server_HintManagerService(JNIEnv* env);
 int register_android_server_storage_AppFuse(JNIEnv* env);
-int register_android_server_SerialService(JNIEnv* env);
 int register_android_server_SystemServer(JNIEnv* env);
 int register_android_server_UsbAlsaJackDetector(JNIEnv* env);
 int register_android_server_UsbAlsaMidiDevice(JNIEnv* env);
@@ -93,7 +92,6 @@
     register_android_server_PowerStatsService(env);
     register_android_server_power_stats_CpuPowerStatsCollector(env);
     register_android_server_HintManagerService(env);
-    register_android_server_SerialService(env);
     register_android_server_InputManager(env);
     register_android_server_LightsService(env);
     register_android_server_UsbDeviceManager(env);
diff --git a/services/tests/mockingservicestests/src/com/android/server/OWNERS b/services/tests/mockingservicestests/src/com/android/server/OWNERS
index dc5cb8d6..0c9f70c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/OWNERS
@@ -1,6 +1,6 @@
 per-file *Alarm* = file:/apex/jobscheduler/OWNERS
 per-file *AppStateTracker* = file:/apex/jobscheduler/OWNERS
-per-file *DeviceIdleController* = file:/apex/jobscheduler/OWNERS
+per-file *DeviceIdleController* = file:/apex/jobscheduler/DEVICE_IDLE_OWNERS
 per-file SensitiveContentProtectionManagerService* = file:/core/java/android/permission/OWNERS
 per-file RescuePartyTest.java = file:/packages/CrashRecovery/OWNERS
 per-file *Storage* = file:/core/java/android/os/storage/OWNERS
diff --git a/services/usb/OWNERS b/services/usb/OWNERS
index d35dbb56..2dff392 100644
--- a/services/usb/OWNERS
+++ b/services/usb/OWNERS
@@ -1,9 +1,9 @@
-aprasath@google.com
-kumarashishg@google.com
-sarup@google.com
 anothermark@google.com
+febinthattil@google.com
+aprasath@google.com
 badhri@google.com
 elaurent@google.com
 albertccwang@google.com
 jameswei@google.com
-howardyen@google.com
\ No newline at end of file
+howardyen@google.com
+kumarashishg@google.com
\ No newline at end of file