Merge "Update boot image and system server profiles [M80C35P56S0PP]" into main
diff --git a/api/Android.bp b/api/Android.bp
index 7ef00b0..c7c5686 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -125,27 +125,54 @@
     }),
 }
 
+// Create a single file containing the latest released version of the whole
+// Android public API.
+java_genrule {
+    name: "android.api.merged.public.latest",
+    srcs: [
+        ":android.api.combined.public.latest",
+    ],
+    out: ["public-latest.txt"],
+    tools: ["metalava"],
+    cmd: metalava_cmd + " merge-signatures --format=2.0 $(in) --out $(out)",
+}
+
+// Make sure that the Android public API is compatible with the
+// previously released public API.
 java_genrule {
     name: "frameworks-base-api-current-compat",
     srcs: [
-        ":android.api.public.latest",
+        ":android.api.merged.public.latest",
         ":android-incompatibilities.api.public.latest",
         ":frameworks-base-api-current.txt",
     ],
     out: ["updated-baseline.txt"],
     tools: ["metalava"],
     cmd: metalava_cmd +
-        "--check-compatibility:api:released $(location :android.api.public.latest) " +
+        "--check-compatibility:api:released $(location :android.api.merged.public.latest) " +
         "--baseline:compatibility:released $(location :android-incompatibilities.api.public.latest) " +
         "--update-baseline:compatibility:released $(genDir)/updated-baseline.txt " +
         "$(location :frameworks-base-api-current.txt)",
 }
 
