Merge "Add Technology Type info for the active secure element list" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 8ced596..9fc4fff 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -49,7 +49,7 @@
         "android.media.tv.flags-aconfig-java",
         "android.multiuser.flags-aconfig-java",
         "android.net.platform.flags-aconfig-java",
-        "android.net.vcn.flags-aconfig-java",
+        "android.net.vcn.flags-aconfig-java-export",
         "android.net.wifi.flags-aconfig-java",
         "android.nfc.flags-aconfig-java",
         "android.os.flags-aconfig-java",
@@ -90,7 +90,7 @@
         "com.android.media.flags.performance-aconfig-java",
         "com.android.media.flags.projection-aconfig-java",
         "com.android.net.thread.platform.flags-aconfig-java",
-        "com.android.ranging.flags.ranging-aconfig-java",
+        "com.android.ranging.flags.ranging-aconfig-java-export",
         "com.android.server.contextualsearch.flags-java",
         "com.android.server.flags.services-aconfig-java",
         "com.android.text.flags-aconfig-java",
@@ -1063,16 +1063,21 @@
 }
 
 // VCN
+// TODO:376339506 Move the VCN code, the flag declaration and
+// java_aconfig_library to framework-connectivity-b
 aconfig_declarations {
     name: "android.net.vcn.flags-aconfig",
     package: "android.net.vcn",
-    container: "system",
+    container: "com.android.tethering",
+    exportable: true,
     srcs: ["core/java/android/net/vcn/*.aconfig"],
 }
 
 java_aconfig_library {
-    name: "android.net.vcn.flags-aconfig-java",
+    name: "android.net.vcn.flags-aconfig-java-export",
     aconfig_declarations: "android.net.vcn.flags-aconfig",
+    mode: "exported",
+    min_sdk_version: "35",
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
@@ -1471,13 +1476,6 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
-// Ranging
-java_aconfig_library {
-    name: "com.android.ranging.flags.ranging-aconfig-java",
-    aconfig_declarations: "ranging_aconfig_flags",
-    defaults: ["framework-minus-apex-aconfig-java-defaults"],
-}
-
 // System Server
 aconfig_declarations {
     name: "android.systemserver.flags-aconfig",
diff --git a/Android.bp b/Android.bp
index dc48668..94e5e33 100644
--- a/Android.bp
+++ b/Android.bp
@@ -396,6 +396,8 @@
         "ext",
         "framework-updatable-stubs-module_libs_api",
         "unsupportedappusage",
+        // TODO(b/379770939): remove prod version of flags from other containers in framework
+        "aconfig_storage_stub",
     ],
     sdk_version: "core_platform",
     static_libs: [
diff --git a/cmds/interrupter/Android.bp b/cmds/interrupter/Android.bp
deleted file mode 100644
index d7f744d..0000000
--- a/cmds/interrupter/Android.bp
+++ /dev/null
@@ -1,20 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-cc_library_shared {
-    name: "interrupter",
-    host_supported: true,
-    srcs: ["interrupter.c"],
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wunused",
-        "-Wunreachable-code",
-    ],
-}
diff --git a/cmds/interrupter/interrupter.c b/cmds/interrupter/interrupter.c
deleted file mode 100644
index ae55515..0000000
--- a/cmds/interrupter/interrupter.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2012, 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.
- */
-
-
-/**
- * The probability of a syscall failing from 0.0 to 1.0
- */
-#define PROBABILITY 0.9
-
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-
-/* for various intercepted calls */
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-/* For builds on glibc */
-#define __USE_GNU
-#include <dlfcn.h>
-
-#include "interrupter.h"
-
-static int probability = PROBABILITY * RAND_MAX;
-
-static int maybe_interrupt() {
-    if (rand() < probability) {
-        return 1;
-    }
-    return 0;
-}
-
-DEFINE_INTERCEPT(read, ssize_t, int, void*, size_t);
-DEFINE_INTERCEPT(write, ssize_t, int, const void*, size_t);
-DEFINE_INTERCEPT(accept, int, int, struct sockaddr*, socklen_t*);
-DEFINE_INTERCEPT(creat, int, const char*, mode_t);
diff --git a/cmds/interrupter/interrupter.h b/cmds/interrupter/interrupter.h
deleted file mode 100644
index 9ad0277e..0000000
--- a/cmds/interrupter/interrupter.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2012, 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 CONCATENATE(arg1, arg2)   CONCATENATE1(arg1, arg2)
-#define CONCATENATE1(arg1, arg2)  CONCATENATE2(arg1, arg2)
-#define CONCATENATE2(arg1, arg2)  arg1##arg2
-
-#define INTERRUPTER(sym) \
-    if (real_##sym == NULL) \
-        __init_##sym(); \
-    if (maybe_interrupt()) { \
-        errno = EINTR; \
-        return -1; \
-    }
-
-#define CALL_FUNCTION_1(sym, ret, type1) \
-ret (*real_##sym)(type1) = NULL; \
-ret sym(type1 arg1) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1); \
-}
-
-#define CALL_FUNCTION_2(sym, ret, type1, type2) \
-ret (*real_##sym)(type1, type2) = NULL; \
-ret sym(type1 arg1, type2 arg2) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1, arg2); \
-}
-
-#define CALL_FUNCTION_3(sym, ret, type1, type2, type3) \
-ret (*real_##sym)(type1, type2, type3) = NULL; \
-ret sym(type1 arg1, type2 arg2, type3 arg3) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1, arg2, arg3); \
-}
-
-#define CALL_FUNCTION_4(sym, ret, type1, type2, type3, type4) \
-ret (*real_##sym)(type1, type2, type3, type4) = NULL; \
-ret sym(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1, arg2, arg3, arg4); \
-}
-
-#define CALL_FUNCTION_5(sym, ret, type1, type2, type3, type4, type5) \
-ret (*real_##sym)(type1, type2, type3, type4, type5) = NULL; \
-ret sym(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
-    INTERRUPTER(sym) \
-    return real_##sym(arg1, arg2, arg3, arg4, arg5); \
-}
-
-#define DEFINE_INTERCEPT_N(N, sym, ret, ...) \
-static void __init_##sym(void); \
-CONCATENATE(CALL_FUNCTION_, N)(sym, ret, __VA_ARGS__) \
-static void __init_##sym(void) { \
-    real_##sym = dlsym(RTLD_NEXT, #sym); \
-    if (real_##sym == NULL) { \
-        fprintf(stderr, "Error hooking " #sym ": %s\n", dlerror()); \
-    } \
-}
-
-#define INTERCEPT_NARG(...) INTERCEPT_NARG_N(__VA_ARGS__, INTERCEPT_RSEQ_N())
-#define INTERCEPT_NARG_N(...) INTERCEPT_ARG_N(__VA_ARGS__)
-#define INTERCEPT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
-#define INTERCEPT_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0
-
-#define DEFINE_INTERCEPT(sym, ret, ...) DEFINE_INTERCEPT_N(INTERCEPT_NARG(__VA_ARGS__), sym, ret, __VA_ARGS__)
diff --git a/core/api/current.txt b/core/api/current.txt
index c96d18d..eb769cea 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -13109,6 +13109,7 @@
     field public static final String FEATURE_BACKUP = "android.software.backup";
     field public static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
     field public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
+    field @FlaggedApi("com.android.ranging.flags.ranging_cs_enabled") public static final String FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING = "android.hardware.bluetooth_le.channel_sounding";
     field public static final String FEATURE_CAMERA = "android.hardware.camera";
     field public static final String FEATURE_CAMERA_ANY = "android.hardware.camera.any";
     field public static final String FEATURE_CAMERA_AR = "android.hardware.camera.ar";
@@ -22797,7 +22798,6 @@
     method public boolean isVendor();
     field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_MEMORY_SAFE = 1; // 0x1
     field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_SANDBOXED = 0; // 0x0
-    field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2; // 0x2
   }
 
   public static final class MediaCodecInfo.AudioCapabilities {
@@ -23688,7 +23688,6 @@
     field public static final int COLOR_TRANSFER_ST2084 = 6; // 0x6
     field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_MEMORY_SAFE = 2; // 0x2
     field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_SANDBOXED = 1; // 0x1
-    field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 4; // 0x4
     field public static final String KEY_AAC_DRC_ALBUM_MODE = "aac-drc-album-mode";
     field public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
     field public static final String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
@@ -29520,6 +29519,7 @@
     method @NonNull public java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate> getVcnUnderlyingNetworkPriorities();
     method public boolean hasGatewayOption(int);
     method @FlaggedApi("android.net.vcn.safe_mode_config") public boolean isSafeModeEnabled();
+    field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1; // 0xffffffff
     field public static final int VCN_GATEWAY_OPTION_ENABLE_DATA_STALL_RECOVERY_WITH_MOBILITY = 0; // 0x0
   }
 
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 0b891f6..529e7f9 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -260,6 +260,10 @@
 
 package android.net {
 
+  @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class ConnectivityFrameworkInitializerBaklava {
+    method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static void registerServiceWrappers();
+  }
+
   public class LocalSocket implements java.io.Closeable {
     ctor public LocalSocket(@NonNull java.io.FileDescriptor);
   }
@@ -319,6 +323,25 @@
 
 }
 
+package android.net.vcn {
+
+  @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public final class VcnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
+    method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int describeContents();
+    method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public long getApplicableRedactions();
+    method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public int getMinUdpPort4500NatTimeoutSeconds();
+    method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.TransportInfo makeCopy(long);
+    method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnTransportInfo> CREATOR;
+  }
+
+  @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public static final class VcnTransportInfo.Builder {
+    ctor @FlaggedApi("android.net.vcn.mainline_vcn_module_api") public VcnTransportInfo.Builder();
+    method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo build();
+    method @FlaggedApi("android.net.vcn.mainline_vcn_module_api") @NonNull public android.net.vcn.VcnTransportInfo.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int);
+  }
+
+}
+
 package android.nfc {
 
   public class NfcServiceManager {
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 3f6e65b..22566b7 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -639,43 +639,8 @@
 
 // protolog end
 
-// Whether to enable read-only system feature codegen.
-gen_readonly_feature_apis = select(release_flag("RELEASE_USE_SYSTEM_FEATURE_BUILD_FLAGS"), {
-    true: "true",
-    false: "false",
-    default: "false",
-})
-
-// Generates com.android.internal.pm.RoSystemFeatures, optionally compiling in
-// details about fixed system features defined by build flags. When disabled,
-// the APIs are simply passthrough stubs with no meaningful side effects.
-// TODO(b/203143243): Implement the `--feature=` aggregation  directly with a native soong module.
-genrule {
+java_system_features_srcs {
     name: "systemfeatures-gen-srcs",
-    cmd: "$(location systemfeatures-gen-tool) com.android.internal.pm.RoSystemFeatures " +
-        // --readonly=false (default) makes the codegen an effective no-op passthrough API.
-        " --readonly=" + gen_readonly_feature_apis +
-        " --feature=AUTOMOTIVE:" + select(release_flag("RELEASE_SYSTEM_FEATURE_AUTOMOTIVE"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=EMBEDDED:" + select(release_flag("RELEASE_SYSTEM_FEATURE_EMBEDDED"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=LEANBACK:" + select(release_flag("RELEASE_SYSTEM_FEATURE_LEANBACK"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=PC:" + select(release_flag("RELEASE_SYSTEM_FEATURE_PC"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=TELEVISION:" + select(release_flag("RELEASE_SYSTEM_FEATURE_TELEVISION"), {
-            any @ value: value,
-            default: "",
-        }) + " --feature=WATCH:" + select(release_flag("RELEASE_SYSTEM_FEATURE_WATCH"), {
-            any @ value: value,
-            default: "",
-        }) + " > $(out)",
-    out: [
-        "RoSystemFeatures.java",
-    ],
-    tools: ["systemfeatures-gen-tool"],
+    full_class_name: "com.android.internal.pm.RoSystemFeatures",
+    visibility: ["//visibility:private"],
 }
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 093dad6..918ae1c 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -150,6 +150,7 @@
 import android.media.tv.tunerresourcemanager.TunerResourceManager;
 import android.nearby.NearbyFrameworkInitializer;
 import android.net.ConnectivityFrameworkInitializer;
+import android.net.ConnectivityFrameworkInitializerBaklava;
 import android.net.ConnectivityFrameworkInitializerTiramisu;
 import android.net.INetworkPolicyManager;
 import android.net.IPacProxyManager;
@@ -160,7 +161,6 @@
 import android.net.PacProxyManager;
 import android.net.TetheringManager;
 import android.net.VpnManager;
-import android.net.vcn.VcnFrameworkInitializer;
 import android.net.wifi.WifiFrameworkInitializer;
 import android.net.wifi.nl80211.WifiNl80211Manager;
 import android.net.wifi.sharedconnectivity.app.SharedConnectivityManager;
@@ -1691,7 +1691,7 @@
             OnDevicePersonalizationFrameworkInitializer.registerServiceWrappers();
             DeviceLockFrameworkInitializer.registerServiceWrappers();
             VirtualizationFrameworkInitializer.registerServiceWrappers();
-            VcnFrameworkInitializer.registerServiceWrappers();
+            ConnectivityFrameworkInitializerBaklava.registerServiceWrappers();
 
             if (com.android.server.telecom.flags.Flags.telecomMainlineBlockedNumbersManager()) {
                 ProviderFrameworkInitializer.registerServiceWrappers();
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 744f019..2a5c533 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -4484,7 +4484,6 @@
      * @see #DISPLAY_HASH_SERVICE
      * @see android.view.displayhash.DisplayHashManager
      */
-    // TODO(b/347269120): Re-add @Nullable
     public abstract Object getSystemService(@ServiceName @NonNull String name);
 
     /**
@@ -4529,7 +4528,6 @@
      * <b>never</b> throw a {@link RuntimeException} if the name is not supported.
      */
     @SuppressWarnings("unchecked")
-    // TODO(b/347269120): Re-add @Nullable
     public final <T> T getSystemService(@NonNull Class<T> serviceClass) {
         // Because subclasses may override getSystemService(String) we cannot
         // perform a lookup by class alone.  We must first map the class to its
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 79fa6ea..77aa628 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -953,7 +953,6 @@
     }
 
     @Override
-    // TODO(b/347269120): Re-add @Nullable
     public Object getSystemService(String name) {
         return mBase.getSystemService(name);
     }
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 4f06209..0113129 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -451,6 +451,13 @@
      * Value of {@link #colorMode} indicating that the activity should use a
      * high dynamic range if the presentation display supports it.
      *
+     * <p>Note: This does not impact SurfaceViews or SurfaceControls, as those have their own
+     * independent HDR support.</p>
+     *
+     * <p><b>Important:</b> Although this value was added in API 26, it is strongly recommended
+     * to avoid using it until API 34 which is when HDR support for the UI toolkit was officially
+     * added.</p>
+     *
      * @see android.R.attr#colorMode
      */
     public static final int COLOR_MODE_HDR = 2;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 2df187b..0ed9c87 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3164,6 +3164,16 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device is capable of ranging with
+     * other devices using channel sounding via Bluetooth Low Energy radio.
+     */
+    @FlaggedApi(com.android.ranging.flags.Flags.FLAG_RANGING_CS_ENABLED)
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING =
+             "android.hardware.bluetooth_le.channel_sounding";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device has a camera facing away
      * from the screen.
      */
diff --git a/core/java/android/net/vcn/VcnFrameworkInitializer.java b/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java
similarity index 86%
rename from core/java/android/net/vcn/VcnFrameworkInitializer.java
rename to core/java/android/net/ConnectivityFrameworkInitializerBaklava.java
index 8cb213b..1f0fa92 100644
--- a/core/java/android/net/vcn/VcnFrameworkInitializer.java
+++ b/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java
@@ -14,15 +14,21 @@
  * limitations under the License.
  */
 
-package android.net.vcn;
+package android.net;
 
+import static android.net.vcn.Flags.FLAG_MAINLINE_VCN_MODULE_API;
+
+import android.annotation.FlaggedApi;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.app.SystemServiceRegistry;
 import android.compat.Compatibility;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledSince;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.net.vcn.IVcnManagementService;
+import android.net.vcn.VcnManager;
 import android.os.Build;
 import android.os.SystemProperties;
 
@@ -31,8 +37,9 @@
  *
  * @hide
  */
-// TODO: Expose it as @SystemApi(client = MODULE_LIBRARIES)
-public final class VcnFrameworkInitializer {
+@FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class ConnectivityFrameworkInitializerBaklava {
     /**
      * Starting with {@link VANILLA_ICE_CREAM}, Telephony feature flags (e.g. {@link
      * PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}) are being checked before returning managers
@@ -55,7 +62,7 @@
      */
     private static final int VENDOR_API_FOR_ANDROID_V = 202404;
 
-    private VcnFrameworkInitializer() {}
+    private ConnectivityFrameworkInitializerBaklava() {}
 
     // Suppressing AndroidFrameworkCompatChange because we're querying vendor
     // partition SDK level, not application's target SDK version (which BTW we
@@ -86,7 +93,10 @@
      *
      * @throws IllegalStateException if this is called anywhere besides {@link
      *     SystemServiceRegistry}.
+     * @hide
      */
+    @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static void registerServiceWrappers() {
         SystemServiceRegistry.registerContextAwareService(
                 VcnManager.VCN_MANAGEMENT_SERVICE_STRING,
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
index af93c96..3219ce8 100644
--- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
+++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
@@ -16,6 +16,7 @@
 package android.net.vcn;
 
 import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_MOBIKE;
+import static android.net.vcn.Flags.FLAG_MAINLINE_VCN_MODULE_API;
 import static android.net.vcn.Flags.FLAG_SAFE_MODE_CONFIG;
 import static android.net.vcn.VcnUnderlyingNetworkTemplate.MATCH_REQUIRED;
 
@@ -82,7 +83,15 @@
  * </ul>
  */
 public final class VcnGatewayConnectionConfig {
-    /** @hide */
+    /**
+     * Minimum NAT timeout not set.
+     *
+     * <p>When the timeout is not set, the device will automatically choose a keepalive interval and
+     * may reduce the keepalive frequency for power-optimization.
+     */
+    @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+    // This constant does not represent a minimum value. It indicates the value is not configured.
+    @SuppressLint("MinMaxConstant")
     public static final int MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET = -1;
 
     /** @hide */
@@ -773,7 +782,7 @@
          *
          * @param minUdpPort4500NatTimeoutSeconds the maximum keepalive timeout supported by the VCN
          *     Gateway Connection, generally the minimum duration a NAT mapping is cached on the VCN
-         *     Gateway.
+         *     Gateway; or {@link MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET} to clear this value.
          * @return this {@link Builder} instance, for chaining
          */
         @NonNull
@@ -781,8 +790,10 @@
                 @IntRange(from = MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS)
                         int minUdpPort4500NatTimeoutSeconds) {
             Preconditions.checkArgument(
-                    minUdpPort4500NatTimeoutSeconds >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
-                    "Timeout must be at least 120s");
+                    minUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET
+                            || minUdpPort4500NatTimeoutSeconds
+                                    >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
+                    "Timeout must be at least 120s or MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET");
 
             mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
             return this;
diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java
index 1fc91ee..3638429 100644
--- a/core/java/android/net/vcn/VcnTransportInfo.java
+++ b/core/java/android/net/vcn/VcnTransportInfo.java
@@ -17,13 +17,16 @@
 package android.net.vcn;
 
 import static android.net.NetworkCapabilities.REDACT_FOR_NETWORK_SETTINGS;
+import static android.net.vcn.Flags.FLAG_MAINLINE_VCN_MODULE_API;
 import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS;
 import static android.net.vcn.VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.net.NetworkCapabilities;
 import android.net.TransportInfo;
 import android.net.wifi.WifiInfo;
@@ -52,23 +55,29 @@
  * @hide
  */
 // TODO: Do not store WifiInfo and subscription ID in VcnTransportInfo anymore
-public class VcnTransportInfo implements TransportInfo, Parcelable {
+@FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class VcnTransportInfo implements TransportInfo, Parcelable {
     @Nullable private final WifiInfo mWifiInfo;
     private final int mSubId;
     private final int mMinUdpPort4500NatTimeoutSeconds;
 
+    /** @hide */
     public VcnTransportInfo(@NonNull WifiInfo wifiInfo) {
         this(wifiInfo, INVALID_SUBSCRIPTION_ID, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
     }
 
+    /** @hide */
     public VcnTransportInfo(@NonNull WifiInfo wifiInfo, int minUdpPort4500NatTimeoutSeconds) {
         this(wifiInfo, INVALID_SUBSCRIPTION_ID, minUdpPort4500NatTimeoutSeconds);
     }
 
+    /** @hide */
     public VcnTransportInfo(int subId) {
         this(null /* wifiInfo */, subId, MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET);
     }
 
+    /** @hide */
     public VcnTransportInfo(int subId, int minUdpPort4500NatTimeoutSeconds) {
         this(null /* wifiInfo */, subId, minUdpPort4500NatTimeoutSeconds);
     }
@@ -86,6 +95,7 @@
      * <p>If the underlying Network for the associated VCN is Cellular, returns null.
      *
      * @return the WifiInfo if there is an underlying WiFi connection, else null.
+     * @hide
      */
     @Nullable
     public WifiInfo getWifiInfo() {
@@ -100,17 +110,27 @@
      *
      * @return the Subscription ID if a cellular underlying Network is present, else {@link
      *     android.telephony.SubscriptionManager#INVALID_SUBSCRIPTION_ID}.
+     * @hide
      */
     public int getSubId() {
         return mSubId;
     }
 
     /**
-     * Get the VCN provided UDP port 4500 NAT timeout
+     * Get the minimum duration that the VCN Gateway guarantees to preserve a NAT mapping.
      *
-     * @return the UDP 4500 NAT timeout, or
+     * <p>To ensure uninterrupted connectivity, the device must send keepalive packets before the
+     * timeout. Failure to do so may result in the mapping being cleared and connection termination.
+     * This value is used as a power-optimization hint for other IKEv2/IPsec use cases (e.g. VPNs,
+     * or IWLAN) to reduce the necessary keepalive frequency, thus conserving power and data.
+     *
+     * @return the minimum duration that the VCN Gateway guarantees to preserve a NAT mapping, or
      *     VcnGatewayConnectionConfig.MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET if not set.
+     * @see VcnGatewayConnectionConfig.Builder#setMinUdpPort4500NatTimeoutSeconds(int)
+     * @hide
      */
+    @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public int getMinUdpPort4500NatTimeoutSeconds() {
         return mMinUdpPort4500NatTimeoutSeconds;
     }
@@ -129,12 +149,21 @@
                 && mMinUdpPort4500NatTimeoutSeconds == that.mMinUdpPort4500NatTimeoutSeconds;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     *
+     * @hide
+     */
+    @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @Override
     public int describeContents() {
         return 0;
     }
 
+    /** @hide */
+    @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @Override
     @NonNull
     public TransportInfo makeCopy(long redactions) {
@@ -149,6 +178,9 @@
                 mMinUdpPort4500NatTimeoutSeconds);
     }
 
+    /** @hide */
+    @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @Override
     public long getApplicableRedactions() {
         long redactions = REDACT_FOR_NETWORK_SETTINGS;
@@ -161,7 +193,13 @@
         return redactions;
     }
 
-    /** {@inheritDoc} */
+    /**
+     * {@inheritDoc}
+     *
+     * @hide
+     */
+    @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(mSubId);
@@ -174,7 +212,13 @@
         return "VcnTransportInfo { mWifiInfo = " + mWifiInfo + ", mSubId = " + mSubId + " }";
     }
 
-    /** Implement the Parcelable interface */
+    /**
+     * Implement the Parcelable interface
+     *
+     * @hide
+     */
+    @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final @NonNull Creator<VcnTransportInfo> CREATOR =
             new Creator<VcnTransportInfo>() {
                 public VcnTransportInfo createFromParcel(Parcel in) {
@@ -201,37 +245,63 @@
                 }
             };
 
-    /** This class can be used to construct a {@link VcnTransportInfo}. */
+    /**
+     * This class can be used to construct a {@link VcnTransportInfo}.
+     *
+     * @hide
+     */
+    @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
     public static final class Builder {
         private int mMinUdpPort4500NatTimeoutSeconds = MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET;
 
-        /** Construct Builder */
+        /**
+         * Construct Builder
+         *
+         * @hide
+         */
+        @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
         public Builder() {}
 
         /**
-         * Sets the maximum supported IKEv2/IPsec NATT keepalive timeout.
+         * Set the minimum duration that the VCN Gateway guarantees to preserve a NAT mapping.
          *
          * <p>This is used as a power-optimization hint for other IKEv2/IPsec use cases (e.g. VPNs,
          * or IWLAN) to reduce the necessary keepalive frequency, thus conserving power and data.
          *
-         * @param minUdpPort4500NatTimeoutSeconds the maximum keepalive timeout supported by the VCN
-         *     Gateway Connection, generally the minimum duration a NAT mapping is cached on the VCN
-         *     Gateway.
+         * @param minUdpPort4500NatTimeoutSeconds the minimum duration that the VCN Gateway
+         *     guarantees to preserve a NAT mapping, or {@link MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET}
+         *     to clear this value. To ensure uninterrupted connectivity, the device must send
+         *     keepalive packets within this interval. Failure to do so may result in the mapping
+         *     being cleared and connection termination.
          * @return this {@link Builder} instance, for chaining
+         * @see VcnGatewayConnectionConfig.Builder#setMinUdpPort4500NatTimeoutSeconds(int)
+         * @hide
          */
+        @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
         @NonNull
         public Builder setMinUdpPort4500NatTimeoutSeconds(
                 @IntRange(from = MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS)
                         int minUdpPort4500NatTimeoutSeconds) {
             Preconditions.checkArgument(
-                    minUdpPort4500NatTimeoutSeconds >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
-                    "Timeout must be at least 120s");
+                    minUdpPort4500NatTimeoutSeconds == MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET
+                            || minUdpPort4500NatTimeoutSeconds
+                                    >= MIN_UDP_PORT_4500_NAT_TIMEOUT_SECONDS,
+                    "Timeout must be at least 120s or MIN_UDP_PORT_4500_NAT_TIMEOUT_UNSET");
 
             mMinUdpPort4500NatTimeoutSeconds = minUdpPort4500NatTimeoutSeconds;
             return Builder.this;
         }
 
-        /** Build a VcnTransportInfo instance */
+        /**
+         * Build a VcnTransportInfo instance
+         *
+         * @hide
+         */
+        @FlaggedApi(FLAG_MAINLINE_VCN_MODULE_API)
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
         @NonNull
         public VcnTransportInfo build() {
             return new VcnTransportInfo(
diff --git a/core/java/android/net/vcn/flags.aconfig b/core/java/android/net/vcn/flags.aconfig
index 1b2c575..b461f95 100644
--- a/core/java/android/net/vcn/flags.aconfig
+++ b/core/java/android/net/vcn/flags.aconfig
@@ -1,5 +1,5 @@
 package: "android.net.vcn"
-container: "system"
+container: "com.android.tethering"
 
 flag {
     name: "safe_mode_config"
@@ -15,14 +15,4 @@
      description: "Expose APIs from VCN for mainline migration"
      is_exported: true
      bug: "376339506"
-}
-
-flag {
-    name: "fix_config_garbage_collection"
-    namespace: "vcn"
-    description: "Handle race condition in subscription change"
-    bug: "370862489"
-    metadata {
-      purpose: PURPOSE_BUGFIX
-    }
 }
\ No newline at end of file
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index e63b664..94259d7 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -89,6 +89,8 @@
 per-file DdmSyncStageUpdater.java = sanglardf@google.com, rpaquay@google.com
 
 # PerformanceHintManager
+per-file CpuHeadroom*.aidl = file:/ADPF_OWNERS
+per-file GpuHeadroom*.aidl = file:/ADPF_OWNERS
 per-file PerformanceHintManager.java = file:/ADPF_OWNERS
 per-file WorkDuration.java = file:/ADPF_OWNERS
 per-file IHintManager.aidl = file:/ADPF_OWNERS
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index d5630fd..4123209 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -214,7 +214,7 @@
             if (mFrozenCalleePolicy != FROZEN_CALLEE_POLICY_UNSET) {
                 try {
                     mBinder.removeFrozenStateChangeCallback(this);
-                } catch (UnsupportedOperationException e) {
+                } catch (UnsupportedOperationException | IllegalArgumentException e) {
                     // The kernel does not support frozen notifications. Ignore the error and move
                     // on.
                 }
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1d70d18..455e680 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -830,7 +830,8 @@
 
     /**
      * Sets the desired amount of HDR headroom to be used when HDR content is presented on this
-     * SurfaceView.
+     * SurfaceView. This is expressed as the ratio of maximum HDR white point over the SDR
+     * white point, not as absolute nits.
      *
      * <p>By default the system will choose an amount of HDR headroom that is appropriate
      * for the underlying device capabilities & bit-depth of the panel. However, for some types
@@ -844,6 +845,10 @@
      * See {@link Display#getHdrSdrRatio()} for more information as well as how to query the
      * current value.</p>
      *
+     * <p>Note: This API operates independently of both the
+     * {@link Window#setColorMode Widow color mode} and the
+     * {@link Window#setDesiredHdrHeadroom Window desiredHdrHeadroom}</p>
+     *
      * @param desiredHeadroom The amount of HDR headroom that is desired. Must be >= 1.0 (no HDR)
      *                        and <= 10,000.0. Passing 0.0 will reset to the default, automatically
      *                        chosen value.
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 0582afe..cbee563 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1334,6 +1334,9 @@
      * <p>The requested color mode is not guaranteed to be honored. Please refer to
      * {@link #getColorMode()} for more information.</p>
      *
+     * <p>Note: This does not impact SurfaceViews or SurfaceControls, as those have their own
+     * independent color mode and HDR parameters.</p>
+     *
      * @see #getColorMode()
      * @see Display#isWideColorGamut()
      * @see Configuration#isScreenWideColorGamut()
@@ -1361,6 +1364,9 @@
      * See {@link Display#getHdrSdrRatio()} for more information as well as how to query the
      * current value.</p>
      *
+     * <p>Note: This does not impact SurfaceViews or SurfaceControls, as those have their own
+     * independent desired HDR headroom and HDR capabilities.</p>
+     *
      * @param desiredHeadroom The amount of HDR headroom that is desired. Must be >= 1.0 (no HDR)
      *                        and <= 10,000.0. Passing 0.0 will reset to the default, automatically
      *                        chosen value.
diff --git a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
index 75aca1b..7ce2ed8 100644
--- a/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
+++ b/core/tests/systemproperties/src/android/os/SystemPropertiesTest.java
@@ -23,10 +23,11 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.platform.test.ravenwood.RavenwoodConfig;
+import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 
+import org.junit.Rule;
 import org.junit.Test;
 
 import java.util.Objects;
@@ -39,8 +40,8 @@
     private static final String PERSIST_KEY = "persist.sys.testkey";
     private static final String NONEXIST_KEY = "doesnotexist_2341431";
 
-    @RavenwoodConfig.Config
-    public static final RavenwoodConfig mRavenwood = new RavenwoodConfig.Builder()
+    @Rule
+    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
             .setSystemPropertyMutable(KEY, null)
             .setSystemPropertyMutable(UNSET_KEY, null)
             .setSystemPropertyMutable(PERSIST_KEY, null)
diff --git a/core/xsd/permission.xsd b/core/xsd/permission.xsd
index 0ec8f7d..0a0ca7c 100644
--- a/core/xsd/permission.xsd
+++ b/core/xsd/permission.xsd
@@ -43,6 +43,7 @@
                 <xs:element name="disabled-until-used-preinstalled-carrier-app" type="disabled-until-used-preinstalled-carrier-app"/>
                 <xs:element name="privapp-permissions" type="privapp-permissions"/>
                 <xs:element name="oem-permissions" type="oem-permissions"/>
+                <xs:element name="signature-permissions" type="signature-permissions"/>
                 <xs:element name="hidden-api-whitelisted-app" type="hidden-api-whitelisted-app"/>
                 <xs:element name="allow-association" type="allow-association"/>
                 <xs:element name="bugreport-whitelisted" type="bugreport-whitelisted"/>
@@ -156,6 +157,21 @@
         </xs:sequence>
         <xs:attribute name="package" type="xs:string"/>
     </xs:complexType>
+    <xs:complexType name="signature-permissions">
+        <xs:sequence>
+            <xs:element name="permission" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:string"/>
+                </xs:complexType>
+            </xs:element>
+            <xs:element name="deny-permission" minOccurs="0" maxOccurs="unbounded">
+                <xs:complexType>
+                    <xs:attribute name="name" type="xs:string"/>
+                </xs:complexType>
+            </xs:element>
+        </xs:sequence>
+        <xs:attribute name="package" type="xs:string"/>
+    </xs:complexType>
     <xs:complexType name="hidden-api-whitelisted-app">
         <xs:attribute name="package" type="xs:string"/>
     </xs:complexType>
diff --git a/core/xsd/schema/current.txt b/core/xsd/schema/current.txt
index f3beea1..cdec6ab 100644
--- a/core/xsd/schema/current.txt
+++ b/core/xsd/schema/current.txt
@@ -183,6 +183,7 @@
     method public java.util.List<com.android.xml.permission.configfile.OemPermissions> getOemPermissions_optional();
     method public java.util.List<com.android.xml.permission.configfile.Permission> getPermission_optional();
     method public java.util.List<com.android.xml.permission.configfile.PrivappPermissions> getPrivappPermissions_optional();
+    method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions> getSignaturePermissions_optional();
     method public java.util.List<com.android.xml.permission.configfile.SplitPermission> getSplitPermission_optional();
     method public java.util.List<com.android.xml.permission.configfile.SystemUserBlacklistedApp> getSystemUserBlacklistedApp_optional();
     method public java.util.List<com.android.xml.permission.configfile.SystemUserWhitelistedApp> getSystemUserWhitelistedApp_optional();
@@ -209,6 +210,26 @@
     method public void setName(String);
   }
 
+  public class SignaturePermissions {
+    ctor public SignaturePermissions();
+    method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions.DenyPermission> getDenyPermission();
+    method public java.util.List<com.android.xml.permission.configfile.SignaturePermissions.Permission> getPermission();
+    method public String get_package();
+    method public void set_package(String);
+  }
+
+  public static class SignaturePermissions.DenyPermission {
+    ctor public SignaturePermissions.DenyPermission();
+    method public String getName();
+    method public void setName(String);
+  }
+
+  public static class SignaturePermissions.Permission {
+    ctor public SignaturePermissions.Permission();
+    method public String getName();
+    method public void setName(String);
+  }
+
   public class SplitPermission {
     ctor public SplitPermission();
     method public java.util.List<com.android.xml.permission.configfile.SplitPermission.Library> getLibrary();
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 96edd63..782db35 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -1876,6 +1876,8 @@
      * Codecs with this security model is not included in
      * {@link MediaCodecList#REGULAR_CODECS}, but included in
      * {@link MediaCodecList#ALL_CODECS}.
+     *
+     * @hide
      */
     @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC)
     public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2;
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index bd65b2e..bc09aee 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -1748,6 +1748,7 @@
             (1 << MediaCodecInfo.SECURITY_MODEL_MEMORY_SAFE);
     /**
      * Flag for {@link MediaCodecInfo#SECURITY_MODEL_TRUSTED_CONTENT_ONLY}.
+     * @hide
      */
     @FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC)
     public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY =
@@ -1759,8 +1760,7 @@
      * The associated value is a flag of the following values:
      * {@link FLAG_SECURITY_MODEL_SANDBOXED},
      * {@link FLAG_SECURITY_MODEL_MEMORY_SAFE},
-     * {@link FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY}. The default value is
-     * {@link FLAG_SECURITY_MODEL_SANDBOXED}.
+     * The default value is {@link FLAG_SECURITY_MODEL_SANDBOXED}.
      * <p>
      * When passed to {@link MediaCodecList#findDecoderForFormat} or
      * {@link MediaCodecList#findEncoderForFormat}, MediaCodecList filters
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 9a7a39f..2aa73db 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -202,6 +202,7 @@
     method public boolean categoryAllowsForegroundPreference(String);
     method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public java.util.List<java.lang.String> getAidsForPreferredPaymentService();
     method public java.util.List<java.lang.String> getAidsForService(android.content.ComponentName, String);
+    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public int getDefaultNfcSubscriptionId();
     method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public CharSequence getDescriptionForPreferredPaymentService();
     method public static android.nfc.cardemulation.CardEmulation getInstance(android.nfc.NfcAdapter);
     method @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public String getRouteDestinationForPreferredPaymentService();
@@ -228,6 +229,10 @@
     field public static final String CATEGORY_PAYMENT = "payment";
     field public static final String EXTRA_CATEGORY = "category";
     field public static final String EXTRA_SERVICE_COMPONENT = "component";
+    field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3; // 0x3
+    field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1; // 0x1
+    field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2; // 0x2
+    field @FlaggedApi("android.nfc.nfc_event_listener") public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0; // 0x0
     field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DEFAULT = 3; // 0x3
     field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_DH = 0; // 0x0
     field @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_ESE = 1; // 0x1
@@ -239,8 +244,13 @@
   }
 
   @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventListener {
+    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidConflictOccurred(@NonNull String);
+    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onAidNotRouted(@NonNull String);
+    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onInternalErrorReported(int);
+    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onNfcStateChanged(int);
     method @FlaggedApi("android.nfc.nfc_event_listener") public default void onObserveModeStateChanged(boolean);
     method @FlaggedApi("android.nfc.nfc_event_listener") public default void onPreferredServiceChanged(boolean);
+    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onRemoteFieldChanged(boolean);
   }
 
   public abstract class HostApduService extends android.app.Service {
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 25d9d35..031ed73 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -60,14 +60,15 @@
     method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.Map<java.lang.String,java.lang.Integer> getActiveNfceeList();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.nfc.RoutingStatus getRoutingStatus();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.List<android.nfc.NfcRoutingTableEntry> getRoutingTable();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public android.nfc.T4tNdefNfcee getT4tNdefNfcee();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean hasUserEnabledNfc();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isAutoChangeEnabled();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagPresent();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overwriteRoutingTable(int, int, int, int);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void pausePolling(int);
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int pausePolling(int);
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback);
-    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void resumePolling();
+    method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int resumePolling();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setAutoChangeEnabled(boolean);
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void setControllerAlwaysOnMode(int);
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState();
@@ -83,6 +84,8 @@
     field public static final int HCE_ACTIVATE = 1; // 0x1
     field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2
     field public static final int HCE_DEACTIVATE = 3; // 0x3
+    field public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2; // 0x2
+    field public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1; // 0x1
     field public static final int STATUS_OK = 0; // 0x0
     field public static final int STATUS_UNKNOWN_ERROR = 1; // 0x1
   }
@@ -96,6 +99,7 @@
     method public void onDisableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onDisableStarted();
     method public void onEeListenActivated(boolean);
+    method public void onEeUpdated();
     method public void onEnableFinished(int);
     method public void onEnableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onEnableStarted();
@@ -119,6 +123,11 @@
 
   @FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry {
     method public int getNfceeId();
+    method public int getType();
+    field public static final int TYPE_AID = 0; // 0x0
+    field public static final int TYPE_PROTOCOL = 1; // 0x1
+    field public static final int TYPE_SYSTEM_CODE = 3; // 0x3
+    field public static final int TYPE_TECHNOLOGY = 2; // 0x2
   }
 
   @FlaggedApi("android.nfc.nfc_oem_extension") public final class OemLogItems implements android.os.Parcelable {
@@ -178,6 +187,47 @@
     field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int TECHNOLOGY_V = 3; // 0x3
   }
 
+  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfcee {
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int clearData();
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isOperationOngoing();
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isSupported();
+    method @Nullable @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public android.nfc.T4tNdefNfceeCcFileInfo readCcfile();
+    method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public byte[] readData(@IntRange(from=0, to=65535) int);
+    method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @WorkerThread public int writeData(@IntRange(from=0, to=65535) int, @NonNull byte[]);
+    field public static final int CLEAR_DATA_FAILED_INTERNAL = 0; // 0x0
+    field public static final int CLEAR_DATA_SUCCESS = 1; // 0x1
+    field public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6; // 0xfffffffa
+    field public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7; // 0xfffffff9
+    field public static final int WRITE_DATA_ERROR_INTERNAL = -1; // 0xffffffff
+    field public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4; // 0xfffffffc
+    field public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5; // 0xfffffffb
+    field public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8; // 0xfffffff8
+    field public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3; // 0xfffffffd
+    field public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2; // 0xfffffffe
+    field public static final int WRITE_DATA_SUCCESS = 0; // 0x0
+  }
+
+  @FlaggedApi("android.nfc.nfc_oem_extension") public final class T4tNdefNfceeCcFileInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @IntRange(from=15, to=32767) public int getCcFileLength();
+    method @IntRange(from=0xffffffff, to=65535) public int getFileId();
+    method @IntRange(from=15, to=65535) public int getMaxReadLength();
+    method @IntRange(from=5, to=32767) public int getMaxSize();
+    method @IntRange(from=13, to=65535) public int getMaxWriteLength();
+    method public int getReadAccess();
+    method public int getVersion();
+    method public int getWriteAccess();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.T4tNdefNfceeCcFileInfo> CREATOR;
+    field public static final int READ_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
+    field public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
+    field public static final int VERSION_2_0 = 32; // 0x20
+    field public static final int VERSION_3_0 = 48; // 0x30
+    field public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 128; // 0x80
+    field public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0; // 0x0
+    field public static final int WRITE_ACCESS_NOT_GRANTED = 255; // 0xff
+  }
+
 }
 
 package android.nfc.cardemulation {
@@ -185,14 +235,19 @@
   public final class CardEmulation {
     method @FlaggedApi("android.permission.flags.wallet_role_enabled") @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static android.content.ComponentName getPreferredPaymentService(@NonNull android.content.Context);
     method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int);
-    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void overrideRoutingTable(@NonNull android.app.Activity, int, int);
-    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void recoverRoutingTable(@NonNull android.app.Activity);
+    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void overrideRoutingTable(@NonNull android.app.Activity, int, int);
+    method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void recoverRoutingTable(@NonNull android.app.Activity);
+    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setDefaultNfcSubscriptionId(int);
     method @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setServiceEnabledForCategoryOther(@NonNull android.content.ComponentName, boolean);
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3; // 0x3
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1; // 0x1
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2; // 0x2
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4; // 0x4
     field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_OK = 0; // 0x0
+    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2; // 0x2
+    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1; // 0x1
+    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3; // 0x3
+    field @FlaggedApi("android.nfc.enable_card_emulation_euicc") public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0; // 0x0
   }
 
 }
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index e9a3c66..5ae1be2 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -31,6 +31,7 @@
 import android.nfc.INfcFCardEmulation;
 import android.nfc.INfcOemExtensionCallback;
 import android.nfc.INfcUnlockHandler;
+import android.nfc.IT4tNdefNfcee;
 import android.nfc.ITagRemovedCallback;
 import android.nfc.INfcDta;
 import android.nfc.INfcWlcStateListener;
@@ -52,8 +53,8 @@
     int getState();
     boolean disable(boolean saveState, in String pkg);
     boolean enable(in String pkg);
-    void pausePolling(int timeoutInMs);
-    void resumePolling();
+    int pausePolling(int timeoutInMs);
+    int resumePolling();
 
     void setForegroundDispatch(in PendingIntent intent,
             in IntentFilter[] filters, in TechListParcel techLists);
@@ -122,4 +123,5 @@
     void indicateDataMigration(boolean inProgress, String pkg);
     int commitRouting();
     boolean isTagIntentAllowed(in String pkg, in int Userid);
+    IT4tNdefNfcee getT4tNdefNfceeInterface();
 }
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
index 633d8bf..bb9fe95 100644
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ b/nfc/java/android/nfc/INfcCardEmulation.aidl
@@ -53,6 +53,8 @@
     void overrideRoutingTable(int userHandle, String protocol, String technology, in String pkg);
     void recoverRoutingTable(int userHandle);
     boolean isEuiccSupported();
+    int getDefaultNfcSubscriptionId(in String pkg);
+    int setDefaultNfcSubscriptionId(int subscriptionId, in String pkg);
     void setAutoChangeStatus(boolean state);
     boolean isAutoChangeEnabled();
     List<String> getRoutingStatus();
diff --git a/nfc/java/android/nfc/INfcEventListener.aidl b/nfc/java/android/nfc/INfcEventListener.aidl
index 5162c26..774d8f8 100644
--- a/nfc/java/android/nfc/INfcEventListener.aidl
+++ b/nfc/java/android/nfc/INfcEventListener.aidl
@@ -8,4 +8,9 @@
 oneway interface INfcEventListener {
     void onPreferredServiceChanged(in ComponentNameAndUser ComponentNameAndUser);
     void onObserveModeStateChanged(boolean isEnabled);
+    void onAidConflictOccurred(in String aid);
+    void onAidNotRouted(in String aid);
+    void onNfcStateChanged(in int nfcState);
+    void onRemoteFieldChanged(boolean isDetected);
+    void onInternalErrorReported(in int errorType);
 }
\ No newline at end of file
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
index 1a21c0b..e5eac0b 100644
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -48,6 +48,7 @@
    void onRfFieldActivated(boolean isActivated);
    void onRfDiscoveryStarted(boolean isDiscoveryStarted);
    void onEeListenActivated(boolean isActivated);
+   void onEeUpdated();
    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/IT4tNdefNfcee.aidl b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
new file mode 100644
index 0000000..b4cda5b
--- /dev/null
+++ b/nfc/java/android/nfc/IT4tNdefNfcee.aidl
@@ -0,0 +1,33 @@
+/******************************************************************************
+ *
+ *  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.nfc.T4tNdefNfceeCcFileInfo;
+
+/**
+ * @hide
+ */
+interface IT4tNdefNfcee {
+    int writeData(in int fileId, in byte[] data);
+    byte[] readData(in int fileId);
+    int clearNdefData();
+    boolean isNdefOperationOngoing();
+    boolean isNdefNfceeEmulationSupported();
+    T4tNdefNfceeCcFileInfo readCcfile();
+}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index 056844f..89ce423 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -589,6 +589,7 @@
     static INfcTag sTagService;
     static INfcCardEmulation sCardEmulationService;
     static INfcFCardEmulation sNfcFCardEmulationService;
+    static IT4tNdefNfcee sNdefNfceeService;
 
     /**
      * The NfcAdapter object for each application context.
@@ -827,7 +828,13 @@
                     throw new UnsupportedOperationException();
                 }
             }
-
+            try {
+                sNdefNfceeService = sService.getT4tNdefNfceeInterface();
+            } catch (RemoteException e) {
+                sNdefNfceeService = null;
+                Log.e(TAG, "could not retrieve NDEF NFCEE service");
+                throw new UnsupportedOperationException();
+            }
             sIsInitialized = true;
         }
         NfcAdapter adapter = sNfcAdapters.get(context);
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index f912cdc..f1198ed 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -216,6 +216,31 @@
     public @interface HostCardEmulationAction {}
 
     /**
+     * Status code returned when the polling state change request succeeded.
+     * @see #pausePolling()
+     * @see #resumePolling()
+     */
+    public static final int POLLING_STATE_CHANGE_SUCCEEDED = 1;
+    /**
+     * Status code returned when the polling state change request is already in
+     * required state.
+     * @see #pausePolling()
+     * @see #resumePolling()
+     */
+    public static final int POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE = 2;
+    /**
+     * Possible status codes for {@link #pausePolling()} and
+     * {@link #resumePolling()}.
+     * @hide
+     */
+    @IntDef(value = {
+            POLLING_STATE_CHANGE_SUCCEEDED,
+            POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PollingStateChangeStatusCode {}
+
+    /**
      * Status OK
      */
     public static final int STATUS_OK = 0;
@@ -410,6 +435,15 @@
         void onEeListenActivated(boolean isActivated);
 
         /**
+        * Notifies that some NFCEE (NFC Execution Environment) has been updated.
+        *
+        * <p> This indicates that some applet has been installed/updated/removed in
+        * one of the NFCEE's.
+        * </p>
+        */
+        void onEeUpdated();
+
+        /**
          * 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.
@@ -501,6 +535,28 @@
     }
 
     /**
+     * Get an instance of {@link T4tNdefNfcee} object for performing T4T (Type-4 Tag)
+     * NDEF (NFC Data Exchange Format) NFCEE (NFC Execution Environment) operations.
+     * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
+     * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
+     * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     *
+     * This is a singleton object which shall be used by OEM extension module to do NDEF-NFCEE
+     * read/write operations.
+     *
+     * <p>Returns {@link T4tNdefNfcee}
+     * <p>Does not cause any RF activity and does not block.
+     * @return NFC Data Exchange Format (NDEF) NFC Execution Environment (NFCEE) object
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+    public T4tNdefNfcee getT4tNdefNfcee() {
+        return T4tNdefNfcee.getInstance();
+    }
+
+    /**
      * Register an {@link Callback} to listen for NFC oem extension callbacks
      * Multiple clients can register and callbacks will be invoked asynchronously.
      *
@@ -691,24 +747,32 @@
 
     /**
      * Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
-     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely
-     * use {@link #resumePolling()} to resume the polling.
+     * In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely.
+     * Use {@link #resumePolling() to resume the polling.
      * @param timeoutInMs the pause polling duration in millisecond, ranging from 0 to 40000.
+     * @return status of the operation
+     * @throws IllegalArgumentException if timeoutInMs value is invalid
+     *         (0 < timeoutInMs < max).
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void pausePolling(@DurationMillisLong int timeoutInMs) {
-        NfcAdapter.callService(() -> NfcAdapter.sService.pausePolling(timeoutInMs));
+    public @PollingStateChangeStatusCode int pausePolling(@DurationMillisLong int timeoutInMs) {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sService.pausePolling(timeoutInMs),
+                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
     }
 
     /**
      * Resumes default NFC tag reader mode polling for the current device state if polling is
      * paused. Calling this while already in polling is a no-op.
+     * @return status of the operation
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
-    public void resumePolling() {
-        NfcAdapter.callService(() -> NfcAdapter.sService.resumePolling());
+    public @PollingStateChangeStatusCode int resumePolling() {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sService.resumePolling(),
+                POLLING_STATE_CHANGE_ALREADY_IN_REQUESTED_STATE);
     }
 
     /**
@@ -877,6 +941,12 @@
         }
 
         @Override
+        public void onEeUpdated() throws RemoteException {
+            mCallbackMap.forEach((cb, ex) ->
+                    handleVoidCallback(null, (Object input) -> cb.onEeUpdated(), 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/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java
index 4e91377..c2cbbed 100644
--- a/nfc/java/android/nfc/NfcRoutingTableEntry.java
+++ b/nfc/java/android/nfc/NfcRoutingTableEntry.java
@@ -17,8 +17,12 @@
 
 
 import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Class to represent an entry of routing table. This class is abstract and extended by
  * {@link RoutingTableTechnologyEntry}, {@link RoutingTableProtocolEntry},
@@ -30,10 +34,42 @@
 @SystemApi
 public abstract class NfcRoutingTableEntry {
     private final int mNfceeId;
+    private final int mType;
+
+    /**
+     * AID routing table type.
+     */
+    public static final int TYPE_AID = 0;
+    /**
+     * Protocol routing table type.
+     */
+    public static final int TYPE_PROTOCOL = 1;
+    /**
+     * Technology routing table type.
+     */
+    public static final int TYPE_TECHNOLOGY = 2;
+    /**
+     * System Code routing table type.
+     */
+    public static final int TYPE_SYSTEM_CODE = 3;
+
+    /**
+     * Possible type of this routing table entry.
+     * @hide
+     */
+    @IntDef(prefix = "TYPE_", value = {
+            TYPE_AID,
+            TYPE_PROTOCOL,
+            TYPE_TECHNOLOGY,
+            TYPE_SYSTEM_CODE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RoutingTableType {}
 
     /** @hide */
-    protected NfcRoutingTableEntry(int nfceeId) {
+    protected NfcRoutingTableEntry(int nfceeId, @RoutingTableType int type) {
         mNfceeId = nfceeId;
+        mType = type;
     }
 
     /**
@@ -43,4 +79,13 @@
     public int getNfceeId() {
         return mNfceeId;
     }
+
+    /**
+     * Get the type of this entry.
+     * @return an integer defined in {@link RoutingTableType}
+     */
+    @RoutingTableType
+    public int getType() {
+        return mType;
+    }
 }
diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java
index 7634fe3..bf697d6 100644
--- a/nfc/java/android/nfc/RoutingTableAidEntry.java
+++ b/nfc/java/android/nfc/RoutingTableAidEntry.java
@@ -20,7 +20,7 @@
 import android.annotation.SystemApi;
 
 /**
- * Represents an AID entry in current routing table.
+ * Represents an Application ID (AID) entry in current routing table.
  * @hide
  */
 @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@@ -30,7 +30,7 @@
 
     /** @hide */
     public RoutingTableAidEntry(int nfceeId, String value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_AID);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
index 0c5be7d..536de4d 100644
--- a/nfc/java/android/nfc/RoutingTableProtocolEntry.java
+++ b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
@@ -97,7 +97,7 @@
 
     /** @hide */
     public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_PROTOCOL);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
index f87ad5f..f61892d 100644
--- a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
+++ b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
@@ -20,7 +20,9 @@
 import android.annotation.SystemApi;
 
 /**
- * Represents a system code entry in current routing table.
+ * Represents a system code entry in current routing table, where system codes are two-byte values
+ * used in NFC-F technology (a type of NFC communication) to identify specific
+ * device configurations.
  * @hide
  */
 @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@@ -30,7 +32,7 @@
 
     /** @hide */
     public RoutingTableSystemCodeEntry(int nfceeId, byte[] value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_SYSTEM_CODE);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
index f51a529..2dbc942 100644
--- a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
+++ b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
@@ -30,22 +30,27 @@
 @SystemApi
 public class RoutingTableTechnologyEntry extends NfcRoutingTableEntry {
     /**
-     * Technology-A
+     * Technology-A.
+     * <p>Tech-A is mostly used for payment and ticketing applications. It supports various
+     * Tag platforms including Type 1, Type 2 and Type 4A tags. </p>
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_A = 0;
     /**
-     * Technology-B
+     * Technology-B which is based on ISO/IEC 14443-3 standard.
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_B = 1;
     /**
-     * Technology-F
+     * Technology-F.
+     * <p>Tech-F is a standard which supports Type 3 Tags and NFC-DEP protocol etc.</p>
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_F = 2;
     /**
-     * Technology-V
+     * Technology-V.
+     * <p>Tech-V is an NFC technology used for communication with passive tags that operate
+     * at a longer range than other NFC technologies. </p>
      */
     @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
     public static final int TECHNOLOGY_V = 3;
@@ -73,7 +78,7 @@
 
     /** @hide */
     public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value) {
-        super(nfceeId);
+        super(nfceeId, TYPE_TECHNOLOGY);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/T4tNdefNfcee.java b/nfc/java/android/nfc/T4tNdefNfcee.java
new file mode 100644
index 0000000..06d02c5
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfcee.java
@@ -0,0 +1,258 @@
+/*
+ * 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.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.WorkerThread;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used for performing T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
+ * NFCEE (NFC Execution Environment) operations.
+ * This can be used to write NDEF data to emulate a T4T tag in an NFCEE
+ * (NFC Execution Environment - eSE, SIM, etc). Refer to the NFC forum specification
+ * "NFCForum-TS-NCI-2.3 section 10.4" and "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class T4tNdefNfcee {
+    private static final String TAG = "NdefNfcee";
+    static T4tNdefNfcee sNdefNfcee;
+
+    private T4tNdefNfcee() {
+    }
+
+    /**
+     * Helper to get an instance of this class.
+     *
+     * @return
+     * @hide
+     */
+    @NonNull
+    public static T4tNdefNfcee getInstance() {
+        if (sNdefNfcee == null) {
+            sNdefNfcee = new T4tNdefNfcee();
+        }
+        return sNdefNfcee;
+    }
+
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data is successful.
+     */
+    public static final int WRITE_DATA_SUCCESS = 0;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to unknown reasons.
+     */
+    public static final int WRITE_DATA_ERROR_INTERNAL = -1;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to ongoing rf activity.
+     */
+    public static final int WRITE_DATA_ERROR_RF_ACTIVATED = -2;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to Nfc off.
+     */
+    public static final int WRITE_DATA_ERROR_NFC_NOT_ON = -3;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to invalid file id.
+     */
+    public static final int WRITE_DATA_ERROR_INVALID_FILE_ID = -4;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to invalid length.
+     */
+    public static final int WRITE_DATA_ERROR_INVALID_LENGTH = -5;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to core connection create failure.
+     */
+    public static final int WRITE_DATA_ERROR_CONNECTION_FAILED = -6;
+    /**
+     * Return flag for {@link #writeData(int, byte[])}.
+     * It indicates write data fail due to empty payload.
+     */
+    public static final int WRITE_DATA_ERROR_EMPTY_PAYLOAD = -7;
+    /**
+     * Returns flag for {@link #writeData(int, byte[])}.
+     * It idicates write data fail due to invalid ndef format.
+     */
+    public static final int WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED = -8;
+
+    /**
+     * Possible return values for {@link #writeData(int, byte[])}.
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "WRITE_DATA_" }, value = {
+        WRITE_DATA_SUCCESS,
+        WRITE_DATA_ERROR_INTERNAL,
+        WRITE_DATA_ERROR_RF_ACTIVATED,
+        WRITE_DATA_ERROR_NFC_NOT_ON,
+        WRITE_DATA_ERROR_INVALID_FILE_ID,
+        WRITE_DATA_ERROR_INVALID_LENGTH,
+        WRITE_DATA_ERROR_CONNECTION_FAILED,
+        WRITE_DATA_ERROR_EMPTY_PAYLOAD,
+        WRITE_DATA_ERROR_NDEF_VALIDATION_FAILED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteDataStatus{}
+
+    /**
+     * This API performs writes of T4T data to NFCEE.
+     *
+     * <p>This is an I/O operation and will block until complete. It must
+     * not be called from the main application thread.</p>
+     *
+     * @param fileId File id (Refer NFC Forum Type 4 Tag Specification
+     *               Section 4.2 File Identifiers and Access Conditions
+     *               for more information) to which to write.
+     * @param data   This should be valid Ndef Message format.
+     *               Refer to Nfc forum NDEF specification NDEF Message section
+     * @return status of the operation.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public @WriteDataStatus int writeData(@IntRange(from = 0, to = 65535) int fileId,
+            @NonNull byte[] data) {
+        return NfcAdapter.callServiceReturn(() ->
+                NfcAdapter.sNdefNfceeService.writeData(fileId, data), WRITE_DATA_ERROR_INTERNAL);
+    }
+
+    /**
+     * This API performs reading of T4T content of Nfcee.
+     *
+     * <p>This is an I/O operation and will block until complete. It must
+     * not be called from the main application thread.</p>
+     *
+     * @param fileId File Id (Refer
+     *               Section 4.2 File Identifiers and Access Conditions
+     *               for more information) from which to read.
+     * @return - Returns Ndef message if success
+     *           Refer to Nfc forum NDEF specification NDEF Message section
+     * @throws IllegalStateException if read fails because the fileId is invalid.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @NonNull
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public byte[] readData(@IntRange(from = 0, to = 65535) int fileId) {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.readData(fileId), null);
+    }
+
+    /**
+     * Return flag for {@link #clearNdefData()}.
+     * It indicates clear data is successful.
+     */
+    public static final int CLEAR_DATA_SUCCESS = 1;
+     /**
+     * Return flag for {@link #clearNdefData()}.
+     * It indicates clear data failed due to internal error while processing the clear.
+     */
+    public static final int CLEAR_DATA_FAILED_INTERNAL = 0;
+
+    /**
+     * Possible return values for {@link #clearNdefData()}.
+     *
+     * @hide
+     */
+    @IntDef(prefix = { "CLEAR_DATA_" }, value = {
+        CLEAR_DATA_SUCCESS,
+        CLEAR_DATA_FAILED_INTERNAL,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ClearDataStatus{}
+
+    /**
+     * This API will set all the T4T NDEF NFCEE data to zero.
+     *
+     * <p>This is an I/O operation and will block until complete. It must
+     * not be called from the main application thread.
+     *
+     * <p>This API can be called regardless of NDEF file lock state.
+     * </p>
+     * @return status of the operation
+     *
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public @ClearDataStatus int clearData() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.clearNdefData(), CLEAR_DATA_FAILED_INTERNAL);
+    }
+
+    /**
+     * Returns whether NDEF NFCEE operation is ongoing or not.
+     *
+     * @return true if NDEF NFCEE operation is ongoing, else false.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public boolean isOperationOngoing() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.isNdefOperationOngoing(), false);
+    }
+
+    /**
+     * This Api is to check the status of NDEF NFCEE emulation feature is
+     * supported or not.
+     *
+     * @return true if NDEF NFCEE emulation feature is supported, else false.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    public boolean isSupported() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.isNdefNfceeEmulationSupported(), false);
+    }
+
+    /**
+     * This API performs reading of T4T NDEF NFCEE CC file content.
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+     *
+     * @return Returns CC file content if success or null if failed to read.
+     * @hide
+     */
+    @SystemApi
+    @WorkerThread
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @Nullable
+    public T4tNdefNfceeCcFileInfo readCcfile() {
+        return NfcAdapter.callServiceReturn(() ->
+            NfcAdapter.sNdefNfceeService.readCcfile(), null);
+    }
+}
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
new file mode 100644
index 0000000..f72f74e
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.aidl
@@ -0,0 +1,20 @@
+/*
+ * 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 T4tNdefNfceeCcFileInfo;
+
diff --git a/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
new file mode 100644
index 0000000..5fca052
--- /dev/null
+++ b/nfc/java/android/nfc/T4tNdefNfceeCcFileInfo.java
@@ -0,0 +1,293 @@
+/*
+ * 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.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used to represence T4T (Type-4 Tag) NDEF (NFC Data Exchange Format)
+ * NFCEE (NFC Execution Environment) CC (Capability Container) File data.
+ * The CC file stores metadata about the T4T tag being emulated.
+ *
+ * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+@SystemApi
+public final class T4tNdefNfceeCcFileInfo implements Parcelable {
+    /**
+     * Indicates the size of this capability container (called “CC File”)<p>
+     */
+    private int mCcLength;
+    /**
+     * Indicates the mapping specification version<p>
+     */
+    private int mVersion;
+    /**
+     * Indicates the max data size by a single ReadBinary<p>
+     */
+    private int mMaxReadLength;
+    /**
+     * Indicates the max data size by a single UpdateBinary<p>
+     */
+    private int mMaxWriteLength;
+    /**
+     * Indicates the NDEF File Identifier<p>
+     */
+    private int mFileId;
+    /**
+     * Indicates the maximum Max NDEF file size<p>
+     */
+    private int mMaxSize;
+    /**
+     * Indicates the read access condition<p>
+     */
+    private int mReadAccess;
+    /**
+     * Indicates the write access condition<p>
+     */
+    private int mWriteAccess;
+
+    /**
+     * Constructor to be used by NFC service and internal classes.
+     * @hide
+     */
+    public T4tNdefNfceeCcFileInfo(int cclen, int version, int maxLe, int maxLc,
+                      int ndefFileId, int ndefMaxSize,
+                      int ndefReadAccess, int ndefWriteAccess) {
+        mCcLength = cclen;
+        mVersion = version;
+        mMaxWriteLength = maxLc;
+        mMaxReadLength = maxLe;
+        mFileId = ndefFileId;
+        mMaxSize = ndefMaxSize;
+        mReadAccess = ndefReadAccess;
+        mWriteAccess = ndefWriteAccess;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+
+        dest.writeInt(mCcLength);
+        dest.writeInt(mVersion);
+        dest.writeInt(mMaxWriteLength);
+        dest.writeInt(mMaxReadLength);
+        dest.writeInt(mFileId);
+        dest.writeInt(mMaxSize);
+        dest.writeInt(mReadAccess);
+        dest.writeInt(mWriteAccess);
+    }
+
+    /**
+     * Indicates the size of this capability container (called “CC File”).
+     *
+     * @return length of the CC file.
+     */
+    @IntRange(from = 0xf, to = 0x7fff)
+    public int getCcFileLength() {
+        return mCcLength;
+    }
+
+    /**
+     * T4T tag mapping version 2.0.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+     */
+    public static final int VERSION_2_0 = 0x20;
+    /**
+     * T4T tag mapping version 2.0.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" for more details.
+     */
+    public static final int VERSION_3_0 = 0x30;
+
+    /**
+     * Possible return values for {@link #getVersion()}.
+     * @hide
+     */
+    @IntDef(prefix = { "VERSION_" }, value = {
+            VERSION_2_0,
+            VERSION_3_0,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Version{}
+
+    /**
+     * Indicates the mapping version of the T4T tag supported.
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.5" for more details.
+     *
+     * @return version of the specification
+     */
+    @Version
+    public int getVersion() {
+        return mVersion;
+    }
+
+    /**
+     * Indicates the max data size that can be read by a single invocation of
+     * {@link T4tNdefNfcee#readData(int)}.
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLe.
+     * @return max size of read (in bytes).
+     */
+    @IntRange(from = 0xf, to = 0xffff)
+    public int getMaxReadLength() {
+        return mMaxReadLength;
+    }
+
+    /**
+     * Indicates the max data size that can be written by a single invocation of
+     * {@link T4tNdefNfcee#writeData(int, byte[])}
+     *
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.4" MLc.
+     * @return max size of write (in bytes).
+     */
+    @IntRange(from = 0xd, to = 0xffff)
+    public int getMaxWriteLength() {
+        return mMaxWriteLength;
+    }
+
+    /**
+     * Indicates the NDEF File Identifier. This is the identifier used in the last invocation of
+     * {@link T4tNdefNfcee#writeData(int, byte[])}
+     *
+     * @return FileId of the data stored or -1 if no data is present.
+     */
+    @IntRange(from = -1, to = 65535)
+    public int getFileId() {
+        return mFileId;
+    }
+
+    /**
+     * Indicates the maximum size of T4T NDEF data that can be written to the NFCEE.
+     *
+     * @return max size of the contents.
+     */
+    @IntRange(from = 0x5, to = 0x7fff)
+    public int getMaxSize() {
+        return mMaxSize;
+    }
+
+    /**
+     * T4T tag read access granted without any security.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int READ_ACCESS_GRANTED_UNRESTRICTED = 0x0;
+    /**
+     * T4T tag read access granted with limited proprietary access only.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int READ_ACCESS_GRANTED_RESTRICTED = 0x80;
+
+    /**
+     * Possible return values for {@link #getVersion()}.
+     * @hide
+     */
+    @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
+            READ_ACCESS_GRANTED_RESTRICTED,
+            READ_ACCESS_GRANTED_UNRESTRICTED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ReadAccess {}
+
+    /**
+     * Indicates the read access condition.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     * @return read access restriction
+     */
+    @ReadAccess
+    public int getReadAccess() {
+        return mReadAccess;
+    }
+
+    /**
+     * T4T tag write access granted without any security.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int WRITE_ACCESS_GRANTED_UNRESTRICTED = 0x0;
+    /**
+     * T4T tag write access granted with limited proprietary access only.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int WRITE_ACCESS_GRANTED_RESTRICTED = 0x80;
+    /**
+     * T4T tag write access not granted.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     */
+    public static final int WRITE_ACCESS_NOT_GRANTED = 0xFF;
+
+    /**
+     * Possible return values for {@link #getVersion()}.
+     * @hide
+     */
+    @IntDef(prefix = { "READ_ACCESS_GRANTED_" }, value = {
+            WRITE_ACCESS_GRANTED_RESTRICTED,
+            WRITE_ACCESS_GRANTED_UNRESTRICTED,
+            WRITE_ACCESS_NOT_GRANTED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteAccess {}
+
+    /**
+     * Indicates the write access condition.
+     * Refer to the NFC forum specification "NFCForum-TS-T4T-1.1 section 4.2" for more details.
+     * @return write access restriction
+     */
+    @WriteAccess
+    public int getWriteAccess() {
+        return mWriteAccess;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final @NonNull Parcelable.Creator<T4tNdefNfceeCcFileInfo> CREATOR =
+            new Parcelable.Creator<>() {
+                @Override
+                public T4tNdefNfceeCcFileInfo createFromParcel(Parcel in) {
+
+                    // NdefNfceeCcFileInfo fields
+                    int cclen = in.readInt();
+                    int version = in.readInt();
+                    int maxLe = in.readInt();
+                    int maxLc = in.readInt();
+                    int ndefFileId = in.readInt();
+                    int ndefMaxSize = in.readInt();
+                    int ndefReadAccess = in.readInt();
+                    int ndefWriteAccess = in.readInt();
+
+                    return new T4tNdefNfceeCcFileInfo(cclen, version, maxLe, maxLc,
+                            ndefFileId, ndefMaxSize,
+                            ndefReadAccess, ndefWriteAccess);
+                }
+
+                @Override
+                public T4tNdefNfceeCcFileInfo[] newArray(int size) {
+                    return new T4tNdefNfceeCcFileInfo[size];
+                }
+            };
+}
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index 8917524..cb364fb 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -22,6 +22,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -45,6 +46,7 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.SettingNotFoundException;
+import android.telephony.SubscriptionManager;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -947,7 +949,7 @@
      *
      * @param service The ComponentName of the service
      * @param status  true to enable, false to disable
-     * @return true if preferred service is successfully set or unset, otherwise return false.
+     * @return status code defined in {@link SetServiceEnabledStatusCode}
      *
      * @hide
      */
@@ -1010,6 +1012,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
     @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
     public void overrideRoutingTable(
             @NonNull Activity activity, @ProtocolAndTechnologyRoute int protocol,
@@ -1037,6 +1040,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
     @FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
     public void recoverRoutingTable(@NonNull Activity activity) {
         if (!activity.isResumed()) {
@@ -1058,6 +1062,97 @@
     }
 
     /**
+     * Setting the default subscription ID succeeded.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public static final int SET_SUBSCRIPTION_ID_STATUS_SUCCESS = 0;
+
+    /**
+     * Setting the default subscription ID failed because the subscription ID is invalid.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID = 1;
+
+    /**
+     * Setting the default subscription ID failed because there was an internal error processing
+     * the request. For ex: NFC service died in the middle of handling the API.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR = 2;
+
+    /**
+     * Setting the default subscription ID failed because this feature is not supported on the
+     * device.
+     * @hide
+     */
+    @SystemApi
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public static final int SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED = 3;
+
+    /** @hide */
+    @IntDef(prefix = "SET_SUBSCRIPTION_ID_STATUS_",
+            value = {
+                    SET_SUBSCRIPTION_ID_STATUS_SUCCESS,
+                    SET_SUBSCRIPTION_ID_STATUS_FAILED_INVALID_SUBSCRIPTION_ID,
+                    SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR,
+                    SET_SUBSCRIPTION_ID_STATUS_FAILED_NOT_SUPPORTED,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SetSubscriptionIdStatus {}
+
+    /**
+     * Sets the system's default NFC subscription id.
+     *
+     * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this sets the
+     * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+     *
+     * @param subscriptionId the default NFC subscription Id to set.
+     * @return status of the operation.
+     *
+     * @throws UnsupportedOperationException If the device does not have
+     * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+    @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public @SetSubscriptionIdStatus int setDefaultNfcSubscriptionId(int subscriptionId) {
+        return callServiceReturn(() ->
+                        sService.setDefaultNfcSubscriptionId(
+                                subscriptionId, mContext.getPackageName()),
+                SET_SUBSCRIPTION_ID_STATUS_FAILED_INTERNAL_ERROR);
+    }
+
+    /**
+     * Returns the system's default NFC subscription id.
+     *
+     * <p> For devices with multiple UICC/EUICC that is configured to be NFCEE, this returns the
+     * default UICC NFCEE that will handle NFC offhost CE transactoions </p>
+     * <p> If the device has no UICC that can serve as NFCEE, this will return
+     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}.</p>
+     *
+     * @return the default NFC subscription Id if set,
+     * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} otherwise.
+     *
+     * @throws UnsupportedOperationException If the device does not have
+     * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION}.
+     */
+    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
+    @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC)
+    public int getDefaultNfcSubscriptionId() {
+        return callServiceReturn(() ->
+                sService.getDefaultNfcSubscriptionId(mContext.getPackageName()),
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+    }
+
+    /**
      * Returns the value of {@link Settings.Secure#NFC_PAYMENT_DEFAULT_COMPONENT}.
      *
      * @param context A context
@@ -1144,6 +1239,40 @@
         };
     }
 
+    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+    public static final int NFC_INTERNAL_ERROR_UNKNOWN = 0;
+
+    /**
+     * This error is reported when the NFC command watchdog restarts the NFC stack.
+     */
+    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+    public static final int NFC_INTERNAL_ERROR_NFC_CRASH_RESTART = 1;
+
+    /**
+     * This error is reported when the NFC controller does not respond or there's an NCI transport
+     * error.
+     */
+    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+    public static final int NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR = 2;
+
+    /**
+     * This error is reported when the NFC stack times out while waiting for a response to a command
+     * sent to the NFC hardware.
+     */
+    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+    public static final int NFC_INTERNAL_ERROR_COMMAND_TIMEOUT = 3;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+    @IntDef(prefix = "NFC_INTERNAL_ERROR_", value = {
+            NFC_INTERNAL_ERROR_UNKNOWN,
+            NFC_INTERNAL_ERROR_NFC_CRASH_RESTART,
+            NFC_INTERNAL_ERROR_NFC_HARDWARE_ERROR,
+            NFC_INTERNAL_ERROR_COMMAND_TIMEOUT,
+    })
+    public @interface NfcInternalErrorType {}
+
     /** Listener for preferred service state changes. */
     @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
     public interface NfcEventListener {
@@ -1166,6 +1295,57 @@
          */
         @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
         default void onObserveModeStateChanged(boolean isEnabled) {}
+
+        /**
+         * This method is called when an AID conflict is detected during an NFC transaction. This
+         * can happen when multiple services are registered for the same AID.
+         *
+         * @param aid The AID that is in conflict
+         */
+        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+        default void onAidConflictOccurred(@NonNull String aid) {}
+
+        /**
+         * This method is called when an AID is not routed to any service during an NFC
+         * transaction. This can happen when no service is registered for the given AID.
+         *
+         * @param aid the AID that was not routed
+         */
+        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+        default void onAidNotRouted(@NonNull String aid) {}
+
+        /**
+         * This method is called when the NFC state changes.
+         *
+         * @see NfcAdapter#getAdapterState()
+         *
+         * @param state The new NFC state
+         */
+        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+        default void onNfcStateChanged(@NfcAdapter.AdapterState int state) {}
+        /**
+         * This method is called when the NFC controller is in card emulation mode and an NFC
+         * reader's field is either detected or lost.
+         *
+         * @param isDetected true if an NFC reader is detected, false if it is lost
+         */
+        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+        default void onRemoteFieldChanged(boolean isDetected) {}
+
+        /**
+         * This method is called when an internal error is reported by the NFC stack.
+         *
+         * No action is required in response to these events as the NFC stack will automatically
+         * attempt to recover. These errors are reported for informational purposes only.
+         *
+         * Note that these errors can be reported when performing various internal NFC operations
+         * (such as during device shutdown) and cannot always be explicitly correlated with NFC
+         * transaction failures.
+         *
+         * @param errorType The type of the internal error
+         */
+        @FlaggedApi(android.nfc.Flags.FLAG_NFC_EVENT_LISTENER)
+        default void onInternalErrorReported(@NfcInternalErrorType int errorType) {}
     }
 
     private final ArrayMap<NfcEventListener, Executor> mNfcEventListeners = new ArrayMap<>();
@@ -1185,25 +1365,61 @@
                                             mContext.getPackageName(),
                                             componentNameAndUser.getComponentName()
                                                     .getPackageName());
-                    synchronized (mNfcEventListeners) {
-                        mNfcEventListeners.forEach(
-                                (listener, executor) -> {
-                                    executor.execute(
-                                            () -> listener.onPreferredServiceChanged(isPreferred));
-                                });
-                    }
+                    callListeners(listener -> listener.onPreferredServiceChanged(isPreferred));
                 }
 
                 public void onObserveModeStateChanged(boolean isEnabled) {
                     if (!android.nfc.Flags.nfcEventListener()) {
                         return;
                     }
+                    callListeners(listener -> listener.onObserveModeStateChanged(isEnabled));
+                }
+
+                public void onAidConflictOccurred(String aid) {
+                    if (!android.nfc.Flags.nfcEventListener()) {
+                        return;
+                    }
+                    callListeners(listener -> listener.onAidConflictOccurred(aid));
+                }
+
+                public void onAidNotRouted(String aid) {
+                    if (!android.nfc.Flags.nfcEventListener()) {
+                        return;
+                    }
+                    callListeners(listener -> listener.onAidNotRouted(aid));
+                }
+
+                public void onNfcStateChanged(int state) {
+                    if (!android.nfc.Flags.nfcEventListener()) {
+                        return;
+                    }
+                    callListeners(listener -> listener.onNfcStateChanged(state));
+                }
+
+                public void onRemoteFieldChanged(boolean isDetected) {
+                    if (!android.nfc.Flags.nfcEventListener()) {
+                        return;
+                    }
+                    callListeners(listener -> listener.onRemoteFieldChanged(isDetected));
+                }
+
+                public void onInternalErrorReported(@NfcInternalErrorType int errorType) {
+                    if (!android.nfc.Flags.nfcEventListener()) {
+                        return;
+                    }
+                    callListeners(listener -> listener.onInternalErrorReported(errorType));
+                }
+
+                interface ListenerCall {
+                    void invoke(NfcEventListener listener);
+                }
+
+                private void callListeners(ListenerCall listenerCall) {
                     synchronized (mNfcEventListeners) {
                         mNfcEventListeners.forEach(
-                                (listener, executor) -> {
-                                    executor.execute(
-                                            () -> listener.onObserveModeStateChanged(isEnabled));
-                                });
+                            (listener, executor) -> {
+                                executor.execute(() -> listenerCall.invoke(listener));
+                            });
                     }
                 }
             };
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/OWNERS b/packages/SettingsProvider/src/com/android/providers/settings/OWNERS
index 0b71816..b0086c1 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/OWNERS
+++ b/packages/SettingsProvider/src/com/android/providers/settings/OWNERS
@@ -1 +1,2 @@
-per-file WritableNamespacePrefixes.java = cbrubaker@google.com,tedbauer@google.com
+per-file WritableNamespacePrefixes.java = mpgroover@google.com,tedbauer@google.com
+per-file WritableNamespaces.java = mpgroover@google.com,tedbauer@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
index 9de229e..a594ad6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
@@ -14,6 +14,14 @@
 per-file *Keyboard* = file:../keyguard/OWNERS
 per-file *Keyguard* = set noparent
 per-file *Keyguard* = file:../keyguard/OWNERS
+# Not setting noparent here, since *Notification* also matches some status bar notification chips files (statusbar/chips/notification) which should be owned by the status bar team.
+per-file *Notification* = file:notification/OWNERS
+# Not setting noparent here, since *Mode* matches many other classes (e.g., *ViewModel*)
+per-file *Mode* = file:notification/OWNERS
+per-file *RemoteInput* = set noparent
+per-file *RemoteInput* = file:notification/OWNERS
+per-file *EmptyShadeView* = set noparent
+per-file *EmptyShadeView* = file:notification/OWNERS
 per-file *Lockscreen* = set noparent
 per-file *Lockscreen* = file:../keyguard/OWNERS
 per-file *Scrim* = set noparent
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
index 869d854..9b71f80 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -30,6 +30,8 @@
 
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import com.android.ravenwood.common.RavenwoodCommonUtils;
+
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runner.Runner;
@@ -229,7 +231,9 @@
             s.evaluate();
             onAfter(description, scope, order, null);
         } catch (Throwable t) {
-            if (onAfter(description, scope, order, t)) {
+            var shouldReportFailure = RavenwoodCommonUtils.runIgnoringException(
+                    () -> onAfter(description, scope, order, t));
+            if (shouldReportFailure == null || shouldReportFailure) {
                 throw t;
             }
         }
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index 678a97b..979076e 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -22,6 +22,8 @@
 import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
 import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
 import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERSION_JAVA_SYSPROP;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.parseNullableInt;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.withDefault;
 
 import static org.junit.Assert.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
@@ -39,6 +41,7 @@
 import android.content.res.Resources;
 import android.os.Binder;
 import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -64,6 +67,7 @@
 import com.android.server.LocalServices;
 import com.android.server.compat.PlatformCompat;
 
+import org.junit.internal.management.ManagementFactory;
 import org.junit.runner.Description;
 
 import java.io.File;
@@ -154,6 +158,13 @@
     private static RavenwoodAwareTestRunner sRunner;
     private static RavenwoodSystemProperties sProps;
 
+    private static final int DEFAULT_TARGET_SDK_LEVEL = VERSION_CODES.CUR_DEVELOPMENT;
+    private static final String DEFAULT_PACKAGE_NAME = "com.android.ravenwoodtests.defaultname";
+
+    private static int sTargetSdkLevel;
+    private static String sTestPackageName;
+    private static String sTargetPackageName;
+
     /**
      * Initialize the global environment.
      */
@@ -194,6 +205,8 @@
         // Some process-wide initialization. (maybe redirect stdout/stderr)
         RavenwoodCommonUtils.loadJniLibrary(LIBRAVENWOOD_INITIALIZER_NAME);
 
+        dumpCommandLineArgs();
+
         // We haven't initialized liblog yet, so directly write to System.out here.
         RavenwoodCommonUtils.log(TAG, "globalInitInner()");
 
@@ -235,9 +248,22 @@
         System.setProperty("android.junit.runner",
                 "androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner");
 
+        loadRavenwoodProperties();
+
         assertMockitoVersion();
     }
 
+    private static void loadRavenwoodProperties() {
+        var props = RavenwoodSystemProperties.readProperties("ravenwood.properties");
+
+        sTargetSdkLevel = withDefault(
+                parseNullableInt(props.get("targetSdkVersionInt")), DEFAULT_TARGET_SDK_LEVEL);
+        sTargetPackageName = withDefault(props.get("packageName"), DEFAULT_PACKAGE_NAME);
+        sTestPackageName = withDefault(props.get("instPackageName"), sTargetPackageName);
+
+        // TODO(b/377765941) Read them from the manifest too?
+    }
+
     /**
      * Initialize the environment.
      */
@@ -256,7 +282,9 @@
             initInner(runner.mState.getConfig());
         } catch (Exception th) {
             Log.e(TAG, "init() failed", th);
-            reset();
+
+            RavenwoodCommonUtils.runIgnoringException(()-> reset());
+
             SneakyThrow.sneakyThrow(th);
         }
     }
@@ -267,6 +295,14 @@
             Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
         }
 
+        config.mTargetPackageName = sTargetPackageName;
+        config.mTestPackageName = sTestPackageName;
+        config.mTargetSdkLevel = sTargetSdkLevel;
+
+        Log.i(TAG, "TargetPackageName=" + sTargetPackageName);
+        Log.i(TAG, "TestPackageName=" + sTestPackageName);
+        Log.i(TAG, "TargetSdkLevel=" + sTargetSdkLevel);
+
         RavenwoodRuntimeState.sUid = config.mUid;
         RavenwoodRuntimeState.sPid = config.mPid;
         RavenwoodRuntimeState.sTargetSdkLevel = config.mTargetSdkLevel;
@@ -349,8 +385,11 @@
      * Partially re-initialize after each test method invocation
      */
     public static void reinit() {
-        var config = sRunner.mState.getConfig();
-        Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid));
+        // sRunner could be null, if there was a failure in the initialization.
+        if (sRunner != null) {
+            var config = sRunner.mState.getConfig();
+            Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid));
+        }
     }
 
     private static void initializeCompatIds(RavenwoodConfig config) {
@@ -380,6 +419,9 @@
 
     /**
      * De-initialize.
+     *
+     * Note, we call this method when init() fails too, so this method should deal with
+     * any partially-initialized states.
      */
     public static void reset() {
         if (RAVENWOOD_VERBOSE_LOGGING) {
@@ -411,7 +453,9 @@
             config.mState.mSystemServerContext.cleanUp();
         }
 
-        Looper.getMainLooper().quit();
+        if (Looper.getMainLooper() != null) {
+            Looper.getMainLooper().quit();
+        }
         Looper.clearMainLooperForTest();
 
         ActivityManager.reset$ravenwood();
@@ -547,4 +591,18 @@
                     + " access to system property '" + key + "' denied via RavenwoodConfig");
         }
     }
+
+    private static void dumpCommandLineArgs() {
+        Log.i(TAG, "JVM arguments:");
+
+        // Note, we use the wrapper in JUnit4, not the actual class (
+        // java.lang.management.ManagementFactory), because we can't see the later at the build
+        // because this source file is compiled for the device target, where ManagementFactory
+        // doesn't exist.
+        var args = ManagementFactory.getRuntimeMXBean().getInputArguments();
+
+        for (var arg : args) {
+            Log.i(TAG, "  " + arg);
+        }
+    }
 }
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
index 3ed8b0a..7ca9239 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
@@ -22,7 +22,6 @@
 import android.annotation.Nullable;
 import android.app.Instrumentation;
 import android.content.Context;
-import android.os.Build;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
@@ -30,16 +29,12 @@
 import java.lang.annotation.Target;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * Represents how to configure the ravenwood environment for a test class.
- *
- * If a ravenwood test class has a public static field with the {@link Config} annotation,
- * Ravenwood will extract the config from it and initializes the environment. The type of the
- * field must be of {@link RavenwoodConfig}.
+ * @deprecated This class will be removed. Reach out to g/ravenwood if you need any features in it.
  */
+@Deprecated
 public final class RavenwoodConfig {
     /**
      * Use this to mark a field as the configuration.
@@ -66,7 +61,7 @@
     String mTestPackageName;
     String mTargetPackageName;
 
-    int mTargetSdkLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
+    int mTargetSdkLevel;
 
     final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties();
 
@@ -91,12 +86,6 @@
         return RavenwoodRule.isOnRavenwood();
     }
 
-    private void setDefaults() {
-        if (mTargetPackageName == null) {
-            mTargetPackageName = mTestPackageName;
-        }
-    }
-
     public static class Builder {
         private final RavenwoodConfig mConfig = new RavenwoodConfig();
 
@@ -120,28 +109,27 @@
         }
 
         /**
-         * Configure the package name of the test, which corresponds to
-         * {@link Instrumentation#getContext()}.
+         * @deprecated no longer used. Package name is set in the build file. (for now)
          */
+        @Deprecated
         public Builder setPackageName(@NonNull String packageName) {
-            mConfig.mTestPackageName = Objects.requireNonNull(packageName);
             return this;
         }
 
         /**
-         * Configure the package name of the target app, which corresponds to
-         * {@link Instrumentation#getTargetContext()}. Defaults to {@link #setPackageName}.
+         * @deprecated no longer used. Package name is set in the build file. (for now)
          */
+        @Deprecated
         public Builder setTargetPackageName(@NonNull String packageName) {
-            mConfig.mTargetPackageName = Objects.requireNonNull(packageName);
             return this;
         }
 
+
         /**
-         * Configure the target SDK level of the test.
+         * @deprecated no longer used. Target SDK level is set in the build file. (for now)
          */
+        @Deprecated
         public Builder setTargetSdkLevel(int sdkLevel) {
-            mConfig.mTargetSdkLevel = sdkLevel;
             return this;
         }
 
@@ -154,33 +142,31 @@
         }
 
         /**
-         * Configure the given system property as immutable for the duration of the test.
-         * Read access to the key is allowed, and write access will fail. When {@code value} is
-         * {@code null}, the value is left as undefined.
-         *
-         * All properties in the {@code debug.*} namespace are automatically mutable, with no
-         * developer action required.
-         *
-         * Has no effect on non-Ravenwood environments.
+         * @deprecated Use {@link RavenwoodRule.Builder#setSystemPropertyImmutable(String, Object)}
          */
+        @Deprecated
         public Builder setSystemPropertyImmutable(@NonNull String key,
                 @Nullable Object value) {
+            return this;
+        }
+
+        /**
+         * @deprecated Use {@link RavenwoodRule.Builder#setSystemPropertyMutable(String, Object)}
+         */
+        @Deprecated
+        public Builder setSystemPropertyMutable(@NonNull String key,
+                @Nullable Object value) {
+            return this;
+        }
+
+        Builder setSystemPropertyImmutableReal(@NonNull String key,
+                @Nullable Object value) {
             mConfig.mSystemProperties.setValue(key, value);
             mConfig.mSystemProperties.setAccessReadOnly(key);
             return this;
         }
 
-        /**
-         * Configure the given system property as mutable for the duration of the test.
-         * Both read and write access to the key is allowed, and its value will be reset between
-         * each test. When {@code value} is {@code null}, the value is left as undefined.
-         *
-         * All properties in the {@code debug.*} namespace are automatically mutable, with no
-         * developer action required.
-         *
-         * Has no effect on non-Ravenwood environments.
-         */
-        public Builder setSystemPropertyMutable(@NonNull String key,
+        Builder setSystemPropertyMutableReal(@NonNull String key,
                 @Nullable Object value) {
             mConfig.mSystemProperties.setValue(key, value);
             mConfig.mSystemProperties.setAccessReadWrite(key);
@@ -205,7 +191,6 @@
         }
 
         public RavenwoodConfig build() {
-            mConfig.setDefaults();
             return mConfig;
         }
     }
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index bfa3802..5681a90 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -36,10 +36,8 @@
 import java.util.regex.Pattern;
 
 /**
- * @deprecated Use {@link RavenwoodConfig} to configure the ravenwood environment instead.
- * A {@link RavenwoodRule} is no longer needed for {@link DisabledOnRavenwood}. To get the
- * {@link Context} and {@link Instrumentation}, use
- * {@link androidx.test.platform.app.InstrumentationRegistry} instead.
+ * @deprecated This class is undergoing a major change. Reach out to g/ravenwood if you need
+ * any featues in it.
  */
 @Deprecated
 public final class RavenwoodRule implements TestRule {
@@ -128,11 +126,10 @@
         }
 
         /**
-         * Configure the identity of this process to be the given package name for the duration
-         * of the test. Has no effect on non-Ravenwood environments.
+         * @deprecated no longer used.
          */
+        @Deprecated
         public Builder setPackageName(@NonNull String packageName) {
-            mBuilder.setPackageName(packageName);
             return this;
         }
 
@@ -155,7 +152,7 @@
          * Has no effect on non-Ravenwood environments.
          */
         public Builder setSystemPropertyImmutable(@NonNull String key, @Nullable Object value) {
-            mBuilder.setSystemPropertyImmutable(key, value);
+            mBuilder.setSystemPropertyImmutableReal(key, value);
             return this;
         }
 
@@ -170,7 +167,7 @@
          * Has no effect on non-Ravenwood environments.
          */
         public Builder setSystemPropertyMutable(@NonNull String key, @Nullable Object value) {
-            mBuilder.setSystemPropertyMutable(key, value);
+            mBuilder.setSystemPropertyMutableReal(key, value);
             return this;
         }
 
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index 3e4619f..9bd376a 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -52,7 +52,7 @@
             "vendor_dlkm",
     };
 
-    private static Map<String, String> readProperties(String propFile) {
+    static Map<String, String> readProperties(String propFile) {
         // Use an ordered map just for cleaner dump log.
         final Map<String, String> ret = new LinkedHashMap<>();
         try {
@@ -60,7 +60,7 @@
                     .map(String::trim)
                     .filter(s -> !s.startsWith("#"))
                     .map(s -> s.split("\\s*=\\s*", 2))
-                    .filter(a -> a.length == 2)
+                    .filter(a -> a.length == 2 && a[1].length() > 0)
                     .forEach(a -> ret.put(a[0], a[1]));
         } catch (IOException e) {
             throw new RuntimeException(e);
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
index 520f050..2a04d44 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
@@ -30,6 +30,7 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.Arrays;
+import java.util.function.Supplier;
 
 public class RavenwoodCommonUtils {
     private static final String TAG = "RavenwoodCommonUtils";
@@ -277,11 +278,55 @@
                 (isStatic ? "static" : "")));
     }
 
+    /**
+     * Run a supplier and swallow the exception, if any.
+     *
+     * It's a dangerous function. Only use it in an exception handler where we don't want to crash.
+     */
+    @Nullable
+    public static <T> T runIgnoringException(@NonNull Supplier<T> s) {
+        try {
+            return s.get();
+        } catch (Throwable th) {
+            log(TAG, "Warning: Exception detected! " + getStackTraceString(th));
+        }
+        return null;
+    }
+
+    /**
+     * Run a runnable and swallow the exception, if any.
+     *
+     * It's a dangerous function. Only use it in an exception handler where we don't want to crash.
+     */
+    public static void runIgnoringException(@NonNull Runnable r) {
+        runIgnoringException(() -> {
+            r.run();
+            return null;
+        });
+    }
+
     @NonNull
-    public static String getStackTraceString(@Nullable Throwable th) {
+    public static String getStackTraceString(@NonNull Throwable th) {
         StringWriter stringWriter = new StringWriter();
         PrintWriter writer = new PrintWriter(stringWriter);
         th.printStackTrace(writer);
         return stringWriter.toString();
     }
+
+    /** Same as {@link Integer#parseInt(String)} but accepts null and returns null. */
+    @Nullable
+    public static Integer parseNullableInt(@Nullable String value) {
+        if (value == null) {
+            return null;
+        }
+        return Integer.parseInt(value);
+    }
+
+    /**
+     * @return {@code value} if it's non-null. Otherwise, returns {@code def}.
+     */
+    @Nullable
+    public static <T> T withDefault(@Nullable T value, @Nullable T def) {
+        return value != null ? value : def;
+    }
 }
diff --git a/ravenwood/tests/bivalentinst/Android.bp b/ravenwood/tests/bivalentinst/Android.bp
index 41e45e5..31e3bcc 100644
--- a/ravenwood/tests/bivalentinst/Android.bp
+++ b/ravenwood/tests/bivalentinst/Android.bp
@@ -27,6 +27,9 @@
         "junit",
         "truth",
     ],
+
+    package_name: "com.android.ravenwood.bivalentinsttest_self_inst",
+
     resource_apk: "RavenwoodBivalentInstTest_self_inst_device",
     auto_gen_config: true,
 }
@@ -53,6 +56,10 @@
         "truth",
     ],
     resource_apk: "RavenwoodBivalentInstTestTarget",
+
+    package_name: "com.android.ravenwood.bivalentinst_target_app",
+    inst_package_name: "com.android.ravenwood.bivalentinsttest_nonself_inst",
+
     inst_resource_apk: "RavenwoodBivalentInstTest_nonself_inst_device",
     auto_gen_config: true,
 }
diff --git a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java
index 77874bd..919aa43 100644
--- a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java
+++ b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java
@@ -19,8 +19,6 @@
 
 import android.app.Instrumentation;
 import android.content.Context;
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodConfig.Config;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
@@ -40,11 +38,6 @@
     private static final String TEST_PACKAGE_NAME =
             "com.android.ravenwood.bivalentinsttest_nonself_inst";
 
-    @Config
-    public static final RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
-            .setPackageName(TEST_PACKAGE_NAME)
-            .setTargetPackageName(TARGET_PACKAGE_NAME)
-            .build();
 
     private static Instrumentation sInstrumentation;
     private static Context sTestContext;
diff --git a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java
index 203923b..81cfa66 100644
--- a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java
+++ b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java
@@ -19,8 +19,6 @@
 
 import android.app.Instrumentation;
 import android.content.Context;
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodConfig.Config;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
@@ -41,13 +39,6 @@
     private static final String TEST_PACKAGE_NAME =
             "com.android.ravenwood.bivalentinsttest_self_inst";
 
-    @Config
-    public static final RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
-            .setPackageName(TEST_PACKAGE_NAME)
-            .setTargetPackageName(TARGET_PACKAGE_NAME)
-            .build();
-
-
     private static Instrumentation sInstrumentation;
     private static Context sTestContext;
     private static Context sTargetContext;
diff --git a/ravenwood/tests/bivalenttest/Android.bp b/ravenwood/tests/bivalenttest/Android.bp
index 40e6672..ac545df 100644
--- a/ravenwood/tests/bivalenttest/Android.bp
+++ b/ravenwood/tests/bivalenttest/Android.bp
@@ -84,6 +84,8 @@
 android_ravenwood_test {
     name: "RavenwoodBivalentTest",
     defaults: ["ravenwood-bivalent-defaults"],
+    target_sdk_version: "34",
+    package_name: "com.android.ravenwoodtest.bivalenttest",
     auto_gen_config: true,
 }
 
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
index a5a16c1..306c2b39 100644
--- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
+++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
@@ -20,8 +20,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assume.assumeTrue;
 
-import android.platform.test.ravenwood.RavenwoodConfig;
-
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
 
@@ -33,13 +31,7 @@
  */
 @RunWith(AndroidJUnit4.class)
 public class RavenwoodConfigTest {
-    private static final String PACKAGE_NAME = "com.test";
-
-    @RavenwoodConfig.Config
-    public static RavenwoodConfig sConfig =
-            new RavenwoodConfig.Builder()
-                    .setPackageName(PACKAGE_NAME)
-                    .build();
+    private static final String PACKAGE_NAME = "com.android.ravenwoodtest.bivalenttest";
 
     @Test
     public void testConfig() {
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
index a95760d..882c91c 100644
--- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
+++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
@@ -16,8 +16,6 @@
 package com.android.ravenwoodtest.bivalenttest.compat
 
 import android.app.compat.CompatChanges
-import android.os.Build
-import android.platform.test.ravenwood.RavenwoodConfig
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.internal.ravenwood.RavenwoodEnvironment.CompatIdsForTest
 import org.junit.Assert
@@ -26,14 +24,6 @@
 
 @RunWith(AndroidJUnit4::class)
 class RavenwoodCompatFrameworkTest {
-    companion object {
-        @JvmField // Expose as a raw field, not as a property.
-        @RavenwoodConfig.Config
-        val config = RavenwoodConfig.Builder()
-            .setTargetSdkLevel(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-            .build()
-    }
-
     @Test
     fun testEnabled() {
         Assert.assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_1))
@@ -53,4 +43,4 @@
     fun testEnabledAfterUForUApps() {
         Assert.assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_4))
     }
-}
\ No newline at end of file
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
index 02d1073..f94b98b 100644
--- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
@@ -24,6 +24,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.platform.app.InstrumentationRegistry;
 
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TestRule;
@@ -32,6 +33,10 @@
 
 /**
  * Test for @Config field extraction and validation.
+ *
+ * TODO(b/377765941) Most of the tests here will be obsolete and deleted with b/377765941, but
+ * some of the tests may need to be re-implemented one way or another. (e.g. the package name
+ * test.) Until that happens, we'll keep all tests here but add an {@code @Ignore} instead.
  */
 @NoRavenizer // This class shouldn't be executed with RavenwoodAwareTestRunner.
 public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase {
@@ -59,6 +64,7 @@
     testRunFinished: 1,0,0,0
     """)
     // CHECKSTYLE:ON
+    @Ignore // Package name is no longer set via config.
     public static class ConfigInBaseClassTest extends ConfigInBaseClass {
         @Test
         public void test() {
@@ -83,6 +89,7 @@
     testRunFinished: 1,0,0,0
     """)
     // CHECKSTYLE:ON
+    @Ignore // Package name is no longer set via config.
     public static class ConfigOverridingTest extends ConfigInBaseClass {
         static String PACKAGE_NAME_OVERRIDE = "com.ConfigOverridingTest";
 
@@ -376,6 +383,7 @@
     testRunFinished: 1,0,0,0
     """)
     // CHECKSTYLE:ON
+    @Ignore // Package name is no longer set via config.
     public static class RuleInBaseClassSuccessTest extends RuleInBaseClass {
 
         @Test
@@ -437,6 +445,7 @@
     testRunFinished: 1,1,0,0
     """)
     // CHECKSTYLE:ON
+    @Ignore // Package name is no longer set via config.
     public static class RuleWithDifferentTypeInBaseClassSuccessTest extends RuleWithDifferentTypeInBaseClass {
 
         @Test
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
index f7a2198..0e3d053 100644
--- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
@@ -25,6 +25,8 @@
 
 import junitparams.JUnitParamsRunner;
 import junitparams.Parameters;
+
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.Description;
 import org.junit.runner.JUnitCore;
@@ -103,6 +105,7 @@
         var thisClass = this.getClass();
         var ret = Arrays.stream(thisClass.getNestMembers())
                 .filter((c) -> c.getAnnotation(Expected.class) != null)
+                .filter((c) -> c.getAnnotation(Ignore.class) == null)
                 .toArray(Class[]::new);
 
         assertThat(ret.length).isGreaterThan(0);
diff --git a/ravenwood/tests/runtime-test/Android.bp b/ravenwood/tests/runtime-test/Android.bp
index 0c0df1f..c352003 100644
--- a/ravenwood/tests/runtime-test/Android.bp
+++ b/ravenwood/tests/runtime-test/Android.bp
@@ -9,7 +9,7 @@
 
 android_ravenwood_test {
     name: "RavenwoodRuntimeTest",
-
+    target_sdk_version: "34",
     libs: [
         "ravenwood-helper-runtime",
     ],
diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt
index 8ec0932..61e254b 100644
--- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt
+++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Validator.kt
@@ -43,7 +43,7 @@
     }
     var allOk = true
 
-    log.i("Checking ${cn.name.toHumanReadableClassName()}")
+    log.v("Checking ${cn.name.toHumanReadableClassName()}")
 
     // See if there's any class that extends a legacy base class.
     // But ignore the base classes in android.test.
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 0c99fcf..f50eb18 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -327,7 +327,7 @@
                 SystemUiDeviceConfigFlags.GENERATED_PREVIEW_API_RESET_INTERVAL_MS,
                 DEFAULT_GENERATED_PREVIEW_RESET_INTERVAL_MS);
         final int generatedPreviewMaxCallsPerInterval = DeviceConfig.getInt(NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.GENERATED_PREVIEW_API_RESET_INTERVAL_MS,
+                SystemUiDeviceConfigFlags.GENERATED_PREVIEW_API_MAX_CALLS_PER_INTERVAL,
                 DEFAULT_GENERATED_PREVIEW_MAX_CALLS_PER_INTERVAL);
         mGeneratedPreviewsApiCounter = new ApiCounter(generatedPreviewResetInterval,
                 generatedPreviewMaxCallsPerInterval);
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 9b987e9..8c83ad7 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -1319,6 +1319,7 @@
                         }
                         XmlUtils.skipCurrentTag(parser);
                     } break;
+                    case "disabled-in-sku":
                     case "disabled-until-used-preinstalled-carrier-app": {
                         if (allowAppConfigs) {
                             String pkgname = parser.getAttributeValue(null, "package");
@@ -1335,6 +1336,24 @@
                         }
                         XmlUtils.skipCurrentTag(parser);
                     } break;
+                    case "enabled-in-sku-override": {
+                        if (allowAppConfigs) {
+                            String pkgname = parser.getAttributeValue(null, "package");
+                            if (pkgname == null) {
+                                Slog.w(TAG,
+                                        "<" + name + "> without "
+                                                + "package in " + permFile + " at "
+                                                + parser.getPositionDescription());
+                            } else if (!mDisabledUntilUsedPreinstalledCarrierApps.remove(pkgname)) {
+                                Slog.w(TAG,
+                                        "<" + name + "> packagename:" + pkgname + " not included"
+                                                + "in disabled-in-sku");
+                            }
+                        } else {
+                            logNotAllowedInPartition(name, permFile, parser);
+                        }
+                        XmlUtils.skipCurrentTag(parser);
+                    } break;
                     case "privapp-permissions": {
                         if (allowPrivappPermissions) {
                             // privapp permissions from system, apex, vendor, product and
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 06e6c8b..2012f56 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -48,7 +48,6 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
-import android.net.vcn.Flags;
 import android.net.vcn.IVcnManagementService;
 import android.net.vcn.IVcnStatusCallback;
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
@@ -890,20 +889,11 @@
         while (configsIterator.hasNext()) {
             final ParcelUuid subGrp = configsIterator.next();
 
-            if (Flags.fixConfigGarbageCollection()) {
-                if (!subGroups.contains(subGrp)) {
-                    // Trim subGrps with no more subscriptions; must have moved to another subGrp
-                    logDbg("Garbage collect VcnConfig for group=" + subGrp);
-                    configsIterator.remove();
-                    shouldWrite = true;
-                }
-            } else {
-                final List<SubscriptionInfo> subscriptions = subMgr.getSubscriptionsInGroup(subGrp);
-                if (subscriptions == null || subscriptions.isEmpty()) {
-                    // Trim subGrps with no more subscriptions; must have moved to another subGrp
-                    configsIterator.remove();
-                    shouldWrite = true;
-                }
+            if (!subGroups.contains(subGrp)) {
+                // Trim subGrps with no more subscriptions; must have moved to another subGrp
+                logDbg("Garbage collect VcnConfig for group=" + subGrp);
+                configsIterator.remove();
+                shouldWrite = true;
             }
         }
 
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 211f952..0b61a80 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -2181,7 +2181,7 @@
                     Slog.d(TAG_AM,
                             "Performing native compaction for pid=" + pid
                                     + " type=" + compactProfile.name());
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactSystem");
+                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "compactNative");
                     try {
                         mProcessDependencies.performCompaction(compactProfile, pid);
                     } catch (Exception e) {
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 4ec2a04..90f92b0 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -449,7 +449,7 @@
       proto.write(StorageRequestMessage.FlagOverrideMessage.FLAG_NAME, flagName);
       proto.write(StorageRequestMessage.FlagOverrideMessage.FLAG_VALUE, flagValue);
       proto.write(StorageRequestMessage.FlagOverrideMessage.OVERRIDE_TYPE, isLocal
-                ? StorageRequestMessage.LOCAL_ON_REBOOT
+                ? StorageRequestMessage.LOCAL_IMMEDIATE
                 : StorageRequestMessage.SERVER_ON_REBOOT);
       proto.end(msgToken);
       proto.end(msgsToken);
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index f085647..645206a 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -174,10 +174,6 @@
             return BIOMETRIC_NO_HARDWARE;
         }
 
-        if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) {
-            return BIOMETRIC_HARDWARE_NOT_DETECTED;
-        }
-
         final boolean wasStrongEnough =
                 Utils.isAtLeastStrength(sensor.oemStrength, requestedStrength);
         final boolean isStrongEnough =
@@ -189,6 +185,10 @@
             return BIOMETRIC_INSUFFICIENT_STRENGTH;
         }
 
+        if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) {
+            return BIOMETRIC_HARDWARE_NOT_DETECTED;
+        }
+
         try {
             if (!sensor.impl.isHardwareDetected(opPackageName)) {
                 return BIOMETRIC_HARDWARE_NOT_DETECTED;
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index 82d5d4d..e8786be 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -677,10 +677,11 @@
      * Start the timeout for the watchdog.
      */
     public void startWatchdog() {
-        if (mCurrentOperation == null) {
+        final BiometricSchedulerOperation operation = mCurrentOperation;
+        if (operation == null) {
+            Slog.e(TAG, "Current operation is null,no need to start watchdog");
             return;
         }
-        final BiometricSchedulerOperation operation = mCurrentOperation;
         mHandler.postDelayed(() -> {
             if (operation == mCurrentOperation && !operation.isFinished()) {
                 Counter.logIncrement("biometric.value_scheduler_watchdog_triggered_count");
diff --git a/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java b/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
index d5aa5e2..43414c0 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
@@ -77,6 +77,16 @@
     }
 
     @Override
+    public void cancel() {
+        super.cancel();
+        try {
+            mInvalidationCallback.onCompleted();
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Unable to complete invalidation client due to exception: " + e);
+        }
+    }
+
+    @Override
     public int getProtoEnum() {
         return BiometricsProto.CM_INVALIDATE;
     }
diff --git a/services/core/java/com/android/server/input/InputShellCommand.java b/services/core/java/com/android/server/input/InputShellCommand.java
index 4c5a3c2..d8cf68e 100644
--- a/services/core/java/com/android/server/input/InputShellCommand.java
+++ b/services/core/java/com/android/server/input/InputShellCommand.java
@@ -472,6 +472,7 @@
                 }
             }
         }
+        event = KeyEvent.changeTimeRepeat(event, SystemClock.uptimeMillis(), 0);
         injectKeyEvent(KeyEvent.changeAction(event, KeyEvent.ACTION_UP), async);
     }
 
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index e8fc577..62b89f32 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -38,19 +38,19 @@
 per-file SaferIntentUtils.java = topjohnwu@google.com
 
 # shortcuts
-per-file LauncherAppsService.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShareTargetInfo.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutBitmapSaver.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutDumpFiles.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutLauncher.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutNonPersistentUser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutPackage.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutPackageInfo.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutPackageItem.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutParser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutRequestPinProcessor.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutService.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
-per-file ShortcutUser.java = omakoto@google.com, yamasani@google.com, sunnygoyal@google.com, mett@google.com, pinyaoting@google.com
+per-file LauncherAppsService.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShareTargetInfo.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutBitmapSaver.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutDumpFiles.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutLauncher.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutNonPersistentUser.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutPackage.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutPackageInfo.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutPackageItem.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutParser.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutRequestPinProcessor.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutService.java = pinyaoting@google.com, sunnygoyal@google.com
+per-file ShortcutUser.java = pinyaoting@google.com, sunnygoyal@google.com
 
 # background install control service
-per-file BackgroundInstall* = file:BACKGROUND_INSTALL_OWNERS
\ No newline at end of file
+per-file BackgroundInstall* = file:BACKGROUND_INSTALL_OWNERS
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 52a2fd6..688312e 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2968,7 +2968,10 @@
         if (com.android.ranging.flags.Flags.rangingStackEnabled()) {
             if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB)
                     || context.getPackageManager().hasSystemFeature(
-                            PackageManager.FEATURE_WIFI_RTT)) {
+                            PackageManager.FEATURE_WIFI_RTT)
+                    || (com.android.ranging.flags.Flags.rangingCsEnabled()
+                            && context.getPackageManager().hasSystemFeature(
+                                    PackageManager.FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING))) {
                 t.traceBegin("RangingService");
                 // TODO: b/375264320 - Remove after RELEASE_RANGING_STACK is ramped to next.
                 try {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
index b40d7ee..6720217 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
@@ -20,6 +20,7 @@
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
+import static android.hardware.biometrics.BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE;
 
 import static com.android.server.biometrics.sensors.LockoutTracker.LOCKOUT_NONE;
 
@@ -55,6 +56,7 @@
     @Rule
     public final MockitoRule mMockitoRule = MockitoJUnit.rule();
 
+    private static final int USER_ID = 0;
     private static final int SENSOR_ID_FINGERPRINT = 0;
     private static final int SENSOR_ID_FACE = 1;
     private static final String TEST_PACKAGE_NAME = "PreAuthInfoTestPackage";
@@ -184,6 +186,20 @@
         assertThat(preAuthInfo.eligibleSensors.get(0).modality).isEqualTo(TYPE_FINGERPRINT);
     }
 
+    @Test
+    public void prioritizeStrengthErrorBeforeCameraUnavailableError() throws Exception {
+        final BiometricSensor sensor = getFaceSensorWithStrength(
+                BiometricManager.Authenticators.BIOMETRIC_WEAK);
+        final PromptInfo promptInfo = new PromptInfo();
+        promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
+        promptInfo.setNegativeButtonText(TEST_PACKAGE_NAME);
+        final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
+                mSettingObserver, List.of(sensor), USER_ID , promptInfo, TEST_PACKAGE_NAME,
+                false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
+
+        assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo(BIOMETRIC_ERROR_NO_HARDWARE);
+    }
+
     private BiometricSensor getFingerprintSensor() {
         BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FINGERPRINT,
                 TYPE_FINGERPRINT, BiometricManager.Authenticators.BIOMETRIC_STRONG,
@@ -202,9 +218,10 @@
         return sensor;
     }
 
-    private BiometricSensor getFaceSensor() {
+    private BiometricSensor getFaceSensorWithStrength(
+            @BiometricManager.Authenticators.Types int sensorStrength) {
         BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FACE, TYPE_FACE,
-                BiometricManager.Authenticators.BIOMETRIC_STRONG, mFaceAuthenticator) {
+                sensorStrength, mFaceAuthenticator) {
             @Override
             boolean confirmationAlwaysRequired(int userId) {
                 return false;
@@ -218,4 +235,8 @@
 
         return sensor;
     }
+
+    private BiometricSensor getFaceSensor() {
+        return getFaceSensorWithStrength(BiometricManager.Authenticators.BIOMETRIC_STRONG);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClientTest.java
new file mode 100644
index 0000000..405fb44
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceInvalidationClientTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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 com.android.server.biometrics.sensors.face.aidl;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.hardware.biometrics.IInvalidationCallback;
+import android.hardware.biometrics.face.V1_0.IBiometricsFace;
+import android.hardware.biometrics.face.V1_0.OptionalUint64;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.testing.TestableContext;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.log.BiometricLogger;
+import com.android.server.biometrics.sensors.ClientMonitorCallback;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.stubbing.Answer;
+
+import java.util.HashMap;
+
+@Presubmit
+@SmallTest
+public class FaceInvalidationClientTest {
+
+    private static final int SENSOR_ID = 4;
+    private static final int USER_ID = 0;
+
+
+    @Rule
+    public final TestableContext mContext = new TestableContext(
+            InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
+
+    @Mock
+    private IBiometricsFace mFace;
+    @Mock
+    private AidlResponseHandler mAidlResponseHandler;
+    @Mock
+    private BiometricLogger mBiometricLogger;
+    @Mock
+    private BiometricContext mBiometricContext;
+    @Mock
+    private IInvalidationCallback mInvalidationCallback;
+    @Mock
+    private ClientMonitorCallback mClientMonitorCallback;
+
+    @Test
+    public void testStartInvalidationClient_whenHalIsHidl() throws RemoteException {
+        final OptionalUint64 halId = new OptionalUint64();
+
+        when(mFace.setCallback(any())).thenReturn(halId);
+
+        final AidlSession aidlSession = new AidlSession(mContext, () -> mFace, USER_ID,
+                mAidlResponseHandler);
+        final FaceInvalidationClient faceInvalidationClient =
+                new FaceInvalidationClient(mContext, () -> aidlSession, USER_ID,
+                        SENSOR_ID, mBiometricLogger, mBiometricContext, new HashMap<>(),
+                        mInvalidationCallback);
+
+        doAnswer((Answer<Void>) invocationOnMock -> {
+            faceInvalidationClient.cancel();
+            return null;
+        }).when(mAidlResponseHandler).onUnsupportedClientScheduled();
+
+        faceInvalidationClient.start(mClientMonitorCallback);
+
+        verify(mInvalidationCallback).onCompleted();
+    }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClientTest.java
new file mode 100644
index 0000000..1ee2fd1
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInvalidationClientTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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 com.android.server.biometrics.sensors.fingerprint.aidl;
+
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.verify;
+
+import android.hardware.biometrics.IInvalidationCallback;
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.os.RemoteException;
+import android.platform.test.annotations.Presubmit;
+import android.testing.TestableContext;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.biometrics.log.BiometricLogger;
+import com.android.server.biometrics.sensors.ClientMonitorCallback;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.mockito.stubbing.Answer;
+
+import java.util.HashMap;
+
+@Presubmit
+@SmallTest
+public class FingerprintInvalidationClientTest {
+
+    private static final int SENSOR_ID = 4;
+    private static final int USER_ID = 0;
+
+
+    @Rule
+    public final TestableContext mContext = new TestableContext(
+            InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
+    @Rule
+    public final MockitoRule mockito = MockitoJUnit.rule();
+
+    @Mock
+    private IBiometricsFingerprint mFingerprint;
+    @Mock
+    private AidlResponseHandler mAidlResponseHandler;
+    @Mock
+    private BiometricLogger mBiometricLogger;
+    @Mock
+    private BiometricContext mBiometricContext;
+    @Mock
+    private IInvalidationCallback mInvalidationCallback;
+    @Mock
+    private ClientMonitorCallback mClientMonitorCallback;
+
+    @Test
+    public void testStartInvalidationClient_whenHalIsHidl() throws RemoteException {
+        final AidlSession aidlSession = new AidlSession(
+                () -> mFingerprint, USER_ID, mAidlResponseHandler);
+        final FingerprintInvalidationClient fingerprintInvalidationClient =
+                new FingerprintInvalidationClient(mContext, () -> aidlSession, USER_ID,
+                        SENSOR_ID, mBiometricLogger, mBiometricContext, new HashMap<>(),
+                        mInvalidationCallback);
+
+        doAnswer((Answer<Void>) invocationOnMock -> {
+            fingerprintInvalidationClient.cancel();
+            return null;
+        }).when(mAidlResponseHandler).onUnsupportedClientScheduled(
+                FingerprintInvalidationClient.class);
+
+        fingerprintInvalidationClient.start(mClientMonitorCallback);
+
+        verify(mInvalidationCallback).onCompleted();
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index 3bc089f..842c441 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -691,6 +691,40 @@
         assertThat(actual).isEqualTo(expected);
     }
 
+    /**
+     * Tests that readPermissions works correctly for the tags:
+     * disabled-in-sku, enabled-in-sku-override.
+     * I.e. that disabled-in-sku add package to block list and
+     * enabled-in-sku-override removes package from the list.
+     */
+    @Test
+    public void testDisablePackageInSku() throws Exception {
+        final String disable_in_sku =
+                "<config>\n"
+                        + "    <disabled-in-sku package=\"com.sony.product1.app\"/>\n"
+                        + "    <disabled-in-sku package=\"com.sony.product2.app\"/>\n"
+                        + "</config>\n";
+
+        final String enable_in_sku_override =
+                "<config>\n"
+                        + "    <enabled-in-sku-override package=\"com.sony.product2.app\"/>\n"
+                        + "</config>\n";
+
+        final File folder1 = createTempSubfolder("folder1");
+        createTempFile(folder1, "permissionFile1.xml", disable_in_sku);
+
+        final File folder2 = createTempSubfolder("folder2");
+        createTempFile(folder2, "permissionFile2.xml", enable_in_sku_override);
+
+        readPermissions(folder1, /* Grant all permission flags */ ~0);
+        readPermissions(folder2, /* Grant all permission flags */ ~0);
+
+        final ArraySet<String> blocklist = mSysConfig.getDisabledUntilUsedPreinstalledCarrierApps();
+
+        assertThat(blocklist).contains("com.sony.product1.app");
+        assertThat(blocklist).doesNotContain("com.sony.product2.app");
+    }
+
     private void parseSharedLibraries(String contents) throws IOException {
         File folder = createTempSubfolder("permissions_folder");
         createTempFile(folder, "permissions.xml", contents);
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 3828a71..4ab8e6a 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -70,7 +70,6 @@
 import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.Uri;
-import android.net.vcn.Flags;
 import android.net.vcn.IVcnStatusCallback;
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
 import android.net.vcn.VcnConfig;
@@ -293,8 +292,6 @@
         doReturn(Collections.singleton(TRANSPORT_WIFI))
                 .when(mMockDeps)
                 .getRestrictedTransports(any(), any(), any());
-
-        mSetFlagsRule.enableFlags(Flags.FLAG_FIX_CONFIG_GARBAGE_COLLECTION);
     }