+// Create a single file containing the latest released version of the whole
+// Android system API.
+java_genrule {
+    name: "android.api.merged.system.latest",
+    srcs: [
+        ":android.api.combined.system.latest",
+    ],
+    out: ["system-latest.txt"],
+    tools: ["metalava"],
+    cmd: metalava_cmd + " merge-signatures --format=2.0 $(in) --out $(out)",
+}
+
+// Make sure that the Android system API is compatible with the
+// previously released system API.
 java_genrule {
     name: "frameworks-base-api-system-current-compat",
     srcs: [
-        ":android.api.public.latest",
-        ":android.api.system.latest",
+        ":android.api.merged.system.latest",
         ":android-incompatibilities.api.system.latest",
         ":frameworks-base-api-current.txt",
         ":frameworks-base-api-system-current.txt",
@@ -153,20 +180,31 @@
     out: ["updated-baseline.txt"],
     tools: ["metalava"],
     cmd: metalava_cmd +
-        "--check-compatibility:api:released $(location :android.api.public.latest) " +
-        "--check-compatibility:api:released $(location :android.api.system.latest) " +
+        "--check-compatibility:api:released $(location :android.api.merged.system.latest) " +
         "--baseline:compatibility:released $(location :android-incompatibilities.api.system.latest) " +
         "--update-baseline:compatibility:released $(genDir)/updated-baseline.txt " +
         "$(location :frameworks-base-api-current.txt) " +
         "$(location :frameworks-base-api-system-current.txt)",
 }
 
+// Create a single file containing the latest released version of the whole
+// Android module-lib API.
+java_genrule {
+    name: "android.api.merged.module-lib.latest",
+    srcs: [
+        ":android.api.combined.module-lib.latest",
+    ],
+    out: ["module-lib-latest.txt"],
+    tools: ["metalava"],
+    cmd: metalava_cmd + " merge-signatures --format=2.0 $(in) --out $(out)",
+}
+
+// Make sure that the Android module-lib API is compatible with the
+// previously released module-lib API.
 java_genrule {
     name: "frameworks-base-api-module-lib-current-compat",
     srcs: [
-        ":android.api.public.latest",
-        ":android.api.system.latest",
-        ":android.api.module-lib.latest",
+        ":android.api.merged.module-lib.latest",
         ":android-incompatibilities.api.module-lib.latest",
         ":frameworks-base-api-current.txt",
         ":frameworks-base-api-system-current.txt",
@@ -175,9 +213,7 @@
     out: ["updated-baseline.txt"],
     tools: ["metalava"],
     cmd: metalava_cmd +
-        "--check-compatibility:api:released $(location :android.api.public.latest) " +
-        "--check-compatibility:api:released $(location :android.api.system.latest) " +
-        "--check-compatibility:api:released $(location :android.api.module-lib.latest) " +
+        "--check-compatibility:api:released $(location :android.api.merged.module-lib.latest) " +
         "--baseline:compatibility:released $(location :android-incompatibilities.api.module-lib.latest) " +
         "--update-baseline:compatibility:released $(genDir)/updated-baseline.txt " +
         "$(location :frameworks-base-api-current.txt) " +
@@ -192,7 +228,7 @@
     cmd: "$(location merge_zips) $(out) $(in)",
     srcs: [
         ":api-stubs-docs-non-updatable{.exportable}",
-        ":all-modules-public-stubs-source",
+        ":all-modules-public-stubs-source-exportable",
     ],
     visibility: ["//visibility:private"], // Used by make module in //development, mind
 }
diff --git a/api/ApiDocs.bp b/api/ApiDocs.bp
index e8fcf4b..1ebe0cd 100644
--- a/api/ApiDocs.bp
+++ b/api/ApiDocs.bp
@@ -129,7 +129,7 @@
 droidstubs {
     name: "framework-doc-stubs",
     defaults: ["android-non-updatable-doc-stubs-defaults"],
-    srcs: [":all-modules-public-stubs-source"],
+    srcs: [":all-modules-public-stubs-source-exportable"],
     api_levels_module: "api_versions_public",
     aidl: {
         include_dirs: [
diff --git a/api/api.go b/api/api.go
index 29083df..aa89c24 100644
--- a/api/api.go
+++ b/api/api.go
@@ -428,8 +428,9 @@
 
 func createPublicStubsSourceFilegroup(ctx android.LoadHookContext, modules proptools.Configurable[[]string]) {
 	props := fgProps{}
-	props.Name = proptools.StringPtr("all-modules-public-stubs-source")
-	props.Device_common_srcs = createSrcs(modules, "{.public.stubs.source}")
+	props.Name = proptools.StringPtr("all-modules-public-stubs-source-exportable")
+	transformConfigurableArray(modules, "", ".stubs.source")
+	props.Device_common_srcs = createSrcs(modules, "{.exportable}")
 	props.Visibility = []string{"//frameworks/base"}
 	ctx.CreateModule(android.FileGroupFactory, &props)
 }
diff --git a/core/api/current.txt b/core/api/current.txt
index 6d9fe44..d6b8a51 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -22663,6 +22663,7 @@
     method public void onCryptoError(@NonNull android.media.MediaCodec, @NonNull android.media.MediaCodec.CryptoException);
     method public abstract void onError(@NonNull android.media.MediaCodec, @NonNull android.media.MediaCodec.CodecException);
     method public abstract void onInputBufferAvailable(@NonNull android.media.MediaCodec, int);
+    method @FlaggedApi("android.media.codec.subsession_metrics") public void onMetricsFlushed(@NonNull android.media.MediaCodec, @NonNull android.os.PersistableBundle);
     method public abstract void onOutputBufferAvailable(@NonNull android.media.MediaCodec, int, @NonNull android.media.MediaCodec.BufferInfo);
     method @FlaggedApi("com.android.media.codec.flags.large_audio_frame") public void onOutputBuffersAvailable(@NonNull android.media.MediaCodec, int, @NonNull java.util.ArrayDeque<android.media.MediaCodec.BufferInfo>);
     method public abstract void onOutputFormatChanged(@NonNull android.media.MediaCodec, @NonNull android.media.MediaFormat);
@@ -23754,6 +23755,7 @@
     field public static final String KEY_MPEGH_COMPATIBLE_SETS = "mpegh-compatible-sets";
     field public static final String KEY_MPEGH_PROFILE_LEVEL_INDICATION = "mpegh-profile-level-indication";
     field public static final String KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT = "mpegh-reference-channel-layout";
+    field @FlaggedApi("android.media.codec.num_input_slots") public static final String KEY_NUM_SLOTS = "num-slots";
     field public static final String KEY_OPERATING_RATE = "operating-rate";
     field public static final String KEY_OUTPUT_REORDER_DEPTH = "output-reorder-depth";
     field public static final String KEY_PCM_ENCODING = "pcm-encoding";
@@ -40010,7 +40012,7 @@
     method @NonNull public android.security.keystore.KeyProtection.Builder setUserPresenceRequired(boolean);
   }
 
-  @FlaggedApi("android.security.keystore_grant_api") public class KeyStoreManager {
+  @FlaggedApi("android.security.keystore_grant_api") public final class KeyStoreManager {
     method @NonNull public java.util.List<java.security.cert.X509Certificate> getGrantedCertificateChainFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
     method @NonNull public java.security.Key getGrantedKeyFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
     method @NonNull public java.security.KeyPair getGrantedKeyPairFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 7e8a309..3f6e65b 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -649,16 +649,31 @@
 // 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 {
     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 +
-        // For now, only export "android.hardware.type.*" system features APIs.
-        // TODO(b/203143243): Use an intermediate soong var that aggregates all declared
-        // RELEASE_SYSTEM_FEATURE_* declarations into a single arg.
-        " --feature-apis=AUTOMOTIVE,WATCH,TELEVISION,EMBEDDED,PC" +
-        " > $(out)",
+        " --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",
     ],
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index ef59e0a..93ef5c3 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -45,7 +45,7 @@
  * </p>
  */
 @RavenwoodKeepWholeClass
-@RavenwoodRedirectionClass("CursorWindow_host")
+@RavenwoodRedirectionClass("CursorWindow_ravenwood")
 public class CursorWindow extends SQLiteClosable implements Parcelable {
     private static final String STATS_TAG = "CursorWindowStats";
 
diff --git a/ravenwood/runtime-helper-src/framework/android/database/CursorWindow_host.java b/core/java/android/database/CursorWindow_ravenwood.java
similarity index 89%
rename from ravenwood/runtime-helper-src/framework/android/database/CursorWindow_host.java
rename to core/java/android/database/CursorWindow_ravenwood.java
index e21a9cd..990ec5e 100644
--- a/ravenwood/runtime-helper-src/framework/android/database/CursorWindow_host.java
+++ b/core/java/android/database/CursorWindow_ravenwood.java
@@ -17,6 +17,7 @@
 
 import android.database.sqlite.SQLiteException;
 import android.os.Parcel;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 import android.util.Base64;
 
 import java.text.DecimalFormat;
@@ -26,9 +27,10 @@
 import java.util.HashMap;
 import java.util.List;
 
-public class CursorWindow_host {
+@RavenwoodKeepWholeClass
+class CursorWindow_ravenwood {
 
-    private static final HashMap<Long, CursorWindow_host> sInstances = new HashMap<>();
+    private static final HashMap<Long, CursorWindow_ravenwood> sInstances = new HashMap<>();
     private static long sNextId = 1;
 
     private String mName;
@@ -41,7 +43,7 @@
     private final List<Row> mRows = new ArrayList<>();
 
     public static long nativeCreate(String name, int cursorWindowSize) {
-        CursorWindow_host instance = new CursorWindow_host();
+        CursorWindow_ravenwood instance = new CursorWindow_ravenwood();
         instance.mName = name;
         long instanceId = sNextId++;
         sInstances.put(instanceId, instance);
@@ -66,7 +68,7 @@
     }
 
     public static boolean nativeAllocRow(long windowPtr) {
-        CursorWindow_host instance = sInstances.get(windowPtr);
+        CursorWindow_ravenwood instance = sInstances.get(windowPtr);
         Row row = new Row();
         row.mFields = new String[instance.mColumnNum];
         row.mTypes = new int[instance.mColumnNum];
@@ -76,7 +78,7 @@
     }
 
     private static boolean put(long windowPtr, String value, int type, int row, int column) {
-        CursorWindow_host instance = sInstances.get(windowPtr);
+        CursorWindow_ravenwood instance = sInstances.get(windowPtr);
         if (row >= instance.mRows.size() || column >= instance.mColumnNum) {
             return false;
         }
@@ -87,7 +89,7 @@
     }
 
     public static int nativeGetType(long windowPtr, int row, int column) {
-        CursorWindow_host instance = sInstances.get(windowPtr);
+        CursorWindow_ravenwood instance = sInstances.get(windowPtr);
         if (row >= instance.mRows.size() || column >= instance.mColumnNum) {
             return Cursor.FIELD_TYPE_NULL;
         }
@@ -101,7 +103,7 @@
     }
 
     public static String nativeGetString(long windowPtr, int row, int column) {
-        CursorWindow_host instance = sInstances.get(windowPtr);
+        CursorWindow_ravenwood instance = sInstances.get(windowPtr);
         if (row >= instance.mRows.size() || column >= instance.mColumnNum) {
             return null;
         }
@@ -164,7 +166,7 @@
     }
 
     public static void nativeWriteToParcel(long windowPtr, Parcel parcel) {
-        CursorWindow_host window = sInstances.get(windowPtr);
+        CursorWindow_ravenwood window = sInstances.get(windowPtr);
         parcel.writeString(window.mName);
         parcel.writeInt(window.mColumnNum);
         parcel.writeInt(window.mRows.size());
@@ -176,7 +178,7 @@
 
     public static long nativeCreateFromParcel(Parcel parcel) {
         long windowPtr = nativeCreate(null, 0);
-        CursorWindow_host window = sInstances.get(windowPtr);
+        CursorWindow_ravenwood window = sInstances.get(windowPtr);
         window.mName = parcel.readString();
         window.mColumnNum = parcel.readInt();
         int rowCount = parcel.readInt();
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index 53da4a9..5a7650b 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -40,7 +40,7 @@
  * {@link Looper#myQueue() Looper.myQueue()}.
  */
 @android.ravenwood.annotation.RavenwoodKeepWholeClass
-@android.ravenwood.annotation.RavenwoodRedirectionClass("MessageQueue_host")
+@android.ravenwood.annotation.RavenwoodRedirectionClass("MessageQueue_ravenwood")
 public final class MessageQueue {
     private static final String TAG = "MessageQueue";
     private static final boolean DEBUG = false;
diff --git a/ravenwood/runtime-helper-src/framework/android/os/MessageQueue_host.java b/core/java/android/os/MessageQueue_ravenwood.java
similarity index 87%
rename from ravenwood/runtime-helper-src/framework/android/os/MessageQueue_host.java
rename to core/java/android/os/MessageQueue_ravenwood.java
index 1b63adc..4033707 100644
--- a/ravenwood/runtime-helper-src/framework/android/os/MessageQueue_host.java
+++ b/core/java/android/os/MessageQueue_ravenwood.java
@@ -16,13 +16,16 @@
 
 package android.os;
 
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
-public class MessageQueue_host {
+@RavenwoodKeepWholeClass
+class MessageQueue_ravenwood {
     private static final AtomicLong sNextId = new AtomicLong(1);
-    private static final Map<Long, MessageQueue_host> sInstances = new ConcurrentHashMap<>();
+    private static final Map<Long, MessageQueue_ravenwood> sInstances = new ConcurrentHashMap<>();
 
     private boolean mDeleted = false;
 
@@ -37,8 +40,8 @@
         }
     }
 
-    private static MessageQueue_host getInstance(long id) {
-        MessageQueue_host q = sInstances.get(id);
+    private static MessageQueue_ravenwood getInstance(long id) {
+        MessageQueue_ravenwood q = sInstances.get(id);
         if (q == null) {
             throw new RuntimeException("MessageQueue doesn't exist with id=" + id);
         }
@@ -48,7 +51,7 @@
 
     public static long nativeInit() {
         final long id = sNextId.getAndIncrement();
-        final MessageQueue_host q = new MessageQueue_host();
+        final MessageQueue_ravenwood q = new MessageQueue_ravenwood();
         sInstances.put(id, q);
         return id;
     }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 505a82a..884a66c 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -2917,12 +2917,12 @@
         private void apply(boolean sync, boolean oneWay) {
             applyResizedSurfaces();
             notifyReparentedSurfaces();
-            nativeApplyTransaction(mNativeObject, sync, oneWay);
 
             if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
                 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
                         "apply", this, null, null);
             }
+            nativeApplyTransaction(mNativeObject, sync, oneWay);
         }
 
         /**
diff --git a/core/java/com/android/internal/os/LongArrayMultiStateCounter.java b/core/java/com/android/internal/os/LongArrayMultiStateCounter.java
index dfb2884..1f9a39d 100644
--- a/core/java/com/android/internal/os/LongArrayMultiStateCounter.java
+++ b/core/java/com/android/internal/os/LongArrayMultiStateCounter.java
@@ -60,14 +60,14 @@
  * @hide
  */
 @RavenwoodKeepWholeClass
-@RavenwoodRedirectionClass("LongArrayMultiStateCounter_host")
+@RavenwoodRedirectionClass("LongArrayMultiStateCounter_ravenwood")
 public final class LongArrayMultiStateCounter implements Parcelable {
 
     /**
      * Container for a native equivalent of a long[].
      */
     @RavenwoodKeepWholeClass
-    @RavenwoodRedirectionClass("LongArrayContainer_host")
+    @RavenwoodRedirectionClass("LongArrayMultiStateCounter_ravenwood$LongArrayContainer")
     public static class LongArrayContainer {
         private static NativeAllocationRegistry sRegistry;
 
diff --git a/ravenwood/runtime-helper-src/framework/com/android/internal/os/LongArrayMultiStateCounter_host.java b/core/java/com/android/internal/os/LongArrayMultiStateCounter_ravenwood.java
similarity index 84%
rename from ravenwood/runtime-helper-src/framework/com/android/internal/os/LongArrayMultiStateCounter_host.java
rename to core/java/com/android/internal/os/LongArrayMultiStateCounter_ravenwood.java
index 9ce8ea8..e5caa6a 100644
--- a/ravenwood/runtime-helper-src/framework/com/android/internal/os/LongArrayMultiStateCounter_host.java
+++ b/core/java/com/android/internal/os/LongArrayMultiStateCounter_ravenwood.java
@@ -18,6 +18,7 @@
 
 import android.os.BadParcelableException;
 import android.os.Parcel;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 
 import java.util.Arrays;
 import java.util.HashMap;
@@ -25,7 +26,52 @@
 /**
  * Native implementation substitutions for the LongArrayMultiStateCounter class.
  */
-public class LongArrayMultiStateCounter_host {
+@RavenwoodKeepWholeClass
+class LongArrayMultiStateCounter_ravenwood {
+
+    static class LongArrayContainer {
+        private static final HashMap<Long, long[]> sInstances = new HashMap<>();
+        private static long sNextId = 1;
+
+        public static long native_init(int arrayLength) {
+            long[] array = new long[arrayLength];
+            long instanceId = sNextId++;
+            sInstances.put(instanceId, array);
+            return instanceId;
+        }
+
+        static long[] getInstance(long instanceId) {
+            return sInstances.get(instanceId);
+        }
+
+        public static void native_setValues(long instanceId, long[] values) {
+            System.arraycopy(values, 0, getInstance(instanceId), 0, values.length);
+        }
+
+        public static void native_getValues(long instanceId, long[] values) {
+            System.arraycopy(getInstance(instanceId), 0, values, 0, values.length);
+        }
+
+        public static boolean native_combineValues(long instanceId, long[] array, int[] indexMap) {
+            long[] values = getInstance(instanceId);
+
+            boolean nonZero = false;
+            Arrays.fill(array, 0);
+
+            for (int i = 0; i < values.length; i++) {
+                int index = indexMap[i];
+                if (index < 0 || index >= array.length) {
+                    throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: [0, "
+                            + (array.length - 1) + "]");
+                }
+                if (values[i] != 0) {
+                    array[index] += values[i];
+                    nonZero = true;
+                }
+            }
+            return nonZero;
+        }
+    }
 
     /**
      * A reimplementation of {@link LongArrayMultiStateCounter}, only in
@@ -288,13 +334,13 @@
 
     public static void native_setValues(long instanceId, int state, long containerInstanceId) {
         getInstance(instanceId).setValue(state,
-                LongArrayContainer_host.getInstance(containerInstanceId));
+                LongArrayContainer.getInstance(containerInstanceId));
     }
 
     public static void native_updateValues(long instanceId, long containerInstanceId,
             long timestampMs) {
         getInstance(instanceId).updateValue(
-                LongArrayContainer_host.getInstance(containerInstanceId), timestampMs);
+                LongArrayContainer.getInstance(containerInstanceId), timestampMs);
     }
 
     public static void native_setState(long instanceId, int state, long timestampMs) {
@@ -308,15 +354,15 @@
     public static void native_incrementValues(long instanceId, long containerInstanceId,
             long timestampMs) {
         getInstance(instanceId).incrementValues(
-                LongArrayContainer_host.getInstance(containerInstanceId), timestampMs);
+                LongArrayContainer.getInstance(containerInstanceId), timestampMs);
     }
 
     public static void native_addCounts(long instanceId, long containerInstanceId) {
-        getInstance(instanceId).addCounts(LongArrayContainer_host.getInstance(containerInstanceId));
+        getInstance(instanceId).addCounts(LongArrayContainer.getInstance(containerInstanceId));
     }
 
     public static void native_getCounts(long instanceId, long containerInstanceId, int state) {
-        getInstance(instanceId).getValues(LongArrayContainer_host.getInstance(containerInstanceId),
+        getInstance(instanceId).getValues(LongArrayContainer.getInstance(containerInstanceId),
                 state);
     }
 
diff --git a/core/java/com/android/internal/os/LongMultiStateCounter.java b/core/java/com/android/internal/os/LongMultiStateCounter.java
index c386a86..ee855d5 100644
--- a/core/java/com/android/internal/os/LongMultiStateCounter.java
+++ b/core/java/com/android/internal/os/LongMultiStateCounter.java
@@ -60,7 +60,7 @@
  * @hide
  */
 @RavenwoodKeepWholeClass
-@RavenwoodRedirectionClass("LongMultiStateCounter_host")
+@RavenwoodRedirectionClass("LongMultiStateCounter_ravenwood")
 public final class LongMultiStateCounter implements Parcelable {
 
     private static NativeAllocationRegistry sRegistry;
diff --git a/ravenwood/runtime-helper-src/framework/com/android/internal/os/LongMultiStateCounter_host.java b/core/java/com/android/internal/os/LongMultiStateCounter_ravenwood.java
similarity index 97%
rename from ravenwood/runtime-helper-src/framework/com/android/internal/os/LongMultiStateCounter_host.java
rename to core/java/com/android/internal/os/LongMultiStateCounter_ravenwood.java
index 1d95aa1..42db37f 100644
--- a/ravenwood/runtime-helper-src/framework/com/android/internal/os/LongMultiStateCounter_host.java
+++ b/core/java/com/android/internal/os/LongMultiStateCounter_ravenwood.java
@@ -18,13 +18,15 @@
 
 import android.os.BadParcelableException;
 import android.os.Parcel;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 
 import java.util.HashMap;
 
 /**
  * Native implementation substitutions for the LongMultiStateCounter class.
  */
-public class LongMultiStateCounter_host {
+@RavenwoodKeepWholeClass
+class LongMultiStateCounter_ravenwood {
 
     /**
      * A reimplementation of {@link com.android.internal.os.LongMultiStateCounter}, only in
diff --git a/keystore/java/android/security/keystore/KeyStoreManager.java b/keystore/java/android/security/keystore/KeyStoreManager.java
index 197aaba..e6091c1 100644
--- a/keystore/java/android/security/keystore/KeyStoreManager.java
+++ b/keystore/java/android/security/keystore/KeyStoreManager.java
@@ -49,7 +49,7 @@
  */
 @FlaggedApi(android.security.Flags.FLAG_KEYSTORE_GRANT_API)
 @SystemService(Context.KEYSTORE_SERVICE)
-public class KeyStoreManager {
+public final class KeyStoreManager {
     private static final String TAG = "KeyStoreManager";
 
     private static final Object sInstanceLock = new Object();
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index e575dae..2ae89d3 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -18,6 +18,7 @@
 
 import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE;
 import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
+import static android.media.codec.Flags.FLAG_SUBSESSION_METRICS;
 
 import static com.android.media.codec.flags.Flags.FLAG_LARGE_AUDIO_FRAME;
 
@@ -890,7 +891,7 @@
  any start codes), and submit it as a <strong>regular</strong> input buffer.
  <p>
  You will receive an {@link #INFO_OUTPUT_FORMAT_CHANGED} return value from {@link
- #dequeueOutputBuffer dequeueOutputBuffer} or a {@link Callback#onOutputBufferAvailable
+ #dequeueOutputBuffer dequeueOutputBuffer} or a {@link Callback#onOutputFormatChanged
  onOutputFormatChanged} callback just after the picture-size change takes place and before any
  frames with the new size have been returned.
  <p class=note>
@@ -1835,6 +1836,13 @@
     private static final int CB_CRYPTO_ERROR = 6;
     private static final int CB_LARGE_FRAME_OUTPUT_AVAILABLE = 7;
 
+    /**
+     * Callback ID for when the metrics for this codec have been flushed due to
+     * the start of a new subsession. The associated Java Message object will
+     * contain the flushed metrics as a PersistentBundle in the obj field.
+     */
+    private static final int CB_METRICS_FLUSHED = 8;
+
     private class EventHandler extends Handler {
         private MediaCodec mCodec;
 
@@ -2007,6 +2015,15 @@
                     break;
                 }
 
+                case CB_METRICS_FLUSHED:
+                {
+
+                    if (GetFlag(() -> android.media.codec.Flags.subsessionMetrics())) {
+                        mCallback.onMetricsFlushed(mCodec, (PersistableBundle)msg.obj);
+                    }
+                    break;
+                }
+
                 default:
                 {
                     break;
@@ -4958,14 +4975,24 @@
     public native final String getCanonicalName();
 
     /**
-     *  Return Metrics data about the current codec instance.
+     * Return Metrics data about the current codec instance.
+     * <p>
+     * Call this method after configuration, during execution, or after
+     * the codec has been already stopped.
+     * <p>
+     * Beginning with {@link android.os.Build.VERSION_CODES#B}
+     * this method can be used to get the Metrics data prior to an error.
+     * (e.g. in {@link Callback#onError} or after a method throws
+     * {@link MediaCodec.CodecException}.) Before that, the Metrics data was
+     * cleared on error, resulting in a null return value.
      *
      * @return a {@link PersistableBundle} containing the set of attributes and values
      * available for the media being handled by this instance of MediaCodec
      * The attributes are descibed in {@link MetricsConstants}.
      *
      * Additional vendor-specific fields may also be present in
-     * the return value.
+     * the return value. Returns null if there is no Metrics data.
+     *
      */
     public PersistableBundle getMetrics() {
         PersistableBundle bundle = native_getMetrics();
@@ -5692,6 +5719,27 @@
          */
         public abstract void onOutputFormatChanged(
                 @NonNull MediaCodec codec, @NonNull MediaFormat format);
+
+        /**
+         * Called when the metrics for this codec have been flushed due to the
+         * start of a new subsession.
+         * <p>
+         * This can happen when the codec is reconfigured after stop(), or
+         * mid-stream e.g. if the video size changes. When this happens, the
+         * metrics for the previous subsession are flushed, and
+         * {@link MediaCodec#getMetrics} will return the metrics for the
+         * new subsession. This happens just before the {@link Callback#onOutputFormatChanged}
+         * event, so this <b>optional</b> callback is provided to be able to
+         * capture the final metrics for the previous subsession.
+         *
+         * @param codec The MediaCodec object.
+         * @param metrics The flushed metrics for this codec.
+         */
+        @FlaggedApi(FLAG_SUBSESSION_METRICS)
+        public void onMetricsFlushed(
+                @NonNull MediaCodec codec, @NonNull PersistableBundle metrics) {
+            // default implementation ignores this callback.
+        }
     }
 
     private void postEventFromNative(
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index b08a86e..bd65b2e 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -17,6 +17,7 @@
 package android.media;
 
 import static android.media.codec.Flags.FLAG_IN_PROCESS_SW_AUDIO_CODEC;
+import static android.media.codec.Flags.FLAG_NUM_INPUT_SLOTS;
 import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
 import static android.media.codec.Flags.FLAG_APV_SUPPORT;
 
@@ -1777,6 +1778,17 @@
     public static final String KEY_SECURITY_MODEL = "security-model";
 
     /**
+     * A key describing the number of slots used in the codec. When present in input format,
+     * the associated value indicates the number of input slots. The entry is set by the codec
+     * if configured with (@link MediaCodec#CONFIGURE_FLAG_BLOCK_MODEL), and will be ignored if set
+     * by the application.
+     * <p>
+     * The associated value is an integer.
+     */
+    @FlaggedApi(FLAG_NUM_INPUT_SLOTS)
+    public static final String KEY_NUM_SLOTS = "num-slots";
+
+    /**
      * QpOffsetRect constitutes the metadata required for encoding a region of interest in an
      * image or a video frame. The region of interest is represented by a rectangle. The four
      * integer coordinates of the rectangle are stored in fields left, top, right, bottom.
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 675c8f8..a23845f 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -100,6 +100,7 @@
     method public void onHceEventReceived(int);
     method public void onLaunchHceAppChooserActivity(@NonNull String, @NonNull java.util.List<android.nfc.cardemulation.ApduServiceInfo>, @NonNull android.content.ComponentName, @NonNull String);
     method public void onLaunchHceTapAgainDialog(@NonNull android.nfc.cardemulation.ApduServiceInfo, @NonNull String);
+    method public void onLogEventNotified(@NonNull android.nfc.OemLogItems);
     method public void onNdefMessage(@NonNull android.nfc.Tag, @NonNull android.nfc.NdefMessage, @NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onNdefRead(@NonNull java.util.function.Consumer<java.lang.Boolean>);
     method public void onReaderOptionChanged(boolean);
@@ -115,6 +116,27 @@
     method public int getNfceeId();
   }
 
+  @FlaggedApi("android.nfc.nfc_oem_extension") public final class OemLogItems implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getAction();
+    method public int getCallingPid();
+    method @Nullable public byte[] getCommandApdu();
+    method public int getEvent();
+    method @Nullable public byte[] getResponseApdu();
+    method @Nullable public java.time.Instant getRfFieldEventTimeMillis();
+    method @Nullable public android.nfc.Tag getTag();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.nfc.OemLogItems> CREATOR;
+    field public static final int EVENT_DISABLE = 2; // 0x2
+    field public static final int EVENT_ENABLE = 1; // 0x1
+    field public static final int EVENT_UNSET = 0; // 0x0
+    field public static final int LOG_ACTION_HCE_DATA = 516; // 0x204
+    field public static final int LOG_ACTION_NFC_TOGGLE = 513; // 0x201
+    field public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 1; // 0x1
+    field public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 518; // 0x206
+    field public static final int LOG_ACTION_TAG_DETECTED = 3; // 0x3
+  }
+
   @FlaggedApi("android.nfc.nfc_oem_extension") public class RoutingStatus {
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultIsoDepRoute();
     method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int getDefaultOffHostRoute();
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
index 7f1fd15..b102e87 100644
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -18,6 +18,7 @@
 import android.content.ComponentName;
 import android.nfc.cardemulation.ApduServiceInfo;
 import android.nfc.NdefMessage;
+import android.nfc.OemLogItems;
 import android.nfc.Tag;
 import android.os.ResultReceiver;
 
@@ -51,4 +52,5 @@
    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);
    void onLaunchHceTapAgainActivity(in ApduServiceInfo service, in String category);
+   void onLogEventNotified(in OemLogItems item);
 }
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index 1bfe714..abd99bc 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -392,6 +392,12 @@
          * @param category the category of the service
          */
         void onLaunchHceTapAgainDialog(@NonNull ApduServiceInfo service, @NonNull String category);
+
+        /**
+         * Callback when OEM specified log event are notified.
+         * @param item the log items that contains log information of NFC event.
+         */
+        void onLogEventNotified(@NonNull OemLogItems item);
     }
 
 
@@ -900,6 +906,12 @@
                     handleVoid2ArgCallback(service, category, cb::onLaunchHceTapAgainDialog, ex));
         }
 
+        @Override
+        public void onLogEventNotified(OemLogItems item) throws RemoteException  {
+            mCallbackMap.forEach((cb, ex) ->
+                    handleVoidCallback(item, cb::onLogEventNotified, ex));
+        }
+
         private <T> void handleVoidCallback(
                 T input, Consumer<T> callbackMethod, Executor executor) {
             synchronized (mLock) {
diff --git a/nfc/java/android/nfc/OemLogItems.aidl b/nfc/java/android/nfc/OemLogItems.aidl
new file mode 100644
index 0000000..3bcb445
--- /dev/null
+++ b/nfc/java/android/nfc/OemLogItems.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.nfc;
+
+parcelable OemLogItems;
\ No newline at end of file
diff --git a/nfc/java/android/nfc/OemLogItems.java b/nfc/java/android/nfc/OemLogItems.java
new file mode 100644
index 0000000..6671941
--- /dev/null
+++ b/nfc/java/android/nfc/OemLogItems.java
@@ -0,0 +1,325 @@
+/*

+ * Copyright 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.NonNull;

+import android.annotation.Nullable;

+import android.annotation.SystemApi;

+import android.os.Parcel;

+import android.os.Parcelable;

+

+import java.lang.annotation.Retention;

+import java.lang.annotation.RetentionPolicy;

+import java.time.Instant;

+

+/**

+ * A log class for OEMs to get log information of NFC events.

+ * @hide

+ */

+@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)

+@SystemApi

+public final class OemLogItems implements Parcelable {

+    /**

+     * Used when RF field state is changed.

+     */

+    public static final int LOG_ACTION_RF_FIELD_STATE_CHANGED = 0X01;

+    /**

+     * Used when NFC is toggled. Event should be set to {@link LogEvent#EVENT_ENABLE} or

+     * {@link LogEvent#EVENT_DISABLE} if this action is used.

+     */

+    public static final int LOG_ACTION_NFC_TOGGLE = 0x0201;

+    /**

+     * Used when sending host routing status.

+     */

+    public static final int LOG_ACTION_HCE_DATA = 0x0204;

+    /**

+     * Used when screen state is changed.

+     */

+    public static final int LOG_ACTION_SCREEN_STATE_CHANGED = 0x0206;

+    /**

+     * Used when tag is detected.

+     */

+    public static final int LOG_ACTION_TAG_DETECTED = 0x03;

+

+    /**

+     * @hide

+     */

+    @IntDef(prefix = { "LOG_ACTION_" }, value = {

+            LOG_ACTION_RF_FIELD_STATE_CHANGED,

+            LOG_ACTION_NFC_TOGGLE,

+            LOG_ACTION_HCE_DATA,

+            LOG_ACTION_SCREEN_STATE_CHANGED,

+            LOG_ACTION_TAG_DETECTED,

+    })

+    @Retention(RetentionPolicy.SOURCE)

+    public @interface LogAction {}

+

+    /**

+     * Represents the event is not set.

+     */

+    public static final int EVENT_UNSET = 0;

+    /**

+     * Represents nfc enable is called.

+     */

+    public static final int EVENT_ENABLE = 1;

+    /**

+     * Represents nfc disable is called.

+     */

+    public static final int EVENT_DISABLE = 2;

+    /** @hide */

+    @IntDef(prefix = { "EVENT_" }, value = {

+            EVENT_UNSET,

+            EVENT_ENABLE,

+            EVENT_DISABLE,

+    })

+    @Retention(RetentionPolicy.SOURCE)

+    public @interface LogEvent {}

+    private int mAction;

+    private int mEvent;

+    private int mCallingPid;

+    private byte[] mCommandApdus;

+    private byte[] mResponseApdus;

+    private Instant mRfFieldOnTime;

+    private Tag mTag;

+

+    /** @hide */

+    public OemLogItems(@LogAction int action, @LogEvent int event, int callingPid,

+            byte[] commandApdus, byte[] responseApdus, Instant rfFieldOnTime,

+            Tag tag) {

+        mAction = action;

+        mEvent = event;

+        mTag = tag;

+        mCallingPid = callingPid;

+        mCommandApdus = commandApdus;

+        mResponseApdus = responseApdus;

+        mRfFieldOnTime = rfFieldOnTime;

+    }

+

+    /**

+     * Describe the kinds of special objects contained in this Parcelable

+     * instance's marshaled representation. For example, if the object will

+     * include a file descriptor in the output of {@link #writeToParcel(Parcel, int)},

+     * the return value of this method must include the

+     * {@link #CONTENTS_FILE_DESCRIPTOR} bit.

+     *

+     * @return a bitmask indicating the set of special object types marshaled

+     * by this Parcelable object instance.

+     */

+    @Override

+    public int describeContents() {

+        return 0;

+    }

+

+    /**

+     * Flatten this object in to a Parcel.

+     *

+     * @param dest  The Parcel in which the object should be written.

+     * @param flags Additional flags about how the object should be written.

+     *              May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.

+     */

+    @Override

+    public void writeToParcel(@NonNull Parcel dest, int flags) {

+        dest.writeInt(mAction);

+        dest.writeInt(mEvent);

+        dest.writeInt(mCallingPid);

+        dest.writeInt(mCommandApdus.length);

+        dest.writeByteArray(mCommandApdus);

+        dest.writeInt(mResponseApdus.length);

+        dest.writeByteArray(mResponseApdus);

+        dest.writeLong(mRfFieldOnTime.getEpochSecond());

+        dest.writeInt(mRfFieldOnTime.getNano());

+        dest.writeParcelable(mTag, 0);

+    }

+

+    /** @hide */

+    public static class Builder {

+        private final OemLogItems mItem;

+

+        public Builder(@LogAction int type) {

+            mItem = new OemLogItems(type, EVENT_UNSET, 0, new byte[0], new byte[0], null, null);

+        }

+

+        /** Setter of the log action. */

+        public OemLogItems.Builder setAction(@LogAction int action) {

+            mItem.mAction = action;

+            return this;

+        }

+

+        /** Setter of the log calling event. */

+        public OemLogItems.Builder setCallingEvent(@LogEvent int event) {

+            mItem.mEvent = event;

+            return this;

+        }

+

+        /** Setter of the log calling Pid. */

+        public OemLogItems.Builder setCallingPid(int pid) {

+            mItem.mCallingPid = pid;

+            return this;

+        }

+

+        /** Setter of APDU command. */

+        public OemLogItems.Builder setApduCommand(byte[] apdus) {

+            mItem.mCommandApdus = apdus;

+            return this;

+        }

+

+        /** Setter of RF field on time. */

+        public OemLogItems.Builder setRfFieldOnTime(Instant time) {

+            mItem.mRfFieldOnTime = time;

+            return this;

+        }

+

+        /** Setter of APDU response. */

+        public OemLogItems.Builder setApduResponse(byte[] apdus) {

+            mItem.mResponseApdus = apdus;

+            return this;

+        }

+

+        /** Setter of dispatched tag. */

+        public OemLogItems.Builder setTag(Tag tag) {

+            mItem.mTag = tag;

+            return this;

+        }

+

+        /** Builds an {@link OemLogItems} instance. */

+        public OemLogItems build() {

+            return mItem;

+        }

+    }

+

+    /**

+     * Gets the action of this log.

+     * @return one of {@link LogAction}

+     */

+    @LogAction

+    public int getAction() {

+        return mAction;

+    }

+

+    /**

+     * Gets the event of this log. This will be set to {@link LogEvent#EVENT_ENABLE} or

+     * {@link LogEvent#EVENT_DISABLE} only when action is set to

+     * {@link LogAction#LOG_ACTION_NFC_TOGGLE}

+     * @return one of {@link LogEvent}

+     */

+    @LogEvent

+    public int getEvent() {

+        return mEvent;

+    }

+

+    /**

+     * Gets the calling Pid of this log. This field will be set only when action is set to

+     * {@link LogAction#LOG_ACTION_NFC_TOGGLE}

+     * @return calling Pid

+     */

+    public int getCallingPid() {

+        return mCallingPid;

+    }

+

+    /**

+     * Gets the command APDUs of this log. This field will be set only when action is set to

+     * {@link LogAction#LOG_ACTION_HCE_DATA}

+     * @return a byte array of command APDUs with the same format as

+     * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}

+     */

+    @Nullable

+    public byte[] getCommandApdu() {

+        return mCommandApdus;

+    }

+

+    /**

+     * Gets the response APDUs of this log. This field will be set only when action is set to

+     * {@link LogAction#LOG_ACTION_HCE_DATA}

+     * @return a byte array of response APDUs with the same format as

+     * {@link android.nfc.cardemulation.HostApduService#sendResponseApdu(byte[])}

+     */

+    @Nullable

+    public byte[] getResponseApdu() {

+        return mResponseApdus;

+    }

+

+    /**

+     * Gets the RF field event time in this log in millisecond. This field will be set only when

+     * action is set to {@link LogAction#LOG_ACTION_RF_FIELD_STATE_CHANGED}

+     * @return an {@link Instant} of RF field event time.

+     */

+    @Nullable

+    public Instant getRfFieldEventTimeMillis() {

+        return mRfFieldOnTime;

+    }

+

+    /**

+     * Gets the tag of this log. This field will be set only when action is set to

+     * {@link LogAction#LOG_ACTION_TAG_DETECTED}

+     * @return a detected {@link Tag} in {@link #LOG_ACTION_TAG_DETECTED} case. Return

+     * null otherwise.

+     */

+    @Nullable

+    public Tag getTag() {

+        return mTag;

+    }

+

+    private String byteToHex(byte[] bytes) {

+        char[] HexArray = "0123456789ABCDEF".toCharArray();

+        char[] hexChars = new char[bytes.length * 2];

+        for (int j = 0; j < bytes.length; j++) {

+            int v = bytes[j] & 0xFF;

+            hexChars[j * 2] = HexArray[v >>> 4];

+            hexChars[j * 2 + 1] = HexArray[v & 0x0F];

+        }

+        return new String(hexChars);

+    }

+

+    @Override

+    public String toString() {

+        return "[mCommandApdus: "

+                + ((mCommandApdus != null) ? byteToHex(mCommandApdus) : "null")

+                + "[mResponseApdus: "

+                + ((mResponseApdus != null) ? byteToHex(mResponseApdus) : "null")

+                + ", mCallingApi= " + mEvent

+                + ", mAction= " + mAction

+                + ", mCallingPId = " + mCallingPid

+                + ", mRfFieldOnTime= " + mRfFieldOnTime;

+    }

+    private OemLogItems(Parcel in) {

+        this.mAction = in.readInt();

+        this.mEvent = in.readInt();

+        this.mCallingPid = in.readInt();

+        this.mCommandApdus = new byte[in.readInt()];

+        in.readByteArray(this.mCommandApdus);

+        this.mResponseApdus = new byte[in.readInt()];

+        in.readByteArray(this.mResponseApdus);

+        this.mRfFieldOnTime = Instant.ofEpochSecond(in.readLong(), in.readInt());

+        this.mTag = in.readParcelable(Tag.class.getClassLoader(), Tag.class);

+    }

+

+    public static final @NonNull Parcelable.Creator<OemLogItems> CREATOR =

+            new Parcelable.Creator<OemLogItems>() {

+                @Override

+                public OemLogItems createFromParcel(Parcel in) {

+                    return new OemLogItems(in);

+                }

+

+                @Override

+                public OemLogItems[] newArray(int size) {

+                    return new OemLogItems[size];

+                }

+            };

+

+}

diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
index d8f2b70..3ed8b0a 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
@@ -16,7 +16,6 @@
 package android.platform.test.ravenwood;
 
 import static android.os.Process.FIRST_APPLICATION_UID;
-import static android.os.Process.SYSTEM_UID;
 import static android.os.UserHandle.SYSTEM;
 
 import android.annotation.NonNull;
@@ -61,17 +60,14 @@
      * Unless the test author requests differently, run as "nobody", and give each collection of
      * tests its own unique PID.
      */
-    int mUid = NOBODY_UID;
+    int mUid = FIRST_APPLICATION_UID;
     int mPid = sNextPid.getAndIncrement();
 
     String mTestPackageName;
     String mTargetPackageName;
 
-    int mMinSdkLevel;
     int mTargetSdkLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
 
-    boolean mProvideMainThread = false;
-
     final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties();
 
     final List<Class<?>> mServicesRequired = new ArrayList<>();
@@ -108,20 +104,18 @@
         }
 
         /**
-         * Configure the identity of this process to be the system UID for the duration of the
-         * test. Has no effect on non-Ravenwood environments.
+         * @deprecated no longer used. We always use an app UID.
          */
+        @Deprecated
         public Builder setProcessSystem() {
-            mConfig.mUid = SYSTEM_UID;
             return this;
         }
 
         /**
-         * Configure the identity of this process to be an app UID for the duration of the
-         * test. Has no effect on non-Ravenwood environments.
+         * @deprecated no longer used. We always use an app UID.
          */
+        @Deprecated
         public Builder setProcessApp() {
-            mConfig.mUid = FIRST_APPLICATION_UID;
             return this;
         }
 
@@ -144,14 +138,6 @@
         }
 
         /**
-         * Configure the min SDK level of the test.
-         */
-        public Builder setMinSdkLevel(int sdkLevel) {
-            mConfig.mMinSdkLevel = sdkLevel;
-            return this;
-        }
-
-        /**
          * Configure the target SDK level of the test.
          */
         public Builder setTargetSdkLevel(int sdkLevel) {
@@ -160,14 +146,10 @@
         }
 
         /**
-         * Configure a "main" thread to be available for the duration of the test, as defined
-         * by {@code Looper.getMainLooper()}. Has no effect on non-Ravenwood environments.
-         *
-         * @deprecated
+         * @deprecated no longer used. Main thread is always available.
          */
         @Deprecated
         public Builder setProvideMainThread(boolean provideMainThread) {
-            mConfig.mProvideMainThread = provideMainThread;
             return this;
         }
 
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index 3d6ac0f..bfa3802 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -112,20 +112,18 @@
         }
 
         /**
-         * Configure the identity of this process to be the system UID for the duration of the
-         * test. Has no effect on non-Ravenwood environments.
+         * @deprecated no longer used. We always use an app UID.
          */
+        @Deprecated
         public Builder setProcessSystem() {
-            mBuilder.setProcessSystem();
             return this;
         }
 
         /**
-         * Configure the identity of this process to be an app UID for the duration of the
-         * test. Has no effect on non-Ravenwood environments.
+         * @deprecated no longer used. We always use an app UID.
          */
+        @Deprecated
         public Builder setProcessApp() {
-            mBuilder.setProcessApp();
             return this;
         }
 
@@ -139,14 +137,10 @@
         }
 
         /**
-         * Configure a "main" thread to be available for the duration of the test, as defined
-         * by {@code Looper.getMainLooper()}. Has no effect on non-Ravenwood environments.
-         *
-         * @deprecated
+         * @deprecated no longer used. Main thread is always available.
          */
         @Deprecated
         public Builder setProvideMainThread(boolean provideMainThread) {
-            mBuilder.setProvideMainThread(provideMainThread);
             return this;
         }
 
diff --git a/ravenwood/runtime-helper-src/framework/android/util/Log_host.java b/ravenwood/runtime-helper-src/framework/android/util/Log_host.java
index d232ef2..c85bd23 100644
--- a/ravenwood/runtime-helper-src/framework/android/util/Log_host.java
+++ b/ravenwood/runtime-helper-src/framework/android/util/Log_host.java
@@ -18,6 +18,7 @@
 import android.util.Log.Level;
 
 import com.android.internal.os.RuntimeInit;
+import com.android.ravenwood.common.RavenwoodCommonUtils;
 
 import java.io.PrintStream;
 
@@ -35,6 +36,9 @@
     }
 
     public static int println_native(int bufID, int priority, String tag, String msg) {
+        if (priority < Log.INFO && !RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING) {
+            return msg.length(); // No verbose logging.
+        }
         final String buffer;
         switch (bufID) {
             case Log.LOG_ID_MAIN: buffer = "main"; break;
diff --git a/ravenwood/runtime-helper-src/framework/com/android/internal/os/LongArrayContainer_host.java b/ravenwood/runtime-helper-src/framework/com/android/internal/os/LongArrayContainer_host.java
deleted file mode 100644
index c18c307..0000000
--- a/ravenwood/runtime-helper-src/framework/com/android/internal/os/LongArrayContainer_host.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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.internal.os;
-
-import java.util.Arrays;
-import java.util.HashMap;
-
-public class LongArrayContainer_host {
-    private static final HashMap<Long, long[]> sInstances = new HashMap<>();
-    private static long sNextId = 1;
-
-    public static long native_init(int arrayLength) {
-        long[] array = new long[arrayLength];
-        long instanceId = sNextId++;
-        sInstances.put(instanceId, array);
-        return instanceId;
-    }
-
-    static long[] getInstance(long instanceId) {
-        return sInstances.get(instanceId);
-    }
-
-    public static void native_setValues(long instanceId, long[] values) {
-        System.arraycopy(values, 0, getInstance(instanceId), 0, values.length);
-    }
-
-    public static void native_getValues(long instanceId, long[] values) {
-        System.arraycopy(getInstance(instanceId), 0, values, 0, values.length);
-    }
-
-    public static boolean native_combineValues(long instanceId, long[] array, int[] indexMap) {
-        long[] values = getInstance(instanceId);
-
-        boolean nonZero = false;
-        Arrays.fill(array, 0);
-
-        for (int i = 0; i < values.length; i++) {
-            int index = indexMap[i];
-            if (index < 0 || index >= array.length) {
-                throw new IndexOutOfBoundsException("Index " + index + " is out of bounds: [0, "
-                        + (array.length - 1) + "]");
-            }
-            if (values[i] != 0) {
-                array[index] += values[i];
-                nonZero = true;
-            }
-        }
-        return nonZero;
-    }
-}
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index a26fe66..5d24c3a 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -12,7 +12,9 @@
 com.android.internal.os.BatteryStatsHistoryIterator
 com.android.internal.os.Clock
 com.android.internal.os.LongArrayMultiStateCounter
+com.android.internal.os.LongArrayMultiStateCounter_ravenwood
 com.android.internal.os.LongMultiStateCounter
+com.android.internal.os.LongMultiStateCounter_ravenwood
 com.android.internal.os.MonotonicClock
 com.android.internal.os.PowerProfile
 com.android.internal.os.PowerStats
@@ -140,6 +142,7 @@
 android.os.Looper
 android.os.Message
 android.os.MessageQueue
+android.os.MessageQueue_ravenwood
 android.os.PackageTagsList
 android.os.Parcel
 android.os.ParcelFileDescriptor
@@ -232,6 +235,7 @@
 android.database.CursorIndexOutOfBoundsException
 android.database.CursorJoiner
 android.database.CursorWindow
+android.database.CursorWindow_ravenwood
 android.database.CursorWrapper
 android.database.DataSetObservable
 android.database.DataSetObserver
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 349f3ee..f08c876 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -233,6 +233,7 @@
         "core_os_flags_lib",
         "connectivity_flags_lib",
         "dreams_flags_lib",
+        "aconfig_flags_java",
         "aconfig_new_storage_flags_lib",
         "powerstats_flags_lib",
         "locksettings_flags_lib",
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 5c3640f..4ec2a04 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -39,6 +39,7 @@
 import android.aconfigd.Aconfigd.StorageReturnMessage;
 import android.aconfigd.Aconfigd.StorageReturnMessages;
 import static com.android.aconfig_new_storage.Flags.enableAconfigStorageDaemon;
+import static com.android.aconfig.flags.Flags.enableSystemAconfigdRust;
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
@@ -391,9 +392,11 @@
     static ProtoInputStream sendAconfigdRequests(ProtoOutputStream requests) {
         // connect to aconfigd socket
         LocalSocket client = new LocalSocket();
-        try{
+        String socketName = enableSystemAconfigdRust()
+                    ? "aconfigd_system" : "aconfigd";
+        try {
             client.connect(new LocalSocketAddress(
-                "aconfigd", LocalSocketAddress.Namespace.RESERVED));
+                socketName, LocalSocketAddress.Namespace.RESERVED));
             Slog.d(TAG, "connected to aconfigd socket");
         } catch (IOException ioe) {
             logErr("failed to connect to aconfigd socket", ioe);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 6fb5598..a91623736 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -39,6 +39,7 @@
 import android.bluetooth.BluetoothLeAudio;
 import android.bluetooth.BluetoothProfile;
 import android.content.Intent;
+import android.media.AudioDescriptor;
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceInfo;
 import android.media.AudioDevicePort;
@@ -46,6 +47,7 @@
 import android.media.AudioManager;
 import android.media.AudioManager.AudioDeviceCategory;
 import android.media.AudioPort;
+import android.media.AudioProfile;
 import android.media.AudioRoutesInfo;
 import android.media.AudioSystem;
 import android.media.IAudioRoutesObserver;
@@ -611,6 +613,8 @@
         final int mGroupId;
         @NonNull String mPeerDeviceAddress;
         @NonNull String mPeerIdentityDeviceAddress;
+        @NonNull List<AudioProfile> mAudioProfiles;
+        @NonNull List<AudioDescriptor> mAudioDescriptors;
 
         /** Disabled operating modes for this device. Use a negative logic so that by default
          * an empty list means all modes are allowed.
@@ -619,7 +623,8 @@
 
         DeviceInfo(int deviceType, String deviceName, String address,
                    String identityAddress, int codecFormat,
-                   int groupId, String peerAddress, String peerIdentityAddress) {
+                   int groupId, String peerAddress, String peerIdentityAddress,
+                   List<AudioProfile> profiles, List<AudioDescriptor> descriptors) {
             mDeviceType = deviceType;
             mDeviceName = TextUtils.emptyIfNull(deviceName);
             mDeviceAddress = TextUtils.emptyIfNull(address);
@@ -631,6 +636,16 @@
             mGroupId = groupId;
             mPeerDeviceAddress = TextUtils.emptyIfNull(peerAddress);
             mPeerIdentityDeviceAddress = TextUtils.emptyIfNull(peerIdentityAddress);
+            mAudioProfiles = profiles;
+            mAudioDescriptors = descriptors;
+        }
+
+        DeviceInfo(int deviceType, String deviceName, String address,
+                   String identityAddress, int codecFormat,
+                   int groupId, String peerAddress, String peerIdentityAddress) {
+            this(deviceType, deviceName, address, identityAddress, codecFormat,
+                    groupId, peerAddress, peerIdentityAddress,
+                    new ArrayList<>(), new ArrayList<>());
         }
 
         /** Constructor for all devices except A2DP sink and LE Audio */
@@ -638,6 +653,13 @@
             this(deviceType, deviceName, address, null, AudioSystem.AUDIO_FORMAT_DEFAULT);
         }
 
+        /** Constructor for HDMI OUT, HDMI ARC/EARC sink devices */
+        DeviceInfo(int deviceType, String deviceName, String address,
+            List<AudioProfile> profiles, List<AudioDescriptor> descriptors) {
+            this(deviceType, deviceName, address, null, AudioSystem.AUDIO_FORMAT_DEFAULT,
+                BluetoothLeAudio.GROUP_ID_INVALID, null, null, profiles, descriptors);
+        }
+
         /** Constructor for A2DP sink devices */
         DeviceInfo(int deviceType, String deviceName, String address,
                    String identityAddress, int codecFormat) {
@@ -1172,27 +1194,31 @@
     }
 
     /*package*/ void onToggleHdmi() {
-        MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "onToggleHdmi")
-                .set(MediaMetrics.Property.DEVICE,
-                        AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HDMI));
+        final int[] hdmiDevices = { AudioSystem.DEVICE_OUT_HDMI,
+                AudioSystem.DEVICE_OUT_HDMI_ARC, AudioSystem.DEVICE_OUT_HDMI_EARC };
+
         synchronized (mDevicesLock) {
-            // Is HDMI connected?
-            final String key = DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_OUT_HDMI, "");
-            final DeviceInfo di = mConnectedDevices.get(key);
-            if (di == null) {
-                Log.e(TAG, "invalid null DeviceInfo in onToggleHdmi");
-                mmi.set(MediaMetrics.Property.EARLY_RETURN, "invalid null DeviceInfo").record();
-                return;
+            for (DeviceInfo di : mConnectedDevices.values()) {
+                boolean isHdmiDevice = Arrays.stream(hdmiDevices).anyMatch(device ->
+                    device == di.mDeviceType);
+                if (isHdmiDevice) {
+                    MediaMetrics.Item mmi = new MediaMetrics.Item(mMetricsId + "onToggleHdmi")
+                            .set(MediaMetrics.Property.DEVICE,
+                                    AudioSystem.getDeviceName(di.mDeviceType));
+                    AudioDeviceAttributes ada = new AudioDeviceAttributes(
+                            AudioDeviceAttributes.ROLE_OUTPUT,
+                            AudioDeviceInfo.convertInternalDeviceToDeviceType(di.mDeviceType),
+                            di.mDeviceAddress, di.mDeviceName, di.mAudioProfiles,
+                            di.mAudioDescriptors);
+                    // Toggle HDMI to retrigger broadcast with proper formats.
+                    setWiredDeviceConnectionState(ada,
+                            AudioSystem.DEVICE_STATE_UNAVAILABLE, "onToggleHdmi"); // disconnect
+                    setWiredDeviceConnectionState(ada,
+                            AudioSystem.DEVICE_STATE_AVAILABLE, "onToggleHdmi"); // reconnect
+                    mmi.record();
+                }
             }
-            // Toggle HDMI to retrigger broadcast with proper formats.
-            setWiredDeviceConnectionState(
-                    new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
-                    AudioSystem.DEVICE_STATE_UNAVAILABLE, "android"); // disconnect
-            setWiredDeviceConnectionState(
-                    new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_HDMI, ""),
-                    AudioSystem.DEVICE_STATE_AVAILABLE, "android"); // reconnect
         }
-        mmi.record();
     }
 
     @GuardedBy("mDevicesLock")
@@ -1787,7 +1813,15 @@
                             .printSlog(EventLogger.Event.ALOGE, TAG));
                     return false;
                 }
-                mConnectedDevices.put(deviceKey, new DeviceInfo(device, deviceName, address));
+
+                if (device == AudioSystem.DEVICE_OUT_HDMI ||
+                    device == AudioSystem.DEVICE_OUT_HDMI_ARC ||
+                    device == AudioSystem.DEVICE_OUT_HDMI_EARC) {
+                    mConnectedDevices.put(deviceKey, new DeviceInfo(device, deviceName,
+                        address, attributes.getAudioProfiles(), attributes.getAudioDescriptors()));
+                } else {
+                    mConnectedDevices.put(deviceKey, new DeviceInfo(device, deviceName, address));
+                }
                 mDeviceBroker.postAccessoryPlugMediaUnmute(device);
                 status = true;
             } else if (!connect && isConnected) {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 2a3be1e..7de2815 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -513,12 +513,6 @@
     private boolean mLoadedRestrictBackground;
 
     /**
-     * Whether or not network for apps in proc-states greater than
-     * {@link NetworkPolicyManager#BACKGROUND_THRESHOLD_STATE} is always blocked.
-     */
-    private boolean mBackgroundNetworkRestricted;
-
-    /**
      * Whether or not metered firewall chains should be used for uid policy controlling access to
      * metered networks.
      */
@@ -1117,14 +1111,7 @@
                         writePolicyAL();
                     }
 
-                    // The flag is boot-stable.
-                    mBackgroundNetworkRestricted = Flags.networkBlockedForTopSleepingAndAbove();
-                    if (mBackgroundNetworkRestricted) {
-                        // Firewall rules and UidBlockedState will get updated in
-                        // updateRulesForGlobalChangeAL below.
-                        enableFirewallChainUL(FIREWALL_CHAIN_BACKGROUND, true);
-                    }
-
+                    enableFirewallChainUL(FIREWALL_CHAIN_BACKGROUND, true);
                     setRestrictBackgroundUL(mLoadedRestrictBackground, "init_service");
                     updateRulesForGlobalChangeAL(false);
                     updateNotificationsNL();
@@ -1135,11 +1122,8 @@
                 final int changes = ActivityManager.UID_OBSERVER_PROCSTATE
                         | ActivityManager.UID_OBSERVER_GONE
                         | ActivityManager.UID_OBSERVER_CAPABILITY;
-
-                final int cutpoint = mBackgroundNetworkRestricted ? PROCESS_STATE_UNKNOWN
-                        : NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE;
                 mActivityManagerInternal.registerNetworkPolicyUidObserver(mUidObserver, changes,
-                        cutpoint, "android");
+                        PROCESS_STATE_UNKNOWN, "android");
                 mNetworkManager.registerObserver(mAlertObserver);
             } catch (RemoteException e) {
                 // ignored; both services live in system_server
@@ -1280,21 +1264,19 @@
                 // different chains may change.
                 return true;
             }
-            if (mBackgroundNetworkRestricted) {
-                if ((previousProcState >= BACKGROUND_THRESHOLD_STATE)
+            if ((previousProcState >= BACKGROUND_THRESHOLD_STATE)
                     != (newProcState >= BACKGROUND_THRESHOLD_STATE)) {
-                    // Proc-state change crossed BACKGROUND_THRESHOLD_STATE: The network rules will
-                    // need to be re-evaluated for the background chain.
-                    return true;
-                }
-                if (mUseDifferentDelaysForBackgroundChain
-                        && newProcState >= BACKGROUND_THRESHOLD_STATE
-                        && getBackgroundTransitioningDelay(newProcState)
-                        < getBackgroundTransitioningDelay(previousProcState)) {
-                    // The old and new proc-state both are in the blocked state but the background
-                    // transition delay is reduced, so we may have to update the rules sooner.
-                    return true;
-                }
+                // Proc-state change crossed BACKGROUND_THRESHOLD_STATE: The network rules will
+                // need to be re-evaluated for the background chain.
+                return true;
+            }
+            if (mUseDifferentDelaysForBackgroundChain
+                    && newProcState >= BACKGROUND_THRESHOLD_STATE
+                    && getBackgroundTransitioningDelay(newProcState)
+                    < getBackgroundTransitioningDelay(previousProcState)) {
+                // The old and new proc-state both are in the blocked state but the background
+                // transition delay is reduced, so we may have to update the rules sooner.
+                return true;
             }
             final int networkCapabilities = PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
                     | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK;
@@ -1367,9 +1349,7 @@
             // on background handler thread, and POWER_SAVE_WHITELIST_CHANGED is protected
             synchronized (mUidRulesFirstLock) {
                 updatePowerSaveAllowlistUL();
-                if (mBackgroundNetworkRestricted) {
-                    updateRulesForBackgroundChainUL();
-                }
+                updateRulesForBackgroundChainUL();
                 updateRulesForRestrictPowerUL();
                 updateRulesForAppIdleUL();
             }
@@ -4100,8 +4080,6 @@
 
                 fout.println();
                 fout.println("Flags:");
-                fout.println(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE + ": "
-                        + mBackgroundNetworkRestricted);
                 fout.println(Flags.FLAG_USE_METERED_FIREWALL_CHAINS + ": "
                         + mUseMeteredFirewallChains);
                 fout.println(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN + ": "
@@ -4251,36 +4229,34 @@
                     fout.decreaseIndent();
                 }
 
-                if (mBackgroundNetworkRestricted) {
+                fout.println();
+                if (mUseDifferentDelaysForBackgroundChain) {
+                    fout.print("Background restrictions short delay: ");
+                    TimeUtils.formatDuration(mBackgroundRestrictionShortDelayMs, fout);
                     fout.println();
-                    if (mUseDifferentDelaysForBackgroundChain) {
-                        fout.print("Background restrictions short delay: ");
-                        TimeUtils.formatDuration(mBackgroundRestrictionShortDelayMs, fout);
-                        fout.println();
 
-                        fout.print("Background restrictions long delay: ");
-                        TimeUtils.formatDuration(mBackgroundRestrictionLongDelayMs, fout);
-                        fout.println();
-                    }
-
-                    size = mBackgroundTransitioningUids.size();
-                    if (size > 0) {
-                        final long nowUptime = SystemClock.uptimeMillis();
-                        fout.println("Uids transitioning to background:");
-                        fout.increaseIndent();
-                        for (int i = 0; i < size; i++) {
-                            fout.print("UID=");
-                            fout.print(mBackgroundTransitioningUids.keyAt(i));
-                            fout.print(", ");
-                            TimeUtils.formatDuration(mBackgroundTransitioningUids.valueAt(i),
-                                    nowUptime, fout);
-                            fout.println();
-                        }
-                        fout.decreaseIndent();
-                    }
+                    fout.print("Background restrictions long delay: ");
+                    TimeUtils.formatDuration(mBackgroundRestrictionLongDelayMs, fout);
                     fout.println();
                 }
 
+                size = mBackgroundTransitioningUids.size();
+                if (size > 0) {
+                    final long nowUptime = SystemClock.uptimeMillis();
+                    fout.println("Uids transitioning to background:");
+                    fout.increaseIndent();
+                    for (int i = 0; i < size; i++) {
+                        fout.print("UID=");
+                        fout.print(mBackgroundTransitioningUids.keyAt(i));
+                        fout.print(", ");
+                        TimeUtils.formatDuration(mBackgroundTransitioningUids.valueAt(i),
+                                nowUptime, fout);
+                        fout.println();
+                    }
+                    fout.decreaseIndent();
+                }
+                fout.println();
+
                 final SparseBooleanArray knownUids = new SparseBooleanArray();
                 collectKeys(mUidState, knownUids);
                 synchronized (mUidBlockedState) {
@@ -4465,51 +4441,49 @@
                     }
                     updatePowerRestrictionRules = true;
                 }
-                if (mBackgroundNetworkRestricted) {
-                    final boolean wasAllowed = isProcStateAllowedNetworkWhileBackground(
-                            oldUidState);
-                    final boolean isAllowed = isProcStateAllowedNetworkWhileBackground(newUidState);
-                    if (!wasAllowed && isAllowed) {
-                        mBackgroundTransitioningUids.delete(uid);
-                        updateRuleForBackgroundUL(uid);
-                        updatePowerRestrictionRules = true;
-                    } else if (!isAllowed) {
-                        final int transitionIdx = mBackgroundTransitioningUids.indexOfKey(uid);
-                        final long completionTimeMs = SystemClock.uptimeMillis()
-                                + getBackgroundTransitioningDelay(procState);
-                        boolean completionTimeUpdated = false;
-                        if (wasAllowed) {
-                            // Rules need to transition from allowed to blocked after the respective
-                            // delay.
-                            if (transitionIdx < 0) {
-                                // This is just a defensive check in case the upstream code ever
-                                // makes multiple calls for the same process state change.
-                                mBackgroundTransitioningUids.put(uid, completionTimeMs);
-                                completionTimeUpdated = true;
-                            }
-                        } else if (mUseDifferentDelaysForBackgroundChain) {
-                            // wasAllowed was false, but the transition delay may have reduced.
-                            // Currently, this can happen when the uid transitions from
-                            // LAST_ACTIVITY to CACHED_ACTIVITY, for example.
-                            if (transitionIdx >= 0
-                                    && completionTimeMs < mBackgroundTransitioningUids.valueAt(
-                                    transitionIdx)) {
-                                mBackgroundTransitioningUids.setValueAt(transitionIdx,
-                                        completionTimeMs);
-                                completionTimeUpdated = true;
-                            }
+                final boolean wasAllowed = isProcStateAllowedNetworkWhileBackground(
+                        oldUidState);
+                final boolean isAllowed = isProcStateAllowedNetworkWhileBackground(newUidState);
+                if (!wasAllowed && isAllowed) {
+                    mBackgroundTransitioningUids.delete(uid);
+                    updateRuleForBackgroundUL(uid);
+                    updatePowerRestrictionRules = true;
+                } else if (!isAllowed) {
+                    final int transitionIdx = mBackgroundTransitioningUids.indexOfKey(uid);
+                    final long completionTimeMs = SystemClock.uptimeMillis()
+                            + getBackgroundTransitioningDelay(procState);
+                    boolean completionTimeUpdated = false;
+                    if (wasAllowed) {
+                        // Rules need to transition from allowed to blocked after the respective
+                        // delay.
+                        if (transitionIdx < 0) {
+                            // This is just a defensive check in case the upstream code ever
+                            // makes multiple calls for the same process state change.
+                            mBackgroundTransitioningUids.put(uid, completionTimeMs);
+                            completionTimeUpdated = true;
                         }
-                        if (completionTimeUpdated
-                                && completionTimeMs < mNextProcessBackgroundUidsTime) {
-                            // Many uids may be in this "transitioning" state at the same time,
-                            // so we always keep one message to process transition completion at
-                            // the earliest time.
-                            mHandler.removeMessages(MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS);
-                            mHandler.sendEmptyMessageAtTime(
-                                    MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS, completionTimeMs);
-                            mNextProcessBackgroundUidsTime = completionTimeMs;
+                    } else if (mUseDifferentDelaysForBackgroundChain) {
+                        // wasAllowed was false, but the transition delay may have reduced.
+                        // Currently, this can happen when the uid transitions from
+                        // LAST_ACTIVITY to CACHED_ACTIVITY, for example.
+                        if (transitionIdx >= 0
+                                && completionTimeMs < mBackgroundTransitioningUids.valueAt(
+                                transitionIdx)) {
+                            mBackgroundTransitioningUids.setValueAt(transitionIdx,
+                                    completionTimeMs);
+                            completionTimeUpdated = true;
                         }
                     }
+                    if (completionTimeUpdated
+                            && completionTimeMs < mNextProcessBackgroundUidsTime) {
+                        // Many uids may be in this "transitioning" state at the same time,
+                        // so we always keep one message to process transition completion at
+                        // the earliest time.
+                        mHandler.removeMessages(MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS);
+                        mHandler.sendEmptyMessageAtTime(
+                                MSG_PROCESS_BACKGROUND_TRANSITIONING_UIDS, completionTimeMs);
+                        mNextProcessBackgroundUidsTime = completionTimeMs;
+                    }
                 }
                 if (mLowPowerStandbyActive) {
                     boolean allowedInLpsChanged =
@@ -4545,12 +4519,10 @@
                 if (mRestrictPower) {
                     updateRuleForRestrictPowerUL(uid);
                 }
-                if (mBackgroundNetworkRestricted) {
-                    // Uid is no longer running, there is no point in any grace period of network
-                    // access during transitions to lower importance proc-states.
-                    mBackgroundTransitioningUids.delete(uid);
-                    updateRuleForBackgroundUL(uid);
-                }
+                // Uid is no longer running, there is no point in any grace period of network
+                // access during transitions to lower importance proc-states.
+                mBackgroundTransitioningUids.delete(uid);
+                updateRuleForBackgroundUL(uid);
                 updateRulesForPowerRestrictionsUL(uid);
                 if (mLowPowerStandbyActive) {
                     updateRuleForLowPowerStandbyUL(uid);
@@ -5021,9 +4993,7 @@
                     "updateRulesForGlobalChangeAL: " + (restrictedNetworksChanged ? "R" : "-"));
         }
         try {
-            if (mBackgroundNetworkRestricted) {
-                updateRulesForBackgroundChainUL();
-            }
+            updateRulesForBackgroundChainUL();
             updateRulesForAppIdleUL();
             updateRulesForRestrictPowerUL();
             updateRulesForRestrictBackgroundUL();
@@ -5183,9 +5153,7 @@
             updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
             updateRuleForDeviceIdleUL(uid);
             updateRuleForRestrictPowerUL(uid);
-            if (mBackgroundNetworkRestricted) {
-                updateRuleForBackgroundUL(uid);
-            }
+            updateRuleForBackgroundUL(uid);
             // Update internal rules.
             updateRulesForPowerRestrictionsUL(uid);
         }
@@ -5358,9 +5326,7 @@
         updateRuleForDeviceIdleUL(uid);
         updateRuleForAppIdleUL(uid, PROCESS_STATE_UNKNOWN);
         updateRuleForRestrictPowerUL(uid);
-        if (mBackgroundNetworkRestricted) {
-            updateRuleForBackgroundUL(uid);
-        }
+        updateRuleForBackgroundUL(uid);
 
         // If the uid has the necessary permissions, then it should be added to the restricted mode
         // firewall allowlist.
@@ -5611,7 +5577,7 @@
             newBlockedReasons |= (mLowPowerStandbyActive ? BLOCKED_REASON_LOW_POWER_STANDBY : 0);
             newBlockedReasons |= (isUidIdle ? BLOCKED_REASON_APP_STANDBY : 0);
             newBlockedReasons |= (uidBlockedState.blockedReasons & BLOCKED_REASON_RESTRICTED_MODE);
-            newBlockedReasons |= mBackgroundNetworkRestricted ? BLOCKED_REASON_APP_BACKGROUND : 0;
+            newBlockedReasons |= BLOCKED_REASON_APP_BACKGROUND;
 
             newAllowedReasons |= (isSystem(uid) ? ALLOWED_REASON_SYSTEM : 0);
             newAllowedReasons |= (isForeground ? ALLOWED_REASON_FOREGROUND : 0);
@@ -5624,8 +5590,7 @@
                     & ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS);
             newAllowedReasons |= (isAllowlistedFromLowPowerStandbyUL(uid))
                     ? ALLOWED_REASON_LOW_POWER_STANDBY_ALLOWLIST : 0;
-            newAllowedReasons |= (mBackgroundNetworkRestricted
-                    && isUidExemptFromBackgroundRestrictions(uid))
+            newAllowedReasons |= isUidExemptFromBackgroundRestrictions(uid)
                     ? ALLOWED_REASON_NOT_IN_BACKGROUND : 0;
 
             uidBlockedState.blockedReasons = (uidBlockedState.blockedReasons
diff --git a/services/core/java/com/android/server/net/flags.aconfig b/services/core/java/com/android/server/net/flags.aconfig
index 7f04e66..3c0ff61 100644
--- a/services/core/java/com/android/server/net/flags.aconfig
+++ b/services/core/java/com/android/server/net/flags.aconfig
@@ -2,13 +2,6 @@
 container: "system"
 
 flag {
-    name: "network_blocked_for_top_sleeping_and_above"
-    namespace: "backstage_power"
-    description: "Block network access for apps in a low importance background state"
-    bug: "304347838"
-}
-
-flag {
     name: "use_metered_firewall_chains"
     namespace: "backstage_power"
     description: "Use metered firewall chains to control access to metered networks"
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index dddab65..5a7027e 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -2158,13 +2158,11 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
     public void testBackgroundChainEnabled() throws Exception {
         verify(mNetworkManager).setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, true);
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
     @RequiresFlagsDisabled(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN)
     public void testBackgroundChainOnProcStateChangeSameDelay() throws Exception {
         // initialization calls setFirewallChainEnabled, so we want to reset the invocations.
@@ -2194,10 +2192,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled({
-            Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE,
-            Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN
-    })
+    @RequiresFlagsEnabled(Flags.FLAG_USE_DIFFERENT_DELAYS_FOR_BACKGROUND_CHAIN)
     public void testBackgroundChainOnProcStateChangeDifferentDelays() throws Exception {
         // The app will be blocked when there is no prior proc-state.
         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
@@ -2247,7 +2242,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
     public void testBackgroundChainOnAllowlistChange() throws Exception {
         // initialization calls setFirewallChainEnabled, so we want to reset the invocations.
         clearInvocations(mNetworkManager);
@@ -2285,7 +2279,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
     public void testBackgroundChainOnTempAllowlistChange() throws Exception {
         // initialization calls setFirewallChainEnabled, so we want to reset the invocations.
         clearInvocations(mNetworkManager);
@@ -2387,7 +2380,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
     public void testUidObserverFiltersProcStateChanges() throws Exception {
         int testProcStateSeq = 0;
         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
@@ -2450,7 +2442,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
     public void testUidObserverFiltersStaleChanges() throws Exception {
         final int testProcStateSeq = 51;
         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
@@ -2470,7 +2461,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
     public void testUidObserverFiltersCapabilityChanges() throws Exception {
         int testProcStateSeq = 0;
         try (SyncBarrier b = new SyncBarrier(mService.mUidEventHandler)) {
@@ -2559,7 +2549,6 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(Flags.FLAG_NETWORK_BLOCKED_FOR_TOP_SLEEPING_AND_ABOVE)
     public void testObsoleteHandleUidChanged() throws Exception {
         callAndWaitOnUidGone(UID_A);
         assertTrue(mService.isUidNetworkingBlocked(UID_A, false));
diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt
index 1abe77f..f260e27 100644
--- a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt
+++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt
@@ -188,7 +188,7 @@
                         ?: throw IllegalArgumentException(
                             "Invalid feature version input for $name: ${featureArgs[1]}"
                         )
-                FeatureInfo(name, featureArgs[1].toInt(), readonly = true)
+                FeatureInfo(name, featureVersion, readonly = true)
             }
         }
     }