Merge "Update comments to point to the new location of event.logtags." into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 1d12378..ed46cdd 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -49,7 +49,6 @@
         "android.media.tv.flags-aconfig-java",
         "android.multiuser.flags-aconfig-java",
         "android.net.platform.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",
@@ -89,6 +88,7 @@
         "com.android.media.flags.editing-aconfig-java",
         "com.android.media.flags.performance-aconfig-java",
         "com.android.media.flags.projection-aconfig-java",
+        "com.android.net.http.flags-aconfig-exported-java",
         "com.android.net.thread.platform.flags-aconfig-java",
         "com.android.ranging.flags.ranging-aconfig-java-export",
         "com.android.server.contextualsearch.flags-java",
@@ -279,6 +279,7 @@
     name: "android_nfc_flags_aconfig_c_lib",
     vendor_available: true,
     aconfig_declarations: "android.nfc.flags-aconfig",
+    min_sdk_version: "34",
     apex_available: [
         "//apex_available:platform",
         "com.android.nfcservices",
@@ -375,6 +376,8 @@
     min_sdk_version: "30",
     apex_available: [
         "//apex_available:platform",
+        "com.android.art",
+        "com.android.art.debug",
         "com.android.btservices",
         "com.android.mediaprovider",
         "com.android.permission",
@@ -1064,25 +1067,6 @@
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
-// 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: "com.android.tethering",
-    exportable: true,
-    srcs: ["core/java/android/net/vcn/*.aconfig"],
-}
-
-java_aconfig_library {
-    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"],
-}
-
 // DevicePolicy
 aconfig_declarations {
     name: "device_policy_aconfig_flags",
diff --git a/Android.bp b/Android.bp
index 20e58ed..68048c6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -87,6 +87,7 @@
         ":framework-wifi-non-updatable-sources",
         ":PacProcessor-aidl-sources",
         ":ProxyHandler-aidl-sources",
+        ":vcn-utils-platform-sources",
         ":net-utils-framework-common-srcs",
 
         // AIDL from frameworks/base/native/
@@ -314,6 +315,7 @@
             ":framework-telephony-sources",
             ":framework-wifi-annotations",
             ":framework-wifi-non-updatable-sources",
+            ":vcn-utils-platform-sources",
             ":PacProcessor-aidl-sources",
             ":ProxyHandler-aidl-sources",
             ":net-utils-framework-common-srcs",
@@ -582,7 +584,7 @@
     srcs: [
         "core/java/com/android/internal/util/HexDump.java",
         "core/java/com/android/internal/util/WakeupMessage.java",
-        "core/java/android/net/vcn/util/PersistableBundleUtils.java",
+        "packages/Vcn/framework-b/src/android/net/vcn/util/PersistableBundleUtils.java",
         "telephony/java/android/telephony/Annotation.java",
     ],
 }
diff --git a/core/api/current.txt b/core/api/current.txt
index 1f10678..3effcc6 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -16734,7 +16734,7 @@
     method public void arcTo(@NonNull android.graphics.RectF, float, float);
     method public void arcTo(float, float, float, float, float, float, boolean);
     method public void close();
-    method @Deprecated public void computeBounds(@NonNull android.graphics.RectF, boolean);
+    method public void computeBounds(@NonNull android.graphics.RectF, boolean);
     method @FlaggedApi("com.android.graphics.flags.exact_compute_bounds") public void computeBounds(@NonNull android.graphics.RectF);
     method public void conicTo(float, float, float, float, float);
     method public void cubicTo(float, float, float, float, float, float);
@@ -29468,128 +29468,6 @@
 
 }
 
-package android.net.vcn {
-
-  public final class VcnCellUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate {
-    method public int getCbs();
-    method public int getDun();
-    method public int getIms();
-    method public int getInternet();
-    method public int getMms();
-    method @NonNull public java.util.Set<java.lang.String> getOperatorPlmnIds();
-    method public int getOpportunistic();
-    method public int getRcs();
-    method public int getRoaming();
-    method @NonNull public java.util.Set<java.lang.Integer> getSimSpecificCarrierIds();
-  }
-
-  public static final class VcnCellUnderlyingNetworkTemplate.Builder {
-    ctor public VcnCellUnderlyingNetworkTemplate.Builder();
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate build();
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setCbs(int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setDun(int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setIms(int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setInternet(int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMetered(int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMms(int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOperatorPlmnIds(@NonNull java.util.Set<java.lang.String>);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOpportunistic(int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRcs(int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRoaming(int);
-    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setSimSpecificCarrierIds(@NonNull java.util.Set<java.lang.Integer>);
-  }
-
-  public final class VcnConfig implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public java.util.Set<android.net.vcn.VcnGatewayConnectionConfig> getGatewayConnectionConfigs();
-    method @NonNull public java.util.Set<java.lang.Integer> getRestrictedUnderlyingNetworkTransports();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnConfig> CREATOR;
-  }
-
-  public static final class VcnConfig.Builder {
-    ctor public VcnConfig.Builder(@NonNull android.content.Context);
-    method @NonNull public android.net.vcn.VcnConfig.Builder addGatewayConnectionConfig(@NonNull android.net.vcn.VcnGatewayConnectionConfig);
-    method @NonNull public android.net.vcn.VcnConfig build();
-    method @NonNull public android.net.vcn.VcnConfig.Builder setRestrictedUnderlyingNetworkTransports(@NonNull java.util.Set<java.lang.Integer>);
-  }
-
-  public final class VcnGatewayConnectionConfig {
-    method @NonNull public int[] getExposedCapabilities();
-    method @NonNull public String getGatewayConnectionName();
-    method @IntRange(from=0x500) public int getMaxMtu();
-    method public int getMinUdpPort4500NatTimeoutSeconds();
-    method @NonNull public long[] getRetryIntervalsMillis();
-    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
-  }
-
-  public static final class VcnGatewayConnectionConfig.Builder {
-    ctor public VcnGatewayConnectionConfig.Builder(@NonNull String, @NonNull android.net.ipsec.ike.IkeTunnelConnectionParams);
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int);
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addGatewayOption(int);
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build();
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int);
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeGatewayOption(int);
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int);
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int);
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]);
-    method @FlaggedApi("android.net.vcn.safe_mode_config") @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setSafeModeEnabled(boolean);
-    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate>);
-  }
-
-  public class VcnManager {
-    method @RequiresPermission("carrier privileges") public void clearVcnConfig(@NonNull android.os.ParcelUuid) throws java.io.IOException;
-    method @NonNull public java.util.List<android.os.ParcelUuid> getConfiguredSubscriptionGroups();
-    method public void registerVcnStatusCallback(@NonNull android.os.ParcelUuid, @NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnStatusCallback);
-    method @RequiresPermission("carrier privileges") public void setVcnConfig(@NonNull android.os.ParcelUuid, @NonNull android.net.vcn.VcnConfig) throws java.io.IOException;
-    method public void unregisterVcnStatusCallback(@NonNull android.net.vcn.VcnManager.VcnStatusCallback);
-    field public static final int VCN_ERROR_CODE_CONFIG_ERROR = 1; // 0x1
-    field public static final int VCN_ERROR_CODE_INTERNAL_ERROR = 0; // 0x0
-    field public static final int VCN_ERROR_CODE_NETWORK_ERROR = 2; // 0x2
-    field public static final int VCN_STATUS_CODE_ACTIVE = 2; // 0x2
-    field public static final int VCN_STATUS_CODE_INACTIVE = 1; // 0x1
-    field public static final int VCN_STATUS_CODE_NOT_CONFIGURED = 0; // 0x0
-    field public static final int VCN_STATUS_CODE_SAFE_MODE = 3; // 0x3
-  }
-
-  public abstract static class VcnManager.VcnStatusCallback {
-    ctor public VcnManager.VcnStatusCallback();
-    method public abstract void onGatewayConnectionError(@NonNull String, int, @Nullable Throwable);
-    method public abstract void onStatusChanged(int);
-  }
-
-  public abstract class VcnUnderlyingNetworkTemplate {
-    method public int getMetered();
-    method public int getMinEntryDownstreamBandwidthKbps();
-    method public int getMinEntryUpstreamBandwidthKbps();
-    method public int getMinExitDownstreamBandwidthKbps();
-    method public int getMinExitUpstreamBandwidthKbps();
-    field public static final int MATCH_ANY = 0; // 0x0
-    field public static final int MATCH_FORBIDDEN = 2; // 0x2
-    field public static final int MATCH_REQUIRED = 1; // 0x1
-  }
-
-  public final class VcnWifiUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate {
-    method @NonNull public java.util.Set<java.lang.String> getSsids();
-  }
-
-  public static final class VcnWifiUnderlyingNetworkTemplate.Builder {
-    ctor public VcnWifiUnderlyingNetworkTemplate.Builder();
-    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate build();
-    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMetered(int);
-    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int);
-    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int);
-    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setSsids(@NonNull java.util.Set<java.lang.String>);
-  }
-
-}
-
 package android.opengl {
 
   public class EGL14 {
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 149e474..5790a73 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -273,10 +273,6 @@
 
 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);
   }
@@ -336,25 +332,6 @@
 
 }
 
-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 {
@@ -499,6 +476,10 @@
     field public static final long TRACE_TAG_NETWORK = 2097152L; // 0x200000L
   }
 
+  public class UpdateEngine {
+    method @FlaggedApi("android.os.update_engine_api") public void triggerPostinstall(@NonNull String);
+  }
+
 }
 
 package android.os.storage {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index f94c97e2..f722ba2 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -9977,28 +9977,6 @@
 
 }
 
-package android.net.vcn {
-
-  public class VcnManager {
-    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void removeVcnNetworkPolicyChangeListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
-  }
-
-  public static interface VcnManager.VcnNetworkPolicyChangeListener {
-    method public void onPolicyChanged();
-  }
-
-  public final class VcnNetworkPolicyResult implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
-    method public boolean isTeardownRequested();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnNetworkPolicyResult> CREATOR;
-  }
-
-}
-
 package android.net.wifi {
 
   public final class WifiKeystore {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 5e69ec1..fb7030f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -6859,21 +6859,44 @@
 
     final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) {
         if (start) {
-            try {
-                switch (profileType) {
-                    default:
+            switch (profileType) {
+                case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD:
+                    if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) {
+                        Slog.w(TAG, "Low overhead tracing feature is not enabled");
+                        break;
+                    }
+                    VMDebug.startLowOverheadTrace();
+                    break;
+                default:
+                    try {
                         mProfiler.setProfiler(profilerInfo);
                         mProfiler.startProfiling();
                         break;
-                }
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
-                        + " -- can the process access this path?");
-            } finally {
-                profilerInfo.closeFd();
+                    } catch (RuntimeException e) {
+                        Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile
+                                + " -- can the process access this path?");
+                    } finally {
+                        profilerInfo.closeFd();
+                    }
             }
         } else {
             switch (profileType) {
+                case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD:
+                    if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) {
+                        if (profilerInfo != null) {
+                            profilerInfo.closeFd();
+                        }
+                        Slog.w(TAG, "Low overhead tracing feature is not enabled");
+                        break;
+                    }
+                    if (profilerInfo != null) {
+                        FileDescriptor fd = profilerInfo.profileFd.getFileDescriptor();
+                        VMDebug.TraceDestination dst =
+                                VMDebug.TraceDestination.fromFileDescriptor(fd);
+                        VMDebug.dumpLowOverheadTrace(dst);
+                    }
+                    VMDebug.stopLowOverheadTrace();
+                    break;
                 default:
                     mProfiler.stopProfiling();
                     break;
diff --git a/core/java/android/app/ProfilerInfo.java b/core/java/android/app/ProfilerInfo.java
index bcae22a..0348b6d 100644
--- a/core/java/android/app/ProfilerInfo.java
+++ b/core/java/android/app/ProfilerInfo.java
@@ -32,6 +32,12 @@
  * {@hide}
  */
 public class ProfilerInfo implements Parcelable {
+    // Regular profiling which provides different modes of profiling at some performance cost.
+    public static final int PROFILE_TYPE_REGULAR = 0;
+
+    // Low overhead profiling that captures a simple sliding window of past events.
+    public static final int PROFILE_TYPE_LOW_OVERHEAD = 1;
+
     // Version of the profiler output
     public static final int OUTPUT_VERSION_DEFAULT = 1;
     // CLOCK_TYPE_DEFAULT chooses the default used by ART. ART uses CLOCK_TYPE_DUAL by default (see
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 918ae1c..4137a5f 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -71,8 +71,6 @@
 import android.content.Context;
 import android.content.IRestrictionsManager;
 import android.content.RestrictionsManager;
-import android.content.integrity.AppIntegrityManager;
-import android.content.integrity.IAppIntegrityManager;
 import android.content.om.IOverlayManager;
 import android.content.om.OverlayManager;
 import android.content.pm.ApplicationInfo;
@@ -1497,16 +1495,6 @@
                         return new AttestationVerificationManager(ctx.getOuterContext(),
                                 IAttestationVerificationManagerService.Stub.asInterface(b));
                     }});
-
-        //CHECKSTYLE:ON IndentationCheck
-        registerService(Context.APP_INTEGRITY_SERVICE, AppIntegrityManager.class,
-                new CachedServiceFetcher<AppIntegrityManager>() {
-                    @Override
-                    public AppIntegrityManager createService(ContextImpl ctx)
-                            throws ServiceNotFoundException {
-                        IBinder b = ServiceManager.getServiceOrThrow(Context.APP_INTEGRITY_SERVICE);
-                        return new AppIntegrityManager(IAppIntegrityManager.Stub.asInterface(b));
-                    }});
         registerService(Context.APP_HIBERNATION_SERVICE, AppHibernationManager.class,
                 new CachedServiceFetcher<AppHibernationManager>() {
                     @Override
diff --git a/core/java/android/net/LocalSocket.java b/core/java/android/net/LocalSocket.java
index a86396c..0fedf8e 100644
--- a/core/java/android/net/LocalSocket.java
+++ b/core/java/android/net/LocalSocket.java
@@ -65,7 +65,7 @@
     }
 
     /**
-     * Creates a AF_LOCAL/UNIX domain stream socket with given socket type
+     * Creates a AF_LOCAL/UNIX domain socket with the given socket type.
      *
      * @param sockType either {@link #SOCKET_DGRAM}, {@link #SOCKET_STREAM}
      * or {@link #SOCKET_SEQPACKET}
diff --git a/core/java/android/net/metrics/DnsEvent.java b/core/java/android/net/metrics/DnsEvent.java
index bf351ce..f53d1c4 100644
--- a/core/java/android/net/metrics/DnsEvent.java
+++ b/core/java/android/net/metrics/DnsEvent.java
@@ -62,7 +62,11 @@
             return isSuccess;
         }
         if (eventCount == eventTypes.length) {
-            resize((int) (1.4 * eventCount));
+            int resizeLength = (int) (1.4 * eventCount);
+            if (eventCount == resizeLength) {
+                resizeLength++;
+            }
+            resize(resizeLength);
         }
         eventTypes[eventCount] = eventType;
         returnCodes[eventCount] = returnCode;
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index bfcc5cc..8d35338 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -118,9 +118,10 @@
 # Memory
 per-file OomKillRecord.java = file:/MEMORY_OWNERS
 
-# MessageQueue
+# MessageQueue and related classes
 per-file MessageQueue.java = [email protected], [email protected]
 per-file Message.java = [email protected], [email protected]
+per-file TestLooperManager.java = [email protected], [email protected]
 
 # Stats
 per-file IStatsBootstrapAtomService.aidl = file:/services/core/java/com/android/server/stats/OWNERS
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index f728552..a41cdd2 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -892,6 +892,12 @@
 
     /**
      * Report whether the parcel contains any marshalled file descriptors.
+     *
+     * WARNING: Parcelable definitions change over time. Unless you define
+     * a Parcelable yourself OR the Parcelable explicitly guarantees that
+     * it would never include such objects, you should not expect the return
+     * value to stay the same, and your code should continue to work even
+     * if the return value changes.
      */
     public boolean hasFileDescriptors() {
         return nativeHasFileDescriptors(mNativePtr);
@@ -901,6 +907,12 @@
      * Report whether the parcel contains any marshalled file descriptors in the range defined by
      * {@code offset} and {@code length}.
      *
+     * WARNING: Parcelable definitions change over time. Unless you define
+     * a Parcelable yourself OR the Parcelable explicitly guarantees that
+     * it would never include such objects, you should not expect the return
+     * value to stay the same, and your code should continue to work even
+     * if the return value changes.
+     *
      * @param offset The offset from which the range starts. Should be between 0 and
      *     {@link #dataSize()}.
      * @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
@@ -921,6 +933,12 @@
      * <p>For most cases, it will use the self-reported {@link Parcelable#describeContents()} method
      * for that.
      *
+     * WARNING: Parcelable definitions change over time. Unless you define
+     * a Parcelable yourself OR the Parcelable explicitly guarantees that
+     * it would never include such objects, you should not expect the return
+     * value to stay the same, and your code should continue to work even
+     * if the return value changes.
+     *
      * @throws IllegalArgumentException if you provide any object not supported by above methods
      *     (including if the unsupported object is inside a nested container).
      *
@@ -990,6 +1008,13 @@
      *
      * @throws UnsupportedOperationException if binder kernel driver was disabled or if method was
      *                                       invoked in case of Binder RPC protocol.
+     *
+     * WARNING: Parcelable definitions change over time. Unless you define
+     * a Parcelable yourself OR the Parcelable explicitly guarantees that
+     * it would never include such objects, you should not expect the return
+     * value to stay the same, and your code should continue to work even
+     * if the return value changes.
+     *
      * @hide
      */
     public boolean hasBinders() {
@@ -1000,6 +1025,12 @@
      * Report whether the parcel contains any marshalled {@link IBinder} objects in the range
      * defined by {@code offset} and {@code length}.
      *
+     * WARNING: Parcelable definitions change over time. Unless you define
+     * a Parcelable yourself OR the Parcelable explicitly guarantees that
+     * it would never include such objects, you should not expect the return
+     * value to stay the same, and your code should continue to work even
+     * if the return value changes.
+     *
      * @param offset The offset from which the range starts. Should be between 0 and
      *               {@link #dataSize()}.
      * @param length The length of the range. Should be between 0 and {@link #dataSize()} - {@code
diff --git a/core/java/android/os/SELinux.java b/core/java/android/os/SELinux.java
index f64a8117..11c54ef 100644
--- a/core/java/android/os/SELinux.java
+++ b/core/java/android/os/SELinux.java
@@ -193,4 +193,31 @@
             return false;
         }
     }
+
+    /**
+     * Gets the genfs labels version of the vendor. The genfs labels version is
+     * specified in {@code /vendor/etc/selinux/genfs_labels_version.txt}. The
+     * version follows the VINTF version format "YYYYMM" and affects how {@code
+     * genfs_contexts} entries are applied.
+     *
+     * <p>The genfs labels version indicates changes in the SELinux labeling
+     * scheme over time. For example:
+     * <ul>
+     *   <li>For version 202504 and later, {@code /sys/class/udc} is labeled as
+     *   {@code sysfs_udc}.
+     *   <li>For version 202404 and earlier, {@code /sys/class/udc} is labeled
+     *   as {@code sysfs}.
+     * </ul>
+     * Check {@code /system/etc/selinux/plat_sepolicy_genfs_{version}.cil} to
+     * see which labels are new in {version}.
+     *
+     * <p>Older vendors may override {@code genfs_contexts} with vendor-specific
+     * extensions. The framework must not break such labellings to maintain
+     * compatibility with such vendors, by checking the genfs labels version and
+     * implementing a fallback mechanism.
+     *
+     * @return an integer representing the genfs labels version of /vendor, in
+     *         the format YYYYMM.
+     */
+    public static final native int getGenfsLabelsVersion();
 }
diff --git a/core/java/android/os/ServiceManager.java b/core/java/android/os/ServiceManager.java
index 8aec7eb..9085fe0 100644
--- a/core/java/android/os/ServiceManager.java
+++ b/core/java/android/os/ServiceManager.java
@@ -277,7 +277,8 @@
             if (service != null) {
                 return service;
             } else {
-                return Binder.allowBlocking(getIServiceManager().checkService(name).getBinder());
+                return Binder.allowBlocking(
+                        getIServiceManager().checkService(name).getServiceWithMetadata().service);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "error in checkService", e);
@@ -425,7 +426,8 @@
     private static IBinder rawGetService(String name) throws RemoteException {
         final long start = sStatLogger.getTime();
 
-        final IBinder binder = getIServiceManager().getService2(name).getBinder();
+        final IBinder binder =
+                getIServiceManager().getService2(name).getServiceWithMetadata().service;
 
         final int time = (int) sStatLogger.logDurationStat(Stats.GET_SERVICE, start);
 
diff --git a/core/java/android/os/ServiceManagerNative.java b/core/java/android/os/ServiceManagerNative.java
index 5a9c878..49b696d 100644
--- a/core/java/android/os/ServiceManagerNative.java
+++ b/core/java/android/os/ServiceManagerNative.java
@@ -61,7 +61,7 @@
     @UnsupportedAppUsage
     public IBinder getService(String name) throws RemoteException {
         // Same as checkService (old versions of servicemanager had both methods).
-        return checkService(name).getBinder();
+        return checkService(name).getServiceWithMetadata().service;
     }
 
     public Service getService2(String name) throws RemoteException {
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index 0a8f62f..81e4549 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -16,6 +16,7 @@
 
 package android.os;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
@@ -667,4 +668,23 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    /**
+     * Run postinstall script for specified partition |partition|
+     *
+     * @param partition The partition to trigger postinstall runs
+     *
+     * @throws ServiceSpecificException error code of this exception would be one of
+     * https://cs.android.com/android/platform/superproject/main/+/main:system/update_engine/common/error_code.h
+     * @hide
+     */
+    @FlaggedApi(Flags.FLAG_UPDATE_ENGINE_API)
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void triggerPostinstall(@NonNull String partition) {
+        try {
+            mUpdateEngine.triggerPostinstall(partition);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 5d1d758..392b42d 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -105,6 +105,7 @@
     namespace: "biometrics"
     description: "Clear StrongAuth on add credential"
     bug: "320817991"
+    is_exported: true
 }
 
 flag {
@@ -127,4 +128,5 @@
     namespace: "hardware_backed_security"
     description: "Feature flag for exposing KeyStore grant APIs"
     bug: "351158708"
+    is_exported: true
 }
diff --git a/core/java/android/security/net/config/CertificatesEntryRef.java b/core/java/android/security/net/config/CertificatesEntryRef.java
index 45cd0f0..a46049f 100644
--- a/core/java/android/security/net/config/CertificatesEntryRef.java
+++ b/core/java/android/security/net/config/CertificatesEntryRef.java
@@ -17,6 +17,7 @@
 package android.security.net.config;
 
 import android.util.ArraySet;
+
 import java.security.cert.X509Certificate;
 import java.util.Set;
 
@@ -24,16 +25,23 @@
 public final class CertificatesEntryRef {
     private final CertificateSource mSource;
     private final boolean mOverridesPins;
+    private final boolean mDisableCT;
 
-    public CertificatesEntryRef(CertificateSource source, boolean overridesPins) {
+    public CertificatesEntryRef(CertificateSource source, boolean overridesPins,
+            boolean disableCT) {
         mSource = source;
         mOverridesPins = overridesPins;
+        mDisableCT = disableCT;
     }
 
     boolean overridesPins() {
         return mOverridesPins;
     }
 
+    boolean disableCT() {
+        return mDisableCT;
+    }
+
     public Set<TrustAnchor> getTrustAnchors() {
         // TODO: cache this [but handle mutable sources]
         Set<TrustAnchor> anchors = new ArraySet<TrustAnchor>();
diff --git a/core/java/android/security/net/config/KeyStoreConfigSource.java b/core/java/android/security/net/config/KeyStoreConfigSource.java
index 8d4f098..a54d8d0 100644
--- a/core/java/android/security/net/config/KeyStoreConfigSource.java
+++ b/core/java/android/security/net/config/KeyStoreConfigSource.java
@@ -17,8 +17,8 @@
 package android.security.net.config;
 
 import android.util.Pair;
+
 import java.security.KeyStore;
-import java.security.KeyStoreException;
 import java.util.Set;
 
 /**
@@ -32,7 +32,7 @@
         mConfig = new NetworkSecurityConfig.Builder()
                 .addCertificatesEntryRef(
                         // Use the KeyStore and do not override pins (of which there are none).
-                        new CertificatesEntryRef(new KeyStoreCertificateSource(ks), false))
+                        new CertificatesEntryRef(new KeyStoreCertificateSource(ks), false, false))
                 .build();
     }
 
diff --git a/core/java/android/security/net/config/NetworkSecurityConfig.java b/core/java/android/security/net/config/NetworkSecurityConfig.java
index 129ae63..410c68b 100644
--- a/core/java/android/security/net/config/NetworkSecurityConfig.java
+++ b/core/java/android/security/net/config/NetworkSecurityConfig.java
@@ -112,7 +112,6 @@
         return mHstsEnforced;
     }
 
-    // TODO(b/28746284): add exceptions for user-added certificates and enterprise overrides.
     public boolean isCertificateTransparencyVerificationRequired() {
         return mCertificateTransparencyVerificationRequired;
     }
@@ -192,20 +191,21 @@
      * @hide
      */
     public static Builder getDefaultBuilder(ApplicationInfo info) {
+        // System certificate store, does not bypass static pins, does not disable CT.
+        CertificatesEntryRef systemRef = new CertificatesEntryRef(
+                SystemCertificateSource.getInstance(), false, false);
         Builder builder = new Builder()
                 .setHstsEnforced(DEFAULT_HSTS_ENFORCED)
-                // System certificate store, does not bypass static pins.
-                .addCertificatesEntryRef(
-                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false));
+                .addCertificatesEntryRef(systemRef);
         final boolean cleartextTrafficPermitted = info.targetSdkVersion < Build.VERSION_CODES.P
                 && !info.isInstantApp();
         builder.setCleartextTrafficPermitted(cleartextTrafficPermitted);
         // Applications targeting N and above must opt in into trusting the user added certificate
         // store.
         if (info.targetSdkVersion <= Build.VERSION_CODES.M && !info.isPrivilegedApp()) {
-            // User certificate store, does not bypass static pins.
+            // User certificate store, does not bypass static pins. CT is disabled.
             builder.addCertificatesEntryRef(
-                    new CertificatesEntryRef(UserCertificateSource.getInstance(), false));
+                    new CertificatesEntryRef(UserCertificateSource.getInstance(), false, true));
         }
         return builder;
     }
@@ -339,6 +339,16 @@
             if (mCertificateTransparencyVerificationRequiredSet) {
                 return mCertificateTransparencyVerificationRequired;
             }
+            // CT verification has not been set explicitly. Before deferring to
+            // the parent, check if any of the CertificatesEntryRef requires it
+            // to be disabled (i.e., user store or inline certificate).
+            if (hasCertificatesEntryRefs()) {
+                for (CertificatesEntryRef ref : getCertificatesEntryRefs()) {
+                    if (ref.disableCT()) {
+                        return false;
+                    }
+                }
+            }
             if (mParentBuilder != null) {
                 return mParentBuilder.getCertificateTransparencyVerificationRequired();
             }
diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java
index b1c1479..95e579fc 100644
--- a/core/java/android/security/net/config/XmlConfigSource.java
+++ b/core/java/android/security/net/config/XmlConfigSource.java
@@ -182,6 +182,7 @@
         boolean overridePins =
                 parser.getAttributeBooleanValue(null, "overridePins", defaultOverridePins);
         int sourceId = parser.getAttributeResourceValue(null, "src", -1);
+        boolean disableCT = false;
         String sourceString = parser.getAttributeValue(null, "src");
         CertificateSource source = null;
         if (sourceString == null) {
@@ -190,10 +191,12 @@
         if (sourceId != -1) {
             // TODO: Cache ResourceCertificateSources by sourceId
             source = new ResourceCertificateSource(sourceId, mContext);
+            disableCT = true;
         } else if ("system".equals(sourceString)) {
             source = SystemCertificateSource.getInstance();
         } else if ("user".equals(sourceString)) {
             source = UserCertificateSource.getInstance();
+            disableCT = true;
         } else if ("wfa".equals(sourceString)) {
             source = WfaCertificateSource.getInstance();
         } else {
@@ -201,7 +204,7 @@
                     + "Should be one of system|user|@resourceVal");
         }
         XmlUtils.skipCurrentTag(parser);
-        return new CertificatesEntryRef(source, overridePins);
+        return new CertificatesEntryRef(source, overridePins, disableCT);
     }
 
     private Collection<CertificatesEntryRef> parseTrustAnchors(XmlResourceParser parser,
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index bd9ab86..6473cd8 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -2310,7 +2310,6 @@
         // -- parcelable interface --
 
         private RankingMap(Parcel in) {
-            final ClassLoader cl = getClass().getClassLoader();
             final int count = in.readInt();
             mOrderedKeys.ensureCapacity(count);
             mRankings.ensureCapacity(count);
diff --git a/core/java/android/service/voice/OWNERS b/core/java/android/service/voice/OWNERS
index 5f9f6bd..b6f0270 100644
--- a/core/java/android/service/voice/OWNERS
+++ b/core/java/android/service/voice/OWNERS
@@ -1,6 +1,6 @@
 # Bug component: 533220
-
 include /core/java/android/app/assist/OWNERS
[email protected]
 
 # The owner here should not be assist owner
 [email protected]
diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING
index 83773e2..f431e93 100644
--- a/core/java/com/android/internal/os/TEST_MAPPING
+++ b/core/java/com/android/internal/os/TEST_MAPPING
@@ -20,7 +20,7 @@
       "file_patterns": [
         "BinderDeathDispatcher\\.java"
       ],
-      "name": "FrameworksCoreTests_internal_os_binder"
+      "name": "FrameworksCoreTests_all_binder"
     },
     {
       "file_patterns": [
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index e402ddf..e60879e 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -19,6 +19,8 @@
 import static android.system.OsConstants.S_IRWXG;
 import static android.system.OsConstants.S_IRWXO;
 
+import static android.net.http.Flags.preloadHttpengineInZygote;
+
 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START;
 import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START;
 
@@ -27,6 +29,7 @@
 import android.content.pm.SharedLibraryInfo;
 import android.content.res.Resources;
 import android.os.Build;
+import android.net.http.HttpEngine;
 import android.os.Environment;
 import android.os.IInstalld;
 import android.os.Process;
@@ -144,6 +147,23 @@
         Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
         preloadSharedLibraries();
         preloadTextResources();
+
+        // TODO: remove the try/catch and the flag read as soon as the flag is ramped and 25Q2
+        // starts building from source.
+        if (preloadHttpengineInZygote()) {
+            try {
+                HttpEngine.preload();
+            } catch (NoSuchMethodError e){
+                // The flag protecting this API is not an exported
+                // flag because ZygoteInit happens before the
+                // system service has initialized the flag which means
+                // that we can't query the real value of the flag
+                // from the tethering module. In order to avoid crashing
+                // in the case where we have (new zygote, old tethering).
+                // we catch the NoSuchMethodError and just log.
+                Log.d(TAG, "HttpEngine.preload() threw " + e);
+            }
+        }
         // Ask the WebViewFactory to do any initialization that must run in the zygote process,
         // for memory sharing purposes.
         WebViewFactory.prepareWebViewInZygote();
diff --git a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
index f306b0b..27dbd98 100644
--- a/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
+++ b/core/java/com/android/internal/pm/pkg/component/AconfigFlags.java
@@ -218,16 +218,12 @@
             negated = true;
             featureFlag = featureFlag.substring(1).strip();
         }
-        final Boolean flagValue = getFlagValue(featureFlag);
+        Boolean flagValue = getFlagValue(featureFlag);
         if (flagValue == null) {
-            Slog.w(LOG_TAG, "Skipping element " + parser.getName()
-                    + " due to unknown feature flag " + featureFlag);
-            return true;
+            flagValue = false;
         }
         // Skip if flag==false && attr=="flag" OR flag==true && attr=="!flag" (negated)
         if (flagValue == negated) {
-            Slog.v(LOG_TAG, "Skipping element " + parser.getName()
-                    + " behind feature flag " + featureFlag + " = " + flagValue);
             return true;
         }
         return false;
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 11123a9..4d1c98d 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -20,6 +20,7 @@
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
+import android.ravenwood.annotation.RavenwoodReplace;
 import android.util.ArraySet;
 import android.util.EmptyArray;
 
@@ -39,6 +40,10 @@
 
 /**
  * Static utility methods for arrays that aren't already included in {@link java.util.Arrays}.
+ * <p>
+ * Test with:
+ * <code>atest FrameworksUtilTests:com.android.internal.util.ArrayUtilsTest</code>
+ * <code>atest FrameworksUtilTestsRavenwood:com.android.internal.util.ArrayUtilsTest</code>
  */
 @android.ravenwood.annotation.RavenwoodKeepWholeClass
 public class ArrayUtils {
@@ -85,6 +90,69 @@
     }
 
     /**
+     * This is like <code>new byte[length]</code>, but it allocates the array as non-movable. This
+     * prevents copies of the data from being left on the Java heap as a result of heap compaction.
+     * Use this when the array will contain sensitive data such as a password or cryptographic key
+     * that needs to be wiped from memory when no longer needed. The owner of the array is still
+     * responsible for the zeroization; {@link #zeroize(byte[])} should be used to do so.
+     *
+     * @param length the length of the array to allocate
+     * @return the new array
+     */
+    public static byte[] newNonMovableByteArray(int length) {
+        return (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, length);
+    }
+
+    /**
+     * Like {@link #newNonMovableByteArray(int)}, but allocates a char array.
+     *
+     * @param length the length of the array to allocate
+     * @return the new array
+     */
+    public static char[] newNonMovableCharArray(int length) {
+        return (char[]) VMRuntime.getRuntime().newNonMovableArray(char.class, length);
+    }
+
+    /**
+     * Zeroizes a byte array as securely as possible. Use this when the array contains sensitive
+     * data such as a password or cryptographic key.
+     * <p>
+     * This zeroizes the array in a way that is guaranteed to not be optimized out by the compiler.
+     * If supported by the architecture, it zeroizes the data not just in the L1 data cache but also
+     * in other levels of the memory hierarchy up to and including main memory (but not above that).
+     * <p>
+     * This works on any <code>byte[]</code>, but to ensure that copies of the array aren't left on
+     * the Java heap the array should have been allocated with {@link #newNonMovableByteArray(int)}.
+     * Use on other arrays might also introduce performance anomalies.
+     *
+     * @param array the array to zeroize. If null, this method has no effect.
+     */
+    @RavenwoodReplace public static native void zeroize(byte[] array);
+
+    /**
+     * Replacement of the above method for host-side unit testing that doesn't support JNI yet.
+     */
+    public static void zeroize$ravenwood(byte[] array) {
+        if (array != null) {
+            Arrays.fill(array, (byte) 0);
+        }
+    }
+
+    /**
+     * Like {@link #zeroize(byte[])}, but for char arrays.
+     */
+    @RavenwoodReplace public static native void zeroize(char[] array);
+
+    /**
+     * Replacement of the above method for host-side unit testing that doesn't support JNI yet.
+     */
+    public static void zeroize$ravenwood(char[] array) {
+        if (array != null) {
+            Arrays.fill(array, (char) 0);
+        }
+    }
+
+    /**
      * Checks if the beginnings of two byte arrays are equal.
      *
      * @param array1 the first byte array
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index f6689d5..e71f607 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -90,6 +90,7 @@
         "android_view_VelocityTracker.cpp",
         "android_view_VerifiedKeyEvent.cpp",
         "android_view_VerifiedMotionEvent.cpp",
+        "com_android_internal_util_ArrayUtils.cpp",
         "com_android_internal_util_VirtualRefBasePtr.cpp",
         "core_jni_helpers.cpp",
         ":deviceproductinfoconstants_aidl",
@@ -287,6 +288,7 @@
                 "libasync_safe",
                 "libbinderthreadstateutils",
                 "libdmabufinfo",
+                "libgenfslabelsversion.ffi",
                 "libgui_window_info_static",
                 "libkernelconfigs",
                 "libnativehelper_lazy",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c5df248..c005d63 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -215,6 +215,7 @@
 extern int register_com_android_internal_os_ZygoteCommandBuffer(JNIEnv *env);
 extern int register_com_android_internal_os_ZygoteInit(JNIEnv *env);
 extern int register_com_android_internal_security_VerityUtils(JNIEnv* env);
+extern int register_com_android_internal_util_ArrayUtils(JNIEnv* env);
 extern int register_com_android_internal_util_VirtualRefBasePtr(JNIEnv *env);
 extern int register_android_window_WindowInfosListener(JNIEnv* env);
 extern int register_android_window_ScreenCapture(JNIEnv* env);
@@ -1613,6 +1614,7 @@
         REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer),
         REG_JNI(register_com_android_internal_os_ZygoteInit),
         REG_JNI(register_com_android_internal_security_VerityUtils),
+        REG_JNI(register_com_android_internal_util_ArrayUtils),
         REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
         REG_JNI(register_android_hardware_Camera),
         REG_JNI(register_android_hardware_camera2_CameraMetadata),
diff --git a/core/jni/android_os_SELinux.cpp b/core/jni/android_os_SELinux.cpp
index 7a4670f4..805d5ad 100644
--- a/core/jni/android_os_SELinux.cpp
+++ b/core/jni/android_os_SELinux.cpp
@@ -18,18 +18,19 @@
 
 #include <errno.h>
 #include <fcntl.h>
-
-#include <utils/Log.h>
-
+#include <genfslabelsversion.h>
 #include <nativehelper/JNIPlatformHelp.h>
-#include "jni.h"
-#include "core_jni_helpers.h"
-#include "selinux/selinux.h"
-#include "selinux/android.h"
-#include <memory>
-#include <atomic>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedUtfChars.h>
+#include <utils/Log.h>
+
+#include <atomic>
+#include <memory>
+
+#include "core_jni_helpers.h"
+#include "jni.h"
+#include "selinux/android.h"
+#include "selinux/selinux.h"
 
 namespace android {
 namespace {
@@ -404,8 +405,19 @@
 }
 
 /*
+ * Function: getGenfsLabelsVersion
+ * Purpose: get which genfs labels version /vendor uses
+ * Returns: int: genfs labels version of /vendor
+ * Exceptions: none
+ */
+static jint getGenfsLabelsVersion(JNIEnv *, jclass) {
+    return get_genfs_labels_version();
+}
+
+/*
  * JNI registration.
  */
+// clang-format off
 static const JNINativeMethod method_table[] = {
     /* name,                     signature,                    funcPtr */
     { "checkSELinuxAccess"       , "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z" , (void*)checkSELinuxAccess },
@@ -420,7 +432,9 @@
     { "setFileContext"           , "(Ljava/lang/String;Ljava/lang/String;)Z"      , (void*)setFileCon       },
     { "setFSCreateContext"       , "(Ljava/lang/String;)Z"                        , (void*)setFSCreateCon   },
     { "fileSelabelLookup"        , "(Ljava/lang/String;)Ljava/lang/String;"       , (void*)fileSelabelLookup},
+    { "getGenfsLabelsVersion"    , "()I"                                          , (void *)getGenfsLabelsVersion},
 };
+// clang-format on
 
 static int log_callback(int type, const char *fmt, ...) {
     va_list ap;
diff --git a/core/jni/com_android_internal_util_ArrayUtils.cpp b/core/jni/com_android_internal_util_ArrayUtils.cpp
new file mode 100644
index 0000000..c706258
--- /dev/null
+++ b/core/jni/com_android_internal_util_ArrayUtils.cpp
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "ArrayUtils"
+
+#include <android-base/logging.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <string.h>
+#include <unistd.h>
+#include <utils/Log.h>
+
+namespace android {
+
+static size_t GetCacheLineSize() {
+    long size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE);
+    if (size <= 0) {
+        ALOGE("Unable to determine L1 data cache line size. Assuming 32 bytes");
+        return 32;
+    }
+    // The cache line size should always be a power of 2.
+    CHECK((size & (size - 1)) == 0);
+
+    return size;
+}
+
+static void CleanCacheLineContainingAddress(const uint8_t* p) {
+#if defined(__aarch64__)
+    // 'dc cvac' stands for "Data Cache line Clean by Virtual Address to point-of-Coherency".
+    // It writes the cache line back to the "point-of-coherency", i.e. main memory.
+    asm volatile("dc cvac, %0" ::"r"(p));
+#elif defined(__i386__) || defined(__x86_64__)
+    asm volatile("clflush (%0)" ::"r"(p));
+#elif defined(__riscv)
+    // This should eventually work, but it is not ready to be enabled yet:
+    //  1.) The Android emulator needs to add support for zicbom.
+    //  2.) Kernel needs to enable zicbom in usermode.
+    //  3.) Android clang needs to add zicbom to the target.
+    // asm volatile("cbo.clean (%0)" ::"r"(p));
+#elif defined(__arm__)
+    // arm32 has a cacheflush() syscall, but it is undocumented and only flushes the icache.
+    // It is not the same as cacheflush(2) as documented in the Linux man-pages project.
+#else
+#error "Unknown architecture"
+#endif
+}
+
+static void CleanDataCache(const uint8_t* p, size_t buffer_size, size_t cache_line_size) {
+    // Clean the first line that overlaps the buffer.
+    CleanCacheLineContainingAddress(p);
+    // Clean any additional lines that overlap the buffer.  Use cache-line-aligned addresses to
+    // ensure that (a) the last cache line gets flushed, and (b) no cache line is flushed twice.
+    for (size_t i = cache_line_size - ((uintptr_t)p & (cache_line_size - 1)); i < buffer_size;
+         i += cache_line_size) {
+        CleanCacheLineContainingAddress(p + i);
+    }
+}
+
+static void ZeroizePrimitiveArray(JNIEnv* env, jclass clazz, jarray array, size_t component_len) {
+    static const size_t cache_line_size = GetCacheLineSize();
+
+    if (array == nullptr) {
+        return;
+    }
+
+    size_t buffer_size = env->GetArrayLength(array) * component_len;
+    if (buffer_size == 0) {
+        return;
+    }
+
+    // ART guarantees that GetPrimitiveArrayCritical never copies.
+    jboolean isCopy;
+    void* elems = env->GetPrimitiveArrayCritical(array, &isCopy);
+    CHECK(!isCopy);
+
+#ifdef __BIONIC__
+    memset_explicit(elems, 0, buffer_size);
+#else
+    memset(elems, 0, buffer_size);
+#endif
+    // Clean the data cache so that the data gets zeroized in main memory right away.  Without this,
+    // it might not be written to main memory until the cache line happens to be evicted.
+    CleanDataCache(static_cast<const uint8_t*>(elems), buffer_size, cache_line_size);
+
+    env->ReleasePrimitiveArrayCritical(array, elems, /* mode= */ 0);
+}
+
+static void ZeroizeByteArray(JNIEnv* env, jclass clazz, jbyteArray array) {
+    ZeroizePrimitiveArray(env, clazz, array, sizeof(jbyte));
+}
+
+static void ZeroizeCharArray(JNIEnv* env, jclass clazz, jcharArray array) {
+    ZeroizePrimitiveArray(env, clazz, array, sizeof(jchar));
+}
+
+static const JNINativeMethod sMethods[] = {
+        {"zeroize", "([B)V", (void*)ZeroizeByteArray},
+        {"zeroize", "([C)V", (void*)ZeroizeCharArray},
+};
+
+int register_com_android_internal_util_ArrayUtils(JNIEnv* env) {
+    return jniRegisterNativeMethods(env, "com/android/internal/util/ArrayUtils", sMethods,
+                                    NELEM(sMethods));
+}
+
+} // namespace android
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index b1c48ab..4b0b98c 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -510,14 +510,25 @@
 }
 
 test_module_config {
-    name: "FrameworksCoreTests_internal_os_binder",
+    name: "FrameworksCoreTests_all_binder",
     base: "FrameworksCoreTests",
     test_suites: [
         "automotive-tests",
         "device-tests",
         "device-platinum-tests",
     ],
-    include_filters: ["com.android.internal.os.BinderDeathDispatcherTest"],
+    include_filters: [
+        "android.os.BinderProxyTest",
+        "android.os.BinderDeathRecipientTest",
+        "android.os.BinderFrozenStateChangeNotificationTest",
+        "android.os.BinderProxyCountingTest",
+        "android.os.BinderUncaughtExceptionHandlerTest",
+        "android.os.BinderThreadPriorityTest",
+        "android.os.BinderWorkSourceTest",
+        "android.os.ParcelNullabilityTest",
+        "android.os.ParcelTest",
+        "com.android.internal.os.BinderDeathDispatcherTest",
+    ],
     exclude_annotations: ["com.android.internal.os.SkipPresubmit"],
 }
 
diff --git a/core/tests/coretests/src/android/os/BinderProxyTest.java b/core/tests/coretests/src/android/os/BinderProxyTest.java
index a903ed9..335791c 100644
--- a/core/tests/coretests/src/android/os/BinderProxyTest.java
+++ b/core/tests/coretests/src/android/os/BinderProxyTest.java
@@ -22,6 +22,7 @@
 import static org.junit.Assert.fail;
 
 import android.annotation.Nullable;
+import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -42,7 +43,7 @@
 import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = PowerManager.class)
+@IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
 public class BinderProxyTest {
     private static class CountingListener implements Binder.ProxyTransactListener {
         int mStartedCount;
@@ -62,7 +63,7 @@
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
 
     private Context mContext;
-    private PowerManager mPowerManager;
+    private ActivityManager mActivityManager;
 
     /**
      * Setup any common data for the upcoming tests.
@@ -70,7 +71,7 @@
     @Before
     public void setUp() throws Exception {
         mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
-        mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
     }
 
     @Test
@@ -80,7 +81,7 @@
         Binder.setProxyTransactListener(listener);
         Binder.setProxyTransactListener(null);
 
-        mPowerManager.isInteractive();
+        mActivityManager.isUserRunning(7); // something which does a binder call
 
         assertEquals(0, listener.mStartedCount);
         assertEquals(0, listener.mEndedCount);
@@ -92,7 +93,7 @@
         CountingListener listener = new CountingListener();
         Binder.setProxyTransactListener(listener);
 
-        mPowerManager.isInteractive();
+        mActivityManager.isUserRunning(27); // something which does a binder call
 
         assertEquals(1, listener.mStartedCount);
         assertEquals(1, listener.mEndedCount);
@@ -112,7 +113,7 @@
         });
 
         // Check it does not throw..
-        mPowerManager.isInteractive();
+        mActivityManager.isUserRunning(47); // something which does a binder call
     }
 
     private IBinder mRemoteBinder = null;
diff --git a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
index 4172bff..9a679d8 100644
--- a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
+++ b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
@@ -31,6 +31,8 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
+import com.android.internal.os.SkipPresubmit;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -131,6 +133,7 @@
     }
 
     @Test
+    @SkipPresubmit("b/381950874: bitrot and failed")
     public void testPassPriorityToService() throws Exception {
         for (int prio = 19; prio >= -20; prio--) {
             Process.setThreadPriority(prio);
@@ -146,6 +149,7 @@
     }
 
     @Test
+    @SkipPresubmit("b/381950874: bitrot and failed")
     public void testCallBackFromServiceWithPriority() throws Exception {
         for (int prio = -20; prio <= 19; prio++) {
             final int expected = prio;
diff --git a/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
index fc233fb..b28c9f7 100644
--- a/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
@@ -496,4 +496,58 @@
             // expected
         }
     }
+
+    // Note: the zeroize() tests only test the behavior that can be tested from a Java test.
+    // They do not verify that no copy of the data is left anywhere.
+
+    @Test
+    @SmallTest
+    public void testZeroizeNonMovableByteArray() {
+        final int length = 10;
+        byte[] array = ArrayUtils.newNonMovableByteArray(length);
+        assertArrayEquals(array, new byte[length]);
+        Arrays.fill(array, (byte) 0xff);
+        ArrayUtils.zeroize(array);
+        assertArrayEquals(array, new byte[length]);
+    }
+
+    @Test
+    @SmallTest
+    public void testZeroizeRegularByteArray() {
+        final int length = 10;
+        byte[] array = new byte[length];
+        assertArrayEquals(array, new byte[length]);
+        Arrays.fill(array, (byte) 0xff);
+        ArrayUtils.zeroize(array);
+        assertArrayEquals(array, new byte[length]);
+    }
+
+    @Test
+    @SmallTest
+    public void testZeroizeNonMovableCharArray() {
+        final int length = 10;
+        char[] array = ArrayUtils.newNonMovableCharArray(length);
+        assertArrayEquals(array, new char[length]);
+        Arrays.fill(array, (char) 0xff);
+        ArrayUtils.zeroize(array);
+        assertArrayEquals(array, new char[length]);
+    }
+
+    @Test
+    @SmallTest
+    public void testZeroizeRegularCharArray() {
+        final int length = 10;
+        char[] array = new char[length];
+        assertArrayEquals(array, new char[length]);
+        Arrays.fill(array, (char) 0xff);
+        ArrayUtils.zeroize(array);
+        assertArrayEquals(array, new char[length]);
+    }
+
+    @Test
+    @SmallTest
+    public void testZeroize_acceptsNull() {
+        ArrayUtils.zeroize((byte[]) null);
+        ArrayUtils.zeroize((char[]) null);
+    }
 }
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index b8bed92..a33a714 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -505,7 +505,6 @@
         <permission name="android.permission.RENOUNCE_PERMISSIONS" />
         <permission name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
         <permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" />
-        <permission name="android.permission.READ_DROPBOX_DATA" />
         <permission name="android.permission.READ_LOGS" />
         <permission name="android.permission.BRIGHTNESS_SLIDER_USAGE" />
         <permission name="android.permission.ACCESS_AMBIENT_LIGHT_STATS" />
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 073307c..d010c52 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -301,10 +301,7 @@
      *
      * @param bounds Returns the computed bounds of the path's control points.
      * @param exact This parameter is no longer used.
-     *
-     * @deprecated use computeBounds(RectF) instead
      */
-    @Deprecated
     @SuppressWarnings({"UnusedDeclaration"})
     public void computeBounds(@NonNull RectF bounds, boolean exact) {
         computeBounds(bounds);
diff --git a/keystore/java/android/security/KeyStore2HalLatest.java b/keystore/java/android/security/KeyStore2HalLatest.java
index b6e1cbb..123f1c0 100644
--- a/keystore/java/android/security/KeyStore2HalLatest.java
+++ b/keystore/java/android/security/KeyStore2HalLatest.java
@@ -23,7 +23,7 @@
 * and KeyMint (V4) are used.
 */
 class KeyStore2HalVersion {
-    public byte[] getSupplementaryAttestationInfoHelper(int tag, KeyStore2 ks)
+    public static byte[] getSupplementaryAttestationInfoHelper(int tag, KeyStore2 ks)
             throws KeyStoreException {
         return ks.handleRemoteExceptionWithRetry(
             (service) -> service.getSupplementaryAttestationInfo(tag));
diff --git a/native/android/OWNERS b/native/android/OWNERS
index f0db2ea..1fde7d2 100644
--- a/native/android/OWNERS
+++ b/native/android/OWNERS
@@ -2,7 +2,7 @@
 
 # General NDK API reviewers
 per-file libandroid.map.txt = [email protected], [email protected], [email protected]
-per-file libandroid.map.txt = [email protected], [email protected]
+per-file libandroid.map.txt = [email protected], [email protected], [email protected]
 
 # Networking
 per-file libandroid_net.map.txt, net.c = set noparent
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index 3ed9b76..e97b15d 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -124,6 +124,7 @@
 
   @FlaggedApi("android.nfc.nfc_oem_extension") public abstract class NfcRoutingTableEntry {
     method public int getNfceeId();
+    method public int getRouteType();
     method public int getType();
     field public static final int TYPE_AID = 0; // 0x0
     field public static final int TYPE_PROTOCOL = 1; // 0x1
diff --git a/nfc/java/android/nfc/Entry.java b/nfc/java/android/nfc/Entry.java
index 49d0f10..aa5ba58 100644
--- a/nfc/java/android/nfc/Entry.java
+++ b/nfc/java/android/nfc/Entry.java
@@ -25,11 +25,13 @@
     private final byte mType;
     private final byte mNfceeId;
     private final String mEntry;
+    private final String mRoutingType;
 
-    public Entry(String entry, byte type, byte nfceeId) {
+    public Entry(String entry, byte type, byte nfceeId, String routingType) {
         mEntry = entry;
         mType = type;
         mNfceeId = nfceeId;
+        mRoutingType = routingType;
     }
 
     public byte getType() {
@@ -44,6 +46,10 @@
         return mEntry;
     }
 
+    public String getRoutingType() {
+        return mRoutingType;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -53,6 +59,7 @@
         this.mEntry = in.readString();
         this.mNfceeId = in.readByte();
         this.mType = in.readByte();
+        this.mRoutingType = in.readString();
     }
 
     public static final @NonNull Parcelable.Creator<Entry> CREATOR =
@@ -73,5 +80,6 @@
         dest.writeString(mEntry);
         dest.writeByte(mNfceeId);
         dest.writeByte(mType);
+        dest.writeString(mRoutingType);
     }
 }
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index f78161e..fb11875 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -887,18 +887,22 @@
             switch (entry.getType()) {
                 case TYPE_TECHNOLOGY -> result.add(
                         new RoutingTableTechnologyEntry(entry.getNfceeId(),
-                                RoutingTableTechnologyEntry.techStringToInt(entry.getEntry()))
+                                RoutingTableTechnologyEntry.techStringToInt(entry.getEntry()),
+                                routeStringToInt(entry.getRoutingType()))
                 );
                 case TYPE_PROTOCOL -> result.add(
                         new RoutingTableProtocolEntry(entry.getNfceeId(),
-                                RoutingTableProtocolEntry.protocolStringToInt(entry.getEntry()))
+                                RoutingTableProtocolEntry.protocolStringToInt(entry.getEntry()),
+                                routeStringToInt(entry.getRoutingType()))
                 );
                 case TYPE_AID -> result.add(
-                        new RoutingTableAidEntry(entry.getNfceeId(), entry.getEntry())
+                        new RoutingTableAidEntry(entry.getNfceeId(), entry.getEntry(),
+                                routeStringToInt(entry.getRoutingType()))
                 );
                 case TYPE_SYSTEMCODE -> result.add(
                         new RoutingTableSystemCodeEntry(entry.getNfceeId(),
-                                entry.getEntry().getBytes(StandardCharsets.UTF_8))
+                                entry.getEntry().getBytes(StandardCharsets.UTF_8),
+                                routeStringToInt(entry.getRoutingType()))
                 );
             }
         }
diff --git a/nfc/java/android/nfc/NfcRoutingTableEntry.java b/nfc/java/android/nfc/NfcRoutingTableEntry.java
index c2cbbed..4153779 100644
--- a/nfc/java/android/nfc/NfcRoutingTableEntry.java
+++ b/nfc/java/android/nfc/NfcRoutingTableEntry.java
@@ -19,6 +19,7 @@
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.SystemApi;
+import android.nfc.cardemulation.CardEmulation;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -35,6 +36,7 @@
 public abstract class NfcRoutingTableEntry {
     private final int mNfceeId;
     private final int mType;
+    private final int mRouteType;
 
     /**
      * AID routing table type.
@@ -67,9 +69,11 @@
     public @interface RoutingTableType {}
 
     /** @hide */
-    protected NfcRoutingTableEntry(int nfceeId, @RoutingTableType int type) {
+    protected NfcRoutingTableEntry(int nfceeId, @RoutingTableType int type,
+            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
         mNfceeId = nfceeId;
         mType = type;
+        mRouteType = routeType;
     }
 
     /**
@@ -88,4 +92,14 @@
     public int getType() {
         return mType;
     }
+
+    /**
+     * Get the route type of this entry.
+     * @return an integer defined in
+     * {@link android.nfc.cardemulation.CardEmulation.ProtocolAndTechnologyRoute}
+     */
+    @CardEmulation.ProtocolAndTechnologyRoute
+    public int getRouteType() {
+        return mRouteType;
+    }
 }
diff --git a/nfc/java/android/nfc/RoutingTableAidEntry.java b/nfc/java/android/nfc/RoutingTableAidEntry.java
index bf697d6..be94f9f 100644
--- a/nfc/java/android/nfc/RoutingTableAidEntry.java
+++ b/nfc/java/android/nfc/RoutingTableAidEntry.java
@@ -18,6 +18,7 @@
 import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.nfc.cardemulation.CardEmulation;
 
 /**
  * Represents an Application ID (AID) entry in current routing table.
@@ -29,8 +30,9 @@
     private final String mValue;
 
     /** @hide */
-    public RoutingTableAidEntry(int nfceeId, String value) {
-        super(nfceeId, TYPE_AID);
+    public RoutingTableAidEntry(int nfceeId, String value,
+            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
+        super(nfceeId, TYPE_AID, routeType);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableProtocolEntry.java b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
index 536de4d..a68d8c1 100644
--- a/nfc/java/android/nfc/RoutingTableProtocolEntry.java
+++ b/nfc/java/android/nfc/RoutingTableProtocolEntry.java
@@ -18,6 +18,7 @@
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.SystemApi;
+import android.nfc.cardemulation.CardEmulation;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -96,8 +97,9 @@
     private final @ProtocolValue int mValue;
 
     /** @hide */
-    public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value) {
-        super(nfceeId, TYPE_PROTOCOL);
+    public RoutingTableProtocolEntry(int nfceeId, @ProtocolValue int value,
+            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
+        super(nfceeId, TYPE_PROTOCOL, routeType);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
index f61892d..06cc0a5 100644
--- a/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
+++ b/nfc/java/android/nfc/RoutingTableSystemCodeEntry.java
@@ -18,6 +18,7 @@
 import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
+import android.nfc.cardemulation.CardEmulation;
 
 /**
  * Represents a system code entry in current routing table, where system codes are two-byte values
@@ -31,8 +32,9 @@
     private final byte[] mValue;
 
     /** @hide */
-    public RoutingTableSystemCodeEntry(int nfceeId, byte[] value) {
-        super(nfceeId, TYPE_SYSTEM_CODE);
+    public RoutingTableSystemCodeEntry(int nfceeId, byte[] value,
+            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
+        super(nfceeId, TYPE_SYSTEM_CODE, routeType);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
index 2dbc942..86239ce7 100644
--- a/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
+++ b/nfc/java/android/nfc/RoutingTableTechnologyEntry.java
@@ -18,6 +18,7 @@
 import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.SystemApi;
+import android.nfc.cardemulation.CardEmulation;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -77,8 +78,9 @@
     private final @TechnologyValue int mValue;
 
     /** @hide */
-    public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value) {
-        super(nfceeId, TYPE_TECHNOLOGY);
+    public RoutingTableTechnologyEntry(int nfceeId, @TechnologyValue int value,
+            @CardEmulation.ProtocolAndTechnologyRoute int routeType) {
+        super(nfceeId, TYPE_TECHNOLOGY, routeType);
         this.mValue = value;
     }
 
diff --git a/nfc/java/android/nfc/cardemulation/HostApduService.java b/nfc/java/android/nfc/cardemulation/HostApduService.java
index 4f601f0..db1f6a2 100644
--- a/nfc/java/android/nfc/cardemulation/HostApduService.java
+++ b/nfc/java/android/nfc/cardemulation/HostApduService.java
@@ -107,7 +107,7 @@
  *     &lt;intent-filter&gt;
  *         &lt;action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/&gt;
  *     &lt;/intent-filter&gt;
- *     &lt;meta-data android:name="android.nfc.cardemulation.host_apdu_ervice" android:resource="@xml/apduservice"/&gt;
+ *     &lt;meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/apduservice"/&gt;
  * &lt;/service&gt;</pre>
  *
  * This meta-data tag points to an apduservice.xml file.
diff --git a/nfc/java/android/nfc/cardemulation/OffHostApduService.java b/nfc/java/android/nfc/cardemulation/OffHostApduService.java
index 2286e84..8d8a172 100644
--- a/nfc/java/android/nfc/cardemulation/OffHostApduService.java
+++ b/nfc/java/android/nfc/cardemulation/OffHostApduService.java
@@ -96,7 +96,7 @@
  *     &lt;intent-filter&gt;
  *         &lt;action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/&gt;
  *     &lt;/intent-filter&gt;
- *     &lt;meta-data android:name="android.nfc.cardemulation.off_host_apdu_ervice" android:resource="@xml/apduservice"/&gt;
+ *     &lt;meta-data android:name="android.nfc.cardemulation.off_host_apdu_service" android:resource="@xml/apduservice"/&gt;
  * &lt;/service&gt;</pre>
  *
  * This meta-data tag points to an apduservice.xml file.
diff --git a/nfc/tests/src/android/nfc/NdefRecordTest.java b/nfc/tests/src/android/nfc/NdefRecordTest.java
new file mode 100644
index 0000000..044c674
--- /dev/null
+++ b/nfc/tests/src/android/nfc/NdefRecordTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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 static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Locale;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NdefRecordTest {
+
+    @Test
+    public void testNdefRecordConstructor() throws FormatException {
+        NdefRecord applicationRecord = NdefRecord
+                .createApplicationRecord("com.android.test");
+        NdefRecord ndefRecord = new NdefRecord(applicationRecord.toByteArray());
+        assertThat(ndefRecord).isNotNull();
+        assertThat(ndefRecord.toByteArray().length).isGreaterThan(0);
+        assertThat(ndefRecord.getType()).isEqualTo("android.com:pkg".getBytes());
+        assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes());
+    }
+
+    @Test
+    public void testCreateExternal() {
+        NdefRecord ndefRecord = NdefRecord.createExternal("test",
+                "android.com:pkg", "com.android.test".getBytes());
+        assertThat(ndefRecord).isNotNull();
+        assertThat(ndefRecord.getType()).isEqualTo("test:android.com:pkg".getBytes());
+        assertThat(ndefRecord.getPayload()).isEqualTo("com.android.test".getBytes());
+    }
+
+    @Test
+    public void testCreateUri() {
+        NdefRecord ndefRecord = NdefRecord.createUri("http://www.example.com");
+        assertThat(ndefRecord).isNotNull();
+        assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_WELL_KNOWN);
+        assertThat(ndefRecord.getType()).isEqualTo(NdefRecord.RTD_URI);
+    }
+
+    @Test
+    public void testCreateMime() {
+        NdefRecord ndefRecord = NdefRecord.createMime("text/plain", "example".getBytes());
+        assertThat(ndefRecord).isNotNull();
+        assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_MIME_MEDIA);
+    }
+
+    @Test
+    public void testCreateTextRecord() {
+        String languageCode = Locale.getDefault().getLanguage();
+        NdefRecord ndefRecord = NdefRecord.createTextRecord(languageCode, "testdata");
+        assertThat(ndefRecord).isNotNull();
+        assertThat(ndefRecord.getTnf()).isEqualTo(NdefRecord.TNF_WELL_KNOWN);
+        assertThat(ndefRecord.getType()).isEqualTo(NdefRecord.RTD_TEXT);
+    }
+
+}
diff --git a/omapi/aidl/Android.bp b/omapi/aidl/Android.bp
index e71597a..3916bf3 100644
--- a/omapi/aidl/Android.bp
+++ b/omapi/aidl/Android.bp
@@ -24,6 +24,7 @@
     backend: {
         java: {
             sdk_version: "module_current",
+            min_sdk_version: "35", // Make it 36 once available.
             apex_available: [
                 "//apex_available:platform",
                 "com.android.nfcservices",
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index fc7802c..68b66df 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -178,11 +178,6 @@
     private static final String APEX_DIR = "/apex";
     private static final String APEX_ACONFIG_PATH_SUFFIX = "/etc/aconfig_flags.pb";
 
-    private static final String STORAGE_MIGRATION_FLAG =
-            "core_experiments_team_internal/com.android.providers.settings.storage_test_mission_1";
-    private static final String STORAGE_MIGRATION_MARKER_FILE =
-            "/metadata/aconfig_test_missions/mission_1";
-
     /**
      * This tag is applied to all aconfig default value-loaded flags.
      */
@@ -1740,32 +1735,6 @@
                     }
                 }
 
-                if (isConfigSettingsKey(mKey) && name != null
-                        && name.equals(STORAGE_MIGRATION_FLAG)) {
-                    if (value.equals("true")) {
-                        Path path = Paths.get(STORAGE_MIGRATION_MARKER_FILE);
-                        if (!Files.exists(path)) {
-                            Files.createFile(path);
-                        }
-
-                        Set<PosixFilePermission> perms =
-                                Files.readAttributes(path, PosixFileAttributes.class).permissions();
-                        perms.add(PosixFilePermission.OWNER_WRITE);
-                        perms.add(PosixFilePermission.OWNER_READ);
-                        perms.add(PosixFilePermission.GROUP_READ);
-                        perms.add(PosixFilePermission.OTHERS_READ);
-                        try {
-                            Files.setPosixFilePermissions(path, perms);
-                        } catch (Exception e) {
-                            Slog.e(LOG_TAG, "failed to set permissions on migration marker", e);
-                        }
-                    } else {
-                        java.nio.file.Path path = Paths.get(STORAGE_MIGRATION_MARKER_FILE);
-                        if (Files.exists(path)) {
-                            Files.delete(path);
-                        }
-                    }
-                }
                 mSettings.put(name, new Setting(name, value, defaultValue, packageName, tag,
                         fromSystem, id, isPreservedInRestore));
 
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 676ff97..acff449 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -65,7 +65,6 @@
     <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
     <uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
     <uses-permission android:name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" />
-    <uses-permission android:name="android.permission.READ_DROPBOX_DATA" />
     <uses-permission android:name="android.permission.READ_LOGS" />
     <uses-permission android:name="android.permission.BRIGHTNESS_SLIDER_USAGE" />
     <uses-permission android:name="android.permission.ACCESS_AMBIENT_LIGHT_STATS" />
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 7f5839d4..057fb68 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1873,7 +1873,9 @@
                     if (posture == DEVICE_POSTURE_OPENED) {
                         mLogger.d("Posture changed to open - attempting to request active"
                                 + " unlock and run face auth");
-                        getFaceAuthInteractor().onDeviceUnfolded();
+                        if (getFaceAuthInteractor() != null) {
+                            getFaceAuthInteractor().onDeviceUnfolded();
+                        }
                         requestActiveUnlockFromWakeReason(PowerManager.WAKE_REASON_UNFOLD_DEVICE,
                                 false);
                     }
diff --git a/packages/Vcn/TEST_MAPPING b/packages/Vcn/TEST_MAPPING
index bde88fe..9722a83 100644
--- a/packages/Vcn/TEST_MAPPING
+++ b/packages/Vcn/TEST_MAPPING
@@ -1,4 +1,12 @@
 {
+  "presubmit": [
+    {
+      "name": "FrameworksVcnTests"
+    },
+    {
+      "name": "CtsVcnTestCases"
+    }
+  ],
   "postsubmit": [
     {
       "name": "FrameworksVcnTests"
diff --git a/packages/Vcn/flags/Android.bp b/packages/Vcn/flags/Android.bp
new file mode 100644
index 0000000..3943c6f
--- /dev/null
+++ b/packages/Vcn/flags/Android.bp
@@ -0,0 +1,38 @@
+//
+// 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 {
+    default_team: "trendy_team_enigma",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aconfig_declarations {
+    name: "android.net.vcn.flags-aconfig",
+    package: "android.net.vcn",
+    container: "com.android.tethering",
+    exportable: true,
+    srcs: [
+        "flags.aconfig",
+    ],
+}
+
+java_aconfig_library {
+    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"],
+}
diff --git a/core/java/android/net/vcn/flags.aconfig b/packages/Vcn/flags/flags.aconfig
similarity index 100%
rename from core/java/android/net/vcn/flags.aconfig
rename to packages/Vcn/flags/flags.aconfig
diff --git a/packages/Vcn/framework-b/Android.bp b/packages/Vcn/framework-b/Android.bp
index 8b010c7..c312116 100644
--- a/packages/Vcn/framework-b/Android.bp
+++ b/packages/Vcn/framework-b/Android.bp
@@ -19,6 +19,18 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+filegroup {
+    name: "vcn-utils-platform-sources",
+    srcs: [
+        "src/android/net/vcn/persistablebundleutils/**/*.java",
+        "src/android/net/vcn/util/**/*.java",
+    ],
+    path: "src",
+    visibility: [
+        "//frameworks/base", // For VpnProfile.java and Vpn.java
+    ],
+}
+
 java_defaults {
     name: "framework-connectivity-b-defaults",
     sdk_version: "module_current",
@@ -27,7 +39,25 @@
 
     srcs: [
         "src/**/*.java",
+        "src/**/*.aidl",
     ],
+
+    libs: [
+        "android.net.ipsec.ike.stubs.module_lib",
+        "app-compat-annotations",
+        "framework-wifi.stubs.module_lib",
+        "unsupportedappusage",
+    ],
+    static_libs: [
+        //TODO:375213246 Use a non-exported flag lib when VCN is in mainline
+        "android.net.vcn.flags-aconfig-java-export",
+    ],
+    aidl: {
+        include_dirs: [
+            // For connectivity-framework classes such as Network.aidl, NetworkCapabilities.aidl
+            "packages/modules/Connectivity/framework/aidl-export",
+        ],
+    },
 }
 
 java_sdk_library {
@@ -36,8 +66,35 @@
         "framework-connectivity-b-defaults",
     ],
 
+    //TODO: b/375213246 Use "framework-connectivity-jarjar-rules" when VCN is
+    // in mainline
+    jarjar_rules: "framework-vcn-jarjar-rules.txt",
+
     permitted_packages: [
+        "android.net",
         "android.net.vcn",
+        "com.android.server.vcn.util",
+
+    ],
+    api_packages: [
+        "android.net",
+        "android.net.vcn",
+    ],
+
+    // Allow VCN APIs to reference APIs in IKE and Connectivity
+    stub_only_libs: [
+        "android.net.ipsec.ike.stubs.module_lib",
+        "framework-connectivity.stubs.module_lib",
+    ],
+
+    // To use non-jarjard names of utilities such as android.util.IndentingPrintWriter
+    impl_only_libs: [
+        "framework-connectivity-pre-jarjar",
+    ],
+
+    aconfig_declarations: [
+        //TODO:375213246 Use a non-exported flag lib when VCN is in mainline
+        "android.net.vcn.flags-aconfig-java-export",
     ],
 
     impl_library_visibility: [
@@ -63,5 +120,18 @@
         "//packages/modules/Wifi/service/tests/wifitests",
     ],
 
-    // TODO: b/375213246 Expose this library to Tethering module
+    apex_available: [
+        // TODO: b/374174952 Remove it when VCN modularization is released
+        "//apex_available:platform",
+
+        "com.android.tethering",
+    ],
+}
+
+java_library {
+    name: "framework-connectivity-b-pre-jarjar",
+    defaults: ["framework-connectivity-b-defaults"],
+    libs: [
+        "framework-connectivity-pre-jarjar",
+    ],
 }
diff --git a/packages/Vcn/framework-b/api/current.txt b/packages/Vcn/framework-b/api/current.txt
index d802177..831b741 100644
--- a/packages/Vcn/framework-b/api/current.txt
+++ b/packages/Vcn/framework-b/api/current.txt
@@ -1 +1,123 @@
 // Signature format: 2.0
+package android.net.vcn {
+
+  public final class VcnCellUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate {
+    method public int getCbs();
+    method public int getDun();
+    method public int getIms();
+    method public int getInternet();
+    method public int getMms();
+    method @NonNull public java.util.Set<java.lang.String> getOperatorPlmnIds();
+    method public int getOpportunistic();
+    method public int getRcs();
+    method public int getRoaming();
+    method @NonNull public java.util.Set<java.lang.Integer> getSimSpecificCarrierIds();
+  }
+
+  public static final class VcnCellUnderlyingNetworkTemplate.Builder {
+    ctor public VcnCellUnderlyingNetworkTemplate.Builder();
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate build();
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setCbs(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setDun(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setIms(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setInternet(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMetered(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setMms(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOperatorPlmnIds(@NonNull java.util.Set<java.lang.String>);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setOpportunistic(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRcs(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setRoaming(int);
+    method @NonNull public android.net.vcn.VcnCellUnderlyingNetworkTemplate.Builder setSimSpecificCarrierIds(@NonNull java.util.Set<java.lang.Integer>);
+  }
+
+  public final class VcnConfig implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public java.util.Set<android.net.vcn.VcnGatewayConnectionConfig> getGatewayConnectionConfigs();
+    method @NonNull public java.util.Set<java.lang.Integer> getRestrictedUnderlyingNetworkTransports();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnConfig> CREATOR;
+  }
+
+  public static final class VcnConfig.Builder {
+    ctor public VcnConfig.Builder(@NonNull android.content.Context);
+    method @NonNull public android.net.vcn.VcnConfig.Builder addGatewayConnectionConfig(@NonNull android.net.vcn.VcnGatewayConnectionConfig);
+    method @NonNull public android.net.vcn.VcnConfig build();
+    method @NonNull public android.net.vcn.VcnConfig.Builder setRestrictedUnderlyingNetworkTransports(@NonNull java.util.Set<java.lang.Integer>);
+  }
+
+  public final class VcnGatewayConnectionConfig {
+    method @NonNull public int[] getExposedCapabilities();
+    method @NonNull public String getGatewayConnectionName();
+    method @IntRange(from=0x500) public int getMaxMtu();
+    method public int getMinUdpPort4500NatTimeoutSeconds();
+    method @NonNull public long[] getRetryIntervalsMillis();
+    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
+  }
+
+  public static final class VcnGatewayConnectionConfig.Builder {
+    ctor public VcnGatewayConnectionConfig.Builder(@NonNull String, @NonNull android.net.ipsec.ike.IkeTunnelConnectionParams);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addGatewayOption(int);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build();
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeGatewayOption(int);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]);
+    method @FlaggedApi("android.net.vcn.safe_mode_config") @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setSafeModeEnabled(boolean);
+    method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate>);
+  }
+
+  public class VcnManager {
+    method @RequiresPermission("carrier privileges") public void clearVcnConfig(@NonNull android.os.ParcelUuid) throws java.io.IOException;
+    method @NonNull public java.util.List<android.os.ParcelUuid> getConfiguredSubscriptionGroups();
+    method public void registerVcnStatusCallback(@NonNull android.os.ParcelUuid, @NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnStatusCallback);
+    method @RequiresPermission("carrier privileges") public void setVcnConfig(@NonNull android.os.ParcelUuid, @NonNull android.net.vcn.VcnConfig) throws java.io.IOException;
+    method public void unregisterVcnStatusCallback(@NonNull android.net.vcn.VcnManager.VcnStatusCallback);
+    field public static final int VCN_ERROR_CODE_CONFIG_ERROR = 1; // 0x1
+    field public static final int VCN_ERROR_CODE_INTERNAL_ERROR = 0; // 0x0
+    field public static final int VCN_ERROR_CODE_NETWORK_ERROR = 2; // 0x2
+    field public static final int VCN_STATUS_CODE_ACTIVE = 2; // 0x2
+    field public static final int VCN_STATUS_CODE_INACTIVE = 1; // 0x1
+    field public static final int VCN_STATUS_CODE_NOT_CONFIGURED = 0; // 0x0
+    field public static final int VCN_STATUS_CODE_SAFE_MODE = 3; // 0x3
+  }
+
+  public abstract static class VcnManager.VcnStatusCallback {
+    ctor public VcnManager.VcnStatusCallback();
+    method public abstract void onGatewayConnectionError(@NonNull String, int, @Nullable Throwable);
+    method public abstract void onStatusChanged(int);
+  }
+
+  public abstract class VcnUnderlyingNetworkTemplate {
+    method public int getMetered();
+    method public int getMinEntryDownstreamBandwidthKbps();
+    method public int getMinEntryUpstreamBandwidthKbps();
+    method public int getMinExitDownstreamBandwidthKbps();
+    method public int getMinExitUpstreamBandwidthKbps();
+    field public static final int MATCH_ANY = 0; // 0x0
+    field public static final int MATCH_FORBIDDEN = 2; // 0x2
+    field public static final int MATCH_REQUIRED = 1; // 0x1
+  }
+
+  public final class VcnWifiUnderlyingNetworkTemplate extends android.net.vcn.VcnUnderlyingNetworkTemplate {
+    method @NonNull public java.util.Set<java.lang.String> getSsids();
+  }
+
+  public static final class VcnWifiUnderlyingNetworkTemplate.Builder {
+    ctor public VcnWifiUnderlyingNetworkTemplate.Builder();
+    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate build();
+    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMetered(int);
+    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinDownstreamBandwidthKbps(int, int);
+    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setMinUpstreamBandwidthKbps(int, int);
+    method @NonNull public android.net.vcn.VcnWifiUnderlyingNetworkTemplate.Builder setSsids(@NonNull java.util.Set<java.lang.String>);
+  }
+
+}
+
diff --git a/packages/Vcn/framework-b/api/module-lib-current.txt b/packages/Vcn/framework-b/api/module-lib-current.txt
index d802177..8961b28 100644
--- a/packages/Vcn/framework-b/api/module-lib-current.txt
+++ b/packages/Vcn/framework-b/api/module-lib-current.txt
@@ -1 +1,28 @@
 // Signature format: 2.0
+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();
+  }
+
+}
+
+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);
+  }
+
+}
+
diff --git a/packages/Vcn/framework-b/api/system-current.txt b/packages/Vcn/framework-b/api/system-current.txt
index d802177..9c5a677 100644
--- a/packages/Vcn/framework-b/api/system-current.txt
+++ b/packages/Vcn/framework-b/api/system-current.txt
@@ -1 +1,23 @@
 // Signature format: 2.0
+package android.net.vcn {
+
+  public class VcnManager {
+    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyChangeListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void removeVcnNetworkPolicyChangeListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener);
+  }
+
+  public static interface VcnManager.VcnNetworkPolicyChangeListener {
+    method public void onPolicyChanged();
+  }
+
+  public final class VcnNetworkPolicyResult implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
+    method public boolean isTeardownRequested();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.vcn.VcnNetworkPolicyResult> CREATOR;
+  }
+
+}
+
diff --git a/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt
new file mode 100644
index 0000000..757043b
--- /dev/null
+++ b/packages/Vcn/framework-b/framework-vcn-jarjar-rules.txt
@@ -0,0 +1,2 @@
+rule android.net.vcn.persistablebundleutils.** android.net.vcn.module.repackaged.persistablebundleutils.@1
+rule android.net.vcn.util.** android.net.vcn.module.repackaged.util.@1
\ No newline at end of file
diff --git a/core/java/android/net/ConnectivityFrameworkInitializerBaklava.java b/packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java
similarity index 100%
rename from core/java/android/net/ConnectivityFrameworkInitializerBaklava.java
rename to packages/Vcn/framework-b/src/android/net/ConnectivityFrameworkInitializerBaklava.java
diff --git a/core/java/android/net/vcn/IVcnManagementService.aidl b/packages/Vcn/framework-b/src/android/net/vcn/IVcnManagementService.aidl
similarity index 100%
rename from core/java/android/net/vcn/IVcnManagementService.aidl
rename to packages/Vcn/framework-b/src/android/net/vcn/IVcnManagementService.aidl
diff --git a/core/java/android/net/vcn/IVcnStatusCallback.aidl b/packages/Vcn/framework-b/src/android/net/vcn/IVcnStatusCallback.aidl
similarity index 100%
rename from core/java/android/net/vcn/IVcnStatusCallback.aidl
rename to packages/Vcn/framework-b/src/android/net/vcn/IVcnStatusCallback.aidl
diff --git a/core/java/android/net/vcn/IVcnUnderlyingNetworkPolicyListener.aidl b/packages/Vcn/framework-b/src/android/net/vcn/IVcnUnderlyingNetworkPolicyListener.aidl
similarity index 100%
rename from core/java/android/net/vcn/IVcnUnderlyingNetworkPolicyListener.aidl
rename to packages/Vcn/framework-b/src/android/net/vcn/IVcnUnderlyingNetworkPolicyListener.aidl
diff --git a/core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
similarity index 100%
rename from core/java/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnCellUnderlyingNetworkTemplate.java
diff --git a/core/java/android/net/vcn/VcnConfig.aidl b/packages/Vcn/framework-b/src/android/net/vcn/VcnConfig.aidl
similarity index 100%
rename from core/java/android/net/vcn/VcnConfig.aidl
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnConfig.aidl
diff --git a/core/java/android/net/vcn/VcnConfig.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnConfig.java
similarity index 100%
rename from core/java/android/net/vcn/VcnConfig.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnConfig.java
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnGatewayConnectionConfig.java
similarity index 100%
rename from core/java/android/net/vcn/VcnGatewayConnectionConfig.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnGatewayConnectionConfig.java
diff --git a/core/java/android/net/vcn/VcnManager.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnManager.java
similarity index 98%
rename from core/java/android/net/vcn/VcnManager.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnManager.java
index f275714..594bbb8 100644
--- a/core/java/android/net/vcn/VcnManager.java
+++ b/packages/Vcn/framework-b/src/android/net/vcn/VcnManager.java
@@ -334,7 +334,7 @@
      * @param executor the Executor that will be used for invoking all calls to the specified
      *     Listener
      * @param listener the VcnUnderlyingNetworkPolicyListener to be added
-     * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
+     * @throws SecurityException if the caller does not have the required permission
      * @throws IllegalStateException if the specified VcnUnderlyingNetworkPolicyListener is already
      *     registered
      * @hide
@@ -423,7 +423,7 @@
      * @param executor the Executor that will be used for invoking all calls to the specified
      *     Listener
      * @param listener the VcnNetworkPolicyChangeListener to be added
-     * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
+     * @throws SecurityException if the caller does not have the required permission
      * @throws IllegalStateException if the specified VcnNetworkPolicyChangeListener is already
      *     registered
      * @hide
@@ -455,7 +455,7 @@
      * <p>If the specified listener is not currently registered, this is a no-op.
      *
      * @param listener the VcnNetworkPolicyChangeListener that will be removed
-     * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
+     * @throws SecurityException if the caller does not have the required permission
      * @hide
      */
     @SystemApi
@@ -489,7 +489,7 @@
      *     policy result for this Network.
      * @param linkProperties the LinkProperties to be used in determining the Network policy result
      *     for this Network.
-     * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
+     * @throws SecurityException if the caller does not have the required permission
      * @return the {@link VcnNetworkPolicyResult} to be used for this Network.
      * @hide
      */
diff --git a/core/java/android/net/vcn/VcnNetworkPolicyResult.aidl b/packages/Vcn/framework-b/src/android/net/vcn/VcnNetworkPolicyResult.aidl
similarity index 100%
rename from core/java/android/net/vcn/VcnNetworkPolicyResult.aidl
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnNetworkPolicyResult.aidl
diff --git a/core/java/android/net/vcn/VcnNetworkPolicyResult.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnNetworkPolicyResult.java
similarity index 100%
rename from core/java/android/net/vcn/VcnNetworkPolicyResult.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnNetworkPolicyResult.java
diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnTransportInfo.java
similarity index 100%
rename from core/java/android/net/vcn/VcnTransportInfo.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnTransportInfo.java
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.aidl b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkPolicy.aidl
similarity index 100%
rename from core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.aidl
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkPolicy.aidl
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkPolicy.java
similarity index 100%
rename from core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkPolicy.java
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkSpecifier.java
similarity index 100%
rename from core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkSpecifier.java
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkTemplate.java
similarity index 100%
rename from core/java/android/net/vcn/VcnUnderlyingNetworkTemplate.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnUnderlyingNetworkTemplate.java
diff --git a/core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java b/packages/Vcn/framework-b/src/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
similarity index 100%
rename from core/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
rename to packages/Vcn/framework-b/src/android/net/vcn/VcnWifiUnderlyingNetworkTemplate.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/CertUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/CertUtils.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/CertUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/CertUtils.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/ChildSaProposalUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/ChildSaProposalUtils.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/ChildSaProposalUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/ChildSaProposalUtils.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/EapSessionConfigUtils.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/EapSessionConfigUtils.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeIdentificationUtils.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeIdentificationUtils.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSaProposalUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeSaProposalUtils.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/IkeSaProposalUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeSaProposalUtils.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeSessionParamsUtils.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtils.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/SaProposalUtilsBase.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/SaProposalUtilsBase.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/SaProposalUtilsBase.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/SaProposalUtilsBase.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtils.java
diff --git a/core/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtils.java
similarity index 100%
rename from core/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtils.java
diff --git a/core/java/android/net/vcn/util/LogUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/util/LogUtils.java
similarity index 95%
rename from core/java/android/net/vcn/util/LogUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/util/LogUtils.java
index 7f7f852..742aa76 100644
--- a/core/java/android/net/vcn/util/LogUtils.java
+++ b/packages/Vcn/framework-b/src/android/net/vcn/util/LogUtils.java
@@ -19,7 +19,7 @@
 import android.annotation.Nullable;
 import android.os.ParcelUuid;
 
-import com.android.internal.util.HexDump;
+import com.android.net.module.util.HexDump;
 
 /** @hide */
 public class LogUtils {
diff --git a/core/java/android/net/vcn/util/MtuUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/util/MtuUtils.java
similarity index 100%
rename from core/java/android/net/vcn/util/MtuUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/util/MtuUtils.java
diff --git a/core/java/android/net/vcn/util/OneWayBoolean.java b/packages/Vcn/framework-b/src/android/net/vcn/util/OneWayBoolean.java
similarity index 100%
rename from core/java/android/net/vcn/util/OneWayBoolean.java
rename to packages/Vcn/framework-b/src/android/net/vcn/util/OneWayBoolean.java
diff --git a/core/java/android/net/vcn/util/PersistableBundleUtils.java b/packages/Vcn/framework-b/src/android/net/vcn/util/PersistableBundleUtils.java
similarity index 99%
rename from core/java/android/net/vcn/util/PersistableBundleUtils.java
rename to packages/Vcn/framework-b/src/android/net/vcn/util/PersistableBundleUtils.java
index 4dc42c7..8a687d8 100644
--- a/core/java/android/net/vcn/util/PersistableBundleUtils.java
+++ b/packages/Vcn/framework-b/src/android/net/vcn/util/PersistableBundleUtils.java
@@ -21,7 +21,7 @@
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
 
-import com.android.internal.util.HexDump;
+import com.android.net.module.util.HexDump;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
diff --git a/packages/Vcn/service-b/Android.bp b/packages/Vcn/service-b/Android.bp
index 03ef4e6..c1a1ee7 100644
--- a/packages/Vcn/service-b/Android.bp
+++ b/packages/Vcn/service-b/Android.bp
@@ -32,6 +32,33 @@
     visibility: ["//frameworks/base/services/core"],
 }
 
+// Do not static include this lib in VCN because these files exist in
+// both service-connectivity.jar and framework.jar
+// TODO: b/374174952 After VCN moves to Connectivity/ and the modularization is done
+// this lib can be removed and "service-connectivity-b-pre-jarjar" can include
+// "service-connectivity-pre-jarjar"
+java_library {
+    name: "connectivity-utils-service-vcn-internal",
+    sdk_version: "module_current",
+    min_sdk_version: "30",
+    srcs: [
+        ":framework-connectivity-shared-srcs",
+    ],
+    libs: [
+        "framework-annotations-lib",
+        "unsupportedappusage",
+    ],
+    visibility: [
+        "//visibility:private",
+    ],
+    apex_available: [
+        // TODO: b/374174952 Remove it when VCN modularization is released
+        "//apex_available:platform",
+
+        "com.android.tethering",
+    ],
+}
+
 java_library {
     name: "service-connectivity-b-pre-jarjar",
     sdk_version: "system_server_current",
@@ -42,8 +69,33 @@
         "src/**/*.java",
     ],
 
-    // TODO: b/375213246 Expose this library to Tethering module
+    libs: [
+        "android.net.ipsec.ike.stubs.module_lib",
+        "connectivity-utils-service-vcn-internal",
+        "framework-annotations-lib",
+        "framework-connectivity-pre-jarjar",
+        "framework-connectivity-t-pre-jarjar",
+        "framework-connectivity-b-pre-jarjar",
+        "framework-wifi.stubs.module_lib",
+        "keepanno-annotations",
+        "modules-utils-statemachine",
+        "unsupportedappusage",
+    ],
+
+    // TODO: b/374174952 Dynamically include these libs when VCN
+    // modularization is released
+    static_libs: [
+        "net-utils-service-vcn",
+        "modules-utils-handlerexecutor",
+    ],
+
     visibility: [
         "//frameworks/base/services",
     ],
+    apex_available: [
+        // TODO: b/374174952 Remove it when VCN modularization is released
+        "//apex_available:platform",
+
+        "com.android.tethering",
+    ],
 }
diff --git a/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
new file mode 100644
index 0000000..02c8ce4
--- /dev/null
+++ b/packages/Vcn/service-b/src/com/android/server/ConnectivityServiceInitializerB.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.util.Log;
+
+import com.android.tools.r8.keepanno.annotations.KeepItemKind;
+import com.android.tools.r8.keepanno.annotations.UsedByReflection;
+
+/**
+ * Service initializer for VCN. This is called by system server to create a new instance of
+ * VcnManagementService.
+ */
+// This class is reflectively invoked from SystemServer and ConnectivityServiceInitializer.
+// Without this annotation, this class will be treated as unused class and be removed during build
+// time.
+@UsedByReflection(kind = KeepItemKind.CLASS_AND_METHODS)
+public final class ConnectivityServiceInitializerB extends SystemService {
+    private static final String TAG = ConnectivityServiceInitializerB.class.getSimpleName();
+    private final VcnManagementService mVcnManagementService;
+
+    public ConnectivityServiceInitializerB(Context context) {
+        super(context);
+        mVcnManagementService = VcnManagementService.create(context);
+    }
+
+    @Override
+    public void onStart() {
+        if (mVcnManagementService != null) {
+            Log.i(TAG, "Registering " + Context.VCN_MANAGEMENT_SERVICE);
+            publishBinderService(
+                    Context.VCN_MANAGEMENT_SERVICE,
+                    mVcnManagementService,
+                    /* allowIsolated= */ false);
+        }
+    }
+
+    @Override
+    public void onBootPhase(int phase) {
+        if (mVcnManagementService != null && phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
+            Log.i(TAG, "Starting " + Context.VCN_MANAGEMENT_SERVICE);
+            mVcnManagementService.systemReady();
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java
similarity index 97%
rename from services/core/java/com/android/server/VcnManagementService.java
rename to packages/Vcn/service-b/src/com/android/server/VcnManagementService.java
index a45b715..26db6a9 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/packages/Vcn/service-b/src/com/android/server/VcnManagementService.java
@@ -86,6 +86,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
 import com.android.net.module.util.BinderUtils;
+import com.android.net.module.util.HandlerUtils;
 import com.android.net.module.util.LocationPermissionChecker;
 import com.android.net.module.util.PermissionUtils;
 import com.android.server.vcn.TelephonySubscriptionTracker;
@@ -1332,41 +1333,46 @@
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "| ");
 
         // Post to handler thread to prevent ConcurrentModificationExceptions, and avoid lock-hell.
-        mHandler.runWithScissors(() -> {
-            mNetworkProvider.dump(pw);
-            pw.println();
+        HandlerUtils.runWithScissorsForDump(
+                mHandler,
+                () -> {
+                    mNetworkProvider.dump(pw);
+                    pw.println();
 
-            mTrackingNetworkCallback.dump(pw);
-            pw.println();
+                    mTrackingNetworkCallback.dump(pw);
+                    pw.println();
 
-            synchronized (mLock) {
-                mLastSnapshot.dump(pw);
-                pw.println();
+                    synchronized (mLock) {
+                        mLastSnapshot.dump(pw);
+                        pw.println();
 
-                pw.println("mConfigs:");
-                pw.increaseIndent();
-                for (Entry<ParcelUuid, VcnConfig> entry : mConfigs.entrySet()) {
-                    pw.println(entry.getKey() + ": "
-                            + entry.getValue().getProvisioningPackageName());
-                }
-                pw.decreaseIndent();
-                pw.println();
+                        pw.println("mConfigs:");
+                        pw.increaseIndent();
+                        for (Entry<ParcelUuid, VcnConfig> entry : mConfigs.entrySet()) {
+                            pw.println(
+                                    entry.getKey()
+                                            + ": "
+                                            + entry.getValue().getProvisioningPackageName());
+                        }
+                        pw.decreaseIndent();
+                        pw.println();
 
-                pw.println("mVcns:");
-                pw.increaseIndent();
-                for (Vcn vcn : mVcns.values()) {
-                    vcn.dump(pw);
-                }
-                pw.decreaseIndent();
-                pw.println();
-            }
+                        pw.println("mVcns:");
+                        pw.increaseIndent();
+                        for (Vcn vcn : mVcns.values()) {
+                            vcn.dump(pw);
+                        }
+                        pw.decreaseIndent();
+                        pw.println();
+                    }
 
-            pw.println("Local log:");
-            pw.increaseIndent();
-            LOCAL_LOG.dump(pw);
-            pw.decreaseIndent();
-            pw.println();
-        }, DUMP_TIMEOUT_MILLIS);
+                    pw.println("Local log:");
+                    pw.increaseIndent();
+                    LOCAL_LOG.dump(pw);
+                    pw.decreaseIndent();
+                    pw.println();
+                },
+                DUMP_TIMEOUT_MILLIS);
     }
 
     // TODO(b/180452282): Make name more generic and implement directly with VcnManagementService
diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java
similarity index 99%
rename from services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java
index 154897e..b448f75 100644
--- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/TelephonySubscriptionTracker.java
@@ -29,7 +29,6 @@
 import android.net.vcn.VcnManager;
 import android.net.vcn.util.PersistableBundleUtils.PersistableBundleWrapper;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
@@ -46,6 +45,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.modules.utils.HandlerExecutor;
 
 import java.util.ArrayList;
 import java.util.Collections;
diff --git a/services/core/java/com/android/server/vcn/Vcn.java b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
similarity index 99%
rename from services/core/java/com/android/server/vcn/Vcn.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
index 95acb10..2524d0e 100644
--- a/services/core/java/com/android/server/vcn/Vcn.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/Vcn.java
@@ -40,7 +40,6 @@
 import android.net.vcn.VcnManager.VcnErrorCode;
 import android.net.vcn.util.LogUtils;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.Message;
 import android.os.ParcelUuid;
 import android.provider.Settings;
@@ -53,6 +52,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.modules.utils.HandlerExecutor;
 import com.android.server.VcnManagementService.VcnCallback;
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 
diff --git a/services/core/java/com/android/server/vcn/VcnContext.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnContext.java
similarity index 100%
rename from services/core/java/com/android/server/vcn/VcnContext.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/VcnContext.java
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java
similarity index 99%
rename from services/core/java/com/android/server/vcn/VcnGatewayConnection.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java
index 9ccf040..e50fc3a 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnGatewayConnection.java
@@ -45,6 +45,7 @@
 import android.net.IpPrefix;
 import android.net.IpSecManager;
 import android.net.IpSecManager.IpSecTunnelInterface;
+import android.net.IpSecManager.PolicyDirection;
 import android.net.IpSecManager.ResourceUnavailableException;
 import android.net.IpSecTransform;
 import android.net.LinkAddress;
@@ -59,7 +60,6 @@
 import android.net.RouteInfo;
 import android.net.TelephonyNetworkSpecifier;
 import android.net.Uri;
-import android.net.annotations.PolicyDirection;
 import android.net.ipsec.ike.ChildSaProposal;
 import android.net.ipsec.ike.ChildSessionCallback;
 import android.net.ipsec.ike.ChildSessionConfiguration;
@@ -83,7 +83,6 @@
 import android.net.vcn.util.OneWayBoolean;
 import android.net.wifi.WifiInfo;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.Message;
 import android.os.ParcelUuid;
 import android.os.PowerManager;
@@ -101,6 +100,7 @@
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
 import com.android.internal.util.WakeupMessage;
+import com.android.modules.utils.HandlerExecutor;
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
 import com.android.server.vcn.routeselection.UnderlyingNetworkController;
@@ -1228,10 +1228,7 @@
 
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     void setSafeModeAlarm() {
-        final boolean isFlagSafeModeConfigEnabled = mVcnContext.getFeatureFlags().safeModeConfig();
-        logVdbg("isFlagSafeModeConfigEnabled " + isFlagSafeModeConfigEnabled);
-
-        if (isFlagSafeModeConfigEnabled && !mConnectionConfig.isSafeModeEnabled()) {
+        if (!mConnectionConfig.isSafeModeEnabled()) {
             logVdbg("setSafeModeAlarm: safe mode disabled");
             return;
         }
diff --git a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
similarity index 99%
rename from services/core/java/com/android/server/vcn/VcnNetworkProvider.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
index 78ff432..4552f50 100644
--- a/services/core/java/com/android/server/vcn/VcnNetworkProvider.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/VcnNetworkProvider.java
@@ -33,7 +33,6 @@
 import android.net.NetworkScore;
 import android.net.vcn.VcnGatewayConnectionConfig;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.Looper;
 import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
@@ -41,6 +40,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.modules.utils.HandlerExecutor;
 
 import java.util.Objects;
 import java.util.Set;
diff --git a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
similarity index 99%
rename from services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
index e6a1ff9..72de613 100644
--- a/services/core/java/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/IpSecPacketLossDetector.java
@@ -32,12 +32,12 @@
 import android.net.Network;
 import android.net.vcn.VcnManager;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.OutcomeReceiver;
 import android.os.PowerManager;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.modules.utils.HandlerExecutor;
 import com.android.server.vcn.VcnContext;
 
 import java.lang.annotation.ElementType;
diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkMetricMonitor.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java
similarity index 100%
rename from services/core/java/com/android/server/vcn/routeselection/NetworkMetricMonitor.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkMetricMonitor.java
diff --git a/services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
similarity index 100%
rename from services/core/java/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/routeselection/NetworkPriorityClassifier.java
diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
similarity index 99%
rename from services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
index f7a564a..29a0762 100644
--- a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
+++ b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkController.java
@@ -41,7 +41,6 @@
 import android.net.vcn.VcnUnderlyingNetworkTemplate;
 import android.net.vcn.util.LogUtils;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.ParcelUuid;
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
@@ -52,6 +51,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.annotations.VisibleForTesting.Visibility;
+import com.android.modules.utils.HandlerExecutor;
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import com.android.server.vcn.VcnContext;
 import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback;
diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
similarity index 100%
rename from services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluator.java
diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java b/packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java
similarity index 100%
rename from services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java
rename to packages/Vcn/service-b/src/com/android/server/vcn/routeselection/UnderlyingNetworkRecord.java
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index 66c8d0f..59043a83 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -182,21 +182,6 @@
     visibility: [":__subpackages__"],
 }
 
-// Separated out from ravenwood-junit-impl since it needs to compile
-// against `module_current`
-java_library {
-    name: "ravenwood-junit-impl-flag",
-    srcs: [
-        "junit-flag-src/**/*.java",
-    ],
-    sdk_version: "module_current",
-    libs: [
-        "junit",
-        "flag-junit",
-    ],
-    visibility: ["//visibility:public"],
-}
-
 // Carefully compiles against only module_current to support tests that
 // want to verify they're unbundled.  The "impl" library above is what
 // ships inside the Ravenwood environment to actually drive any API
@@ -651,7 +636,6 @@
         "flag-junit",
         "ravenwood-framework",
         "ravenwood-junit-impl",
-        "ravenwood-junit-impl-flag",
         "mockito-ravenwood-prebuilt",
         "inline-mockito-ravenwood-prebuilt",
 
diff --git a/ravenwood/junit-flag-src/android/platform/test/flag/junit/RavenwoodFlagsValueProvider.java b/ravenwood/junit-flag-src/android/platform/test/flag/junit/RavenwoodFlagsValueProvider.java
deleted file mode 100644
index 9d62774..0000000
--- a/ravenwood/junit-flag-src/android/platform/test/flag/junit/RavenwoodFlagsValueProvider.java
+++ /dev/null
@@ -1,54 +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 android.platform.test.flag.junit;
-
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.IFlagsValueProvider;
-
-/**
- * Offer to create {@link CheckFlagsRule} instances that are useful on the Ravenwood deviceless
- * testing environment.
- *
- * At the moment, default flag values are not available on Ravenwood, so the only options offered
- * here are "all-on" and "all-off" options. Tests that want to exercise specific flag states should
- * use {@link android.platform.test.flag.junit.SetFlagsRule}.
- */
-public class RavenwoodFlagsValueProvider {
-    /**
-     * Create a {@link CheckFlagsRule} instance where flags are in an "all-on" state.
-     */
-    public static CheckFlagsRule createAllOnCheckFlagsRule() {
-        return new CheckFlagsRule(new IFlagsValueProvider() {
-            @Override
-            public boolean getBoolean(String flag) {
-                return true;
-            }
-        });
-    }
-
-    /**
-     * Create a {@link CheckFlagsRule} instance where flags are in an "all-off" state.
-     */
-    public static CheckFlagsRule createAllOffCheckFlagsRule() {
-        return new CheckFlagsRule(new IFlagsValueProvider() {
-            @Override
-            public boolean getBoolean(String flag) {
-                return false;
-            }
-        });
-    }
-}
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 de3c5f2..3ebef02 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -63,8 +63,6 @@
  * - Handle {@link android.platform.test.annotations.DisabledOnRavenwood}.
  */
 public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase {
-    public static final String TAG = "Ravenwood";
-
     /** Scope of a hook. */
     public enum Scope {
         Class,
@@ -131,7 +129,7 @@
 
         mTestClass = new TestClass(testClass);
 
-        Log.v(TAG, "RavenwoodAwareTestRunner starting for " + testClass.getCanonicalName());
+        Log.v(TAG, "RavenwoodAwareTestRunner initializing for " + testClass.getCanonicalName());
 
         // Hook point to allow more customization.
         runAnnotatedMethodsOnRavenwood(RavenwoodTestRunnerInitializing.class, null);
@@ -148,7 +146,9 @@
 
     private void runAnnotatedMethodsOnRavenwood(Class<? extends Annotation> annotationClass,
             Object instance) {
-        Log.v(TAG, "runAnnotatedMethodsOnRavenwood() " + annotationClass.getName());
+        if (RAVENWOOD_VERBOSE_LOGGING) {
+            Log.v(TAG, "runAnnotatedMethodsOnRavenwood() " + annotationClass.getName());
+        }
 
         for (var method : mTestClass.getAnnotatedMethods(annotationClass)) {
             ensureIsPublicVoidMethod(method.getMethod(), /* isStatic=*/ instance == null);
@@ -171,12 +171,14 @@
         RavenwoodTestStats.getInstance().attachToRunNotifier(notifier);
 
         if (mRealRunner instanceof ClassSkippingTestRunner) {
-            Log.i(TAG, "onClassSkipped: description=" + description);
+            Log.v(TAG, "onClassSkipped: description=" + description);
             mRealRunner.run(notifier);
             return;
         }
 
-        Log.v(TAG, "Starting " + mTestJavaClass.getCanonicalName());
+        if (RAVENWOOD_VERBOSE_LOGGING) {
+            Log.v(TAG, "Running " + mTestJavaClass.getCanonicalName());
+        }
         if (RAVENWOOD_VERBOSE_LOGGING) {
             dumpDescription(description);
         }
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
index 239c806..a332633 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
@@ -45,7 +45,7 @@
 import java.util.function.Supplier;
 
 public class RavenwoodContext extends RavenwoodBaseContext {
-    private static final String TAG = "Ravenwood";
+    private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG;
 
     private final Object mLock = new Object();
     private final String mPackageName;
@@ -132,36 +132,27 @@
 
     @Override
     public Looper getMainLooper() {
-        Objects.requireNonNull(mMainThread,
-                "Test must request setProvideMainThread() via RavenwoodConfig");
         return mMainThread.getLooper();
     }
 
     @Override
     public Handler getMainThreadHandler() {
-        Objects.requireNonNull(mMainThread,
-                "Test must request setProvideMainThread() via RavenwoodConfig");
         return mMainThread.getThreadHandler();
     }
 
     @Override
     public Executor getMainExecutor() {
-        Objects.requireNonNull(mMainThread,
-                "Test must request setProvideMainThread() via RavenwoodConfig");
         return mMainThread.getThreadExecutor();
     }
 
     @Override
     public String getPackageName() {
-        return Objects.requireNonNull(mPackageName,
-                "Test must request setPackageName() (or setTargetPackageName())"
-                + " via RavenwoodConfig");
+        return mPackageName;
     }
 
     @Override
     public String getOpPackageName() {
-        return Objects.requireNonNull(mPackageName,
-                "Test must request setPackageName() via RavenwoodConfig");
+        return mPackageName;
     }
 
     @Override
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java
index 77275c4..3cb2c67 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java
@@ -27,8 +27,6 @@
  * Calculates which tests need to be executed on Ravenwood.
  */
 public class RavenwoodEnablementChecker {
-    private static final String TAG = "RavenwoodDisablementChecker";
-
     private RavenwoodEnablementChecker() {
     }
 
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
index 6dfcf4ce..70bc52b 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRunnerState.java
@@ -15,6 +15,8 @@
  */
 package android.platform.test.ravenwood;
 
+import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -40,7 +42,7 @@
  * All members must be called from the runner's main thread.
  */
 public final class RavenwoodRunnerState {
-    private static final String TAG = "RavenwoodRunnerState";
+    private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG;
     private static final String RAVENWOOD_RULE_ERROR =
             "RavenwoodRule(s) are not executed in the correct order";
 
@@ -59,16 +61,22 @@
     private Description mMethodDescription;
 
     public void enterTestRunner() {
-        Log.i(TAG, "enterTestRunner: " + mRunner);
+        if (RAVENWOOD_VERBOSE_LOGGING) {
+            Log.v(TAG, "enterTestRunner: " + mRunner);
+        }
         RavenwoodRuntimeEnvironmentController.initForRunner();
     }
 
     public void enterTestClass() {
-        Log.i(TAG, "enterTestClass: " + mRunner.mTestJavaClass.getName());
+        if (RAVENWOOD_VERBOSE_LOGGING) {
+            Log.v(TAG, "enterTestClass: " + mRunner.mTestJavaClass.getName());
+        }
     }
 
     public void exitTestClass() {
-        Log.i(TAG, "exitTestClass: " + mRunner.mTestJavaClass.getName());
+        if (RAVENWOOD_VERBOSE_LOGGING) {
+            Log.v(TAG, "exitTestClass: " + mRunner.mTestJavaClass.getName());
+        }
         assertTrue(RAVENWOOD_RULE_ERROR, sActiveProperties.isEmpty());
         RavenwoodRuntimeEnvironmentController.exitTestClass();
     }
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 172cec3..3cb6c5a 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -96,7 +96,7 @@
  * Responsible for initializing and the environment.
  */
 public class RavenwoodRuntimeEnvironmentController {
-    private static final String TAG = "RavenwoodRuntimeEnvironmentController";
+    private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG;
 
     private RavenwoodRuntimeEnvironmentController() {
     }
@@ -105,6 +105,9 @@
     private static final String LIBRAVENWOOD_INITIALIZER_NAME = "ravenwood_initializer";
     private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime";
 
+    private static final String ANDROID_LOG_TAGS = "ANDROID_LOG_TAGS";
+    private static final String RAVENWOOD_ANDROID_LOG_TAGS = "RAVENWOOD_" + ANDROID_LOG_TAGS;
+
     /**
      * When enabled, attempt to dump all thread stacks just before we hit the
      * overall Tradefed timeout, to aid in debugging deadlocks.
@@ -232,20 +235,22 @@
         // Make sure libravenwood_runtime is loaded.
         System.load(RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_RUNTIME_NAME));
 
+        Log_ravenwood.setLogLevels(getLogTags());
         Log_ravenwood.onRavenwoodRuntimeNativeReady();
 
         // Do the basic set up for the android sysprops.
         RavenwoodSystemProperties.initialize();
 
+        // Enable all log levels for native logging, until we'll have a way to change the native
+        // side log level at runtime.
         // Do this after loading RAVENWOOD_NATIVE_RUNTIME_NAME (which backs Os.setenv()),
         // before loadFrameworkNativeCode() (which uses $ANDROID_LOG_TAGS).
-        if (RAVENWOOD_VERBOSE_LOGGING) {
-            RavenwoodCommonUtils.log(TAG, "Force enabling verbose logging");
-            try {
-                Os.setenv("ANDROID_LOG_TAGS", "*:v", true);
-            } catch (ErrnoException e) {
-                throw new RuntimeException(e);
-            }
+        // This would also prevent libbase from crashing the process (b/381112373) because
+        // the string format it accepts is very limited.
+        try {
+            Os.setenv("ANDROID_LOG_TAGS", "*:v", true);
+        } catch (ErrnoException e) {
+            throw new RuntimeException(e);
         }
 
         // Make sure libandroid_runtime is loaded.
@@ -333,6 +338,18 @@
         initializeCompatIds();
     }
 
+    /**
+     * Get log tags from environmental variable.
+     */
+    @Nullable
+    private static String getLogTags() {
+        var logTags = System.getenv(RAVENWOOD_ANDROID_LOG_TAGS);
+        if (logTags == null) {
+            logTags = System.getenv(ANDROID_LOG_TAGS);
+        }
+        return logTags;
+    }
+
     private static void loadRavenwoodProperties() {
         var props = RavenwoodSystemProperties.readProperties("ravenwood.properties");
 
@@ -535,7 +552,7 @@
     }
 
     private static void dumpCommandLineArgs() {
-        Log.i(TAG, "JVM arguments:");
+        Log.v(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
@@ -544,7 +561,7 @@
         var args = ManagementFactory.getRuntimeMXBean().getInputArguments();
 
         for (var arg : args) {
-            Log.i(TAG, "  " + arg);
+            Log.v(TAG, "  " + arg);
         }
     }
 }
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index 99b38ed..70c161c1 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -34,7 +34,7 @@
  * A class to manage the core default system properties of the Ravenwood environment.
  */
 public class RavenwoodSystemProperties {
-    private static final String TAG = "RavenwoodSystemProperties";
+    private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG;
 
     /** We pull in properties from this file. */
     private static final String RAVENWOOD_BUILD_PROP = "ravenwood-data/ravenwood-build.prop";
@@ -84,7 +84,7 @@
         var ravenwoodProps = readProperties(path + RAVENWOOD_BUILD_PROP);
         var deviceProps = readProperties(path + DEVICE_BUILD_PROP);
 
-        Log.i(TAG, "Default system properties:");
+        Log.v(TAG, "Default system properties:");
         ravenwoodProps.forEach((key, origValue) -> {
             final String value;
 
@@ -100,7 +100,7 @@
             } else {
                 value = origValue;
             }
-            Log.i(TAG, key + "=" + value);
+            Log.v(TAG, key + "=" + value);
             sDefaultValues.put(key, value);
         });
 
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
index 7870585..c8b10d2 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodTestStats.java
@@ -41,7 +41,7 @@
  * `/tmp/Ravenwood-stats_[TEST-MODULE=NAME]_latest.csv`.
  */
 public class RavenwoodTestStats {
-    private static final String TAG = "RavenwoodTestStats";
+    private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG;
     private static final String HEADER = "Module,Class,OuterClass,Passed,Failed,Skipped";
 
     private static RavenwoodTestStats sInstance;
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java
index 31a1416..3592105 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodAwareTestRunnerBase.java
@@ -15,6 +15,8 @@
  */
 package android.platform.test.ravenwood;
 
+import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
+
 import android.platform.test.annotations.internal.InnerRunner;
 import android.util.Log;
 
@@ -35,7 +37,7 @@
 import org.junit.runners.model.TestClass;
 
 abstract class RavenwoodAwareTestRunnerBase extends Runner implements Filterable, Orderable {
-    private static final String TAG = "Ravenwood";
+    public static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG;
 
     boolean mRealRunnerTakesRunnerBuilder = false;
 
@@ -53,7 +55,9 @@
         }
 
         try {
-            Log.i(TAG, "Initializing the inner runner: " + runnerClass);
+            if (RAVENWOOD_VERBOSE_LOGGING) {
+                Log.v(TAG, "Initializing the inner runner: " + runnerClass);
+            }
             try {
                 return runnerClass.getConstructor(Class.class)
                         .newInstance(testClass.getJavaClass());
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
deleted file mode 100644
index 3ed0f50..0000000
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
+++ /dev/null
@@ -1,139 +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 android.platform.test.ravenwood;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @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.
-     * @hide
-     */
-    @Target({ElementType.FIELD})
-    @Retention(RetentionPolicy.RUNTIME)
-    public @interface Config {
-    }
-
-    /**
-     * Stores internal states / methods associated with this config that's only needed in
-     * junit-impl.
-     */
-    private RavenwoodConfig() {
-    }
-
-    /**
-     * Return if the current process is running on a Ravenwood test environment.
-     */
-    public static boolean isOnRavenwood() {
-        return RavenwoodRule.isOnRavenwood();
-    }
-
-    public static class Builder {
-        private final RavenwoodConfig mConfig = new RavenwoodConfig();
-
-        public Builder() {
-        }
-
-        /**
-         * @deprecated no longer used. We always use an app UID.
-         */
-        @Deprecated
-        public Builder setProcessSystem() {
-            return this;
-        }
-
-        /**
-         * @deprecated no longer used. We always use an app UID.
-         */
-        @Deprecated
-        public Builder setProcessApp() {
-            return this;
-        }
-
-        /**
-         * @deprecated no longer used. Package name is set in the build file. (for now)
-         */
-        @Deprecated
-        public Builder setPackageName(@NonNull String packageName) {
-            return this;
-        }
-
-        /**
-         * @deprecated no longer used. Package name is set in the build file. (for now)
-         */
-        @Deprecated
-        public Builder setTargetPackageName(@NonNull String packageName) {
-            return this;
-        }
-
-
-        /**
-         * @deprecated no longer used. Target SDK level is set in the build file. (for now)
-         */
-        @Deprecated
-        public Builder setTargetSdkLevel(int sdkLevel) {
-            return this;
-        }
-
-        /**
-         * @deprecated no longer used. Main thread is always available.
-         */
-        @Deprecated
-        public Builder setProvideMainThread(boolean provideMainThread) {
-            return this;
-        }
-
-        /**
-         * @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;
-        }
-
-        /**
-         * @deprecated no longer used. All supported services are available.
-         */
-        @Deprecated
-        public Builder setServicesRequired(@NonNull Class<?>... services) {
-            return this;
-        }
-
-        public RavenwoodConfig build() {
-            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 e49d3d9..ffe5f6c 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -36,12 +36,10 @@
 import java.util.regex.Pattern;
 
 /**
- * @deprecated This class is undergoing a major change. Reach out to g/ravenwood if you need
- * any featues in it.
+ * Reach out to g/ravenwood if you need any features in it.
  */
-@Deprecated
 public final class RavenwoodRule implements TestRule {
-    private static final String TAG = "RavenwoodRule";
+    private static final String TAG = com.android.ravenwood.common.RavenwoodCommonUtils.TAG;
 
     static final boolean IS_ON_RAVENWOOD = RavenwoodCommonUtils.isOnRavenwood();
 
@@ -193,6 +191,12 @@
         return IS_ON_RAVENWOOD;
     }
 
+    private static void ensureOnRavenwood(String featureName) {
+        if (!IS_ON_RAVENWOOD) {
+            throw new RuntimeException(featureName + " is only supported on Ravenwood.");
+        }
+    }
+
     /**
      * @deprecated Use
      * {@code androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().getContext()}
@@ -242,6 +246,40 @@
         return System.currentTimeMillis();
     }
 
+    /**
+     * Equivalent to setting the ANDROID_LOG_TAGS environmental variable.
+     *
+     * See https://developer.android.com/tools/logcat#filteringOutput for the string format.
+     *
+     * NOTE: this works only on Ravenwood.
+     */
+    public static void setAndroidLogTags(@Nullable String androidLogTags) {
+        ensureOnRavenwood("RavenwoodRule.setAndroidLogTags()");
+        try {
+            Class<?> logRavenwoodClazz = Class.forName("android.util.Log_ravenwood");
+            var setter = logRavenwoodClazz.getMethod("setLogLevels", String.class);
+            setter.invoke(null, androidLogTags);
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Set a log level for a given tag. Pass NULL to {@code tag} to change the default level.
+     *
+     * NOTE: this works only on Ravenwood.
+     */
+    public static void setLogLevel(@Nullable String tag, int level) {
+        ensureOnRavenwood("RavenwoodRule.setLogLevel()");
+        try {
+            Class<?> logRavenwoodClazz = Class.forName("android.util.Log_ravenwood");
+            var setter = logRavenwoodClazz.getMethod("setLogLevel", String.class, int.class);
+            setter.invoke(null, tag, level);
+        } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     // Below are internal to ravenwood. Don't use them from normal tests...
 
     public static class RavenwoodPrivate {
diff --git a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
index b4b75178..8d9bcd5 100644
--- a/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-stub-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -31,8 +31,6 @@
  * This is only used when a real device-side test has Ravenizer enabled.
  */
 public class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase {
-    private static final String TAG = "Ravenwood";
-
     private static class NopRule implements TestRule {
         @Override
         public Statement apply(Statement base, Description description) {
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 2a04d44..a967a3f 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
@@ -33,7 +33,7 @@
 import java.util.function.Supplier;
 
 public class RavenwoodCommonUtils {
-    private static final String TAG = "RavenwoodCommonUtils";
+    public static final String TAG = "Ravenwood";
 
     private RavenwoodCommonUtils() {
     }
diff --git a/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java
index 7b26fe5..7ab9cda 100644
--- a/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java
+++ b/ravenwood/runtime-helper-src/framework/android/util/Log_ravenwood.java
@@ -15,8 +15,10 @@
  */
 package android.util;
 
+import android.annotation.Nullable;
 import android.util.Log.Level;
 
+import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.RuntimeInit;
 import com.android.ravenwood.RavenwoodRuntimeNative;
 import com.android.ravenwood.common.RavenwoodCommonUtils;
@@ -24,7 +26,9 @@
 import java.io.PrintStream;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.Locale;
+import java.util.Map;
 
 /**
  * Ravenwood "native substitution" class for {@link android.util.Log}.
@@ -35,16 +39,100 @@
  */
 public class Log_ravenwood {
 
-    public static final SimpleDateFormat sTimestampFormat =
+    private static final SimpleDateFormat sTimestampFormat =
             new SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US);
 
-    public static boolean isLoggable(String tag, @Level int level) {
-        return true;
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static int sDefaultLogLevel;
+
+    @GuardedBy("sLock")
+    private static final Map<String, Integer> sTagLogLevels = new HashMap<>();
+
+    /**
+     * Used by {@link android.platform.test.ravenwood.RavenwoodRule#setAndroidLogTags(String)}
+     * via reflections.
+     */
+    public static void setLogLevels(String androidLogTags) {
+        var map = parseLogLevels(androidLogTags);
+
+        synchronized (sLock) {
+            sTagLogLevels.clear();
+            sTagLogLevels.putAll(map);
+
+            var def = map.get("*");
+            sDefaultLogLevel = def != null ? def : Log.VERBOSE;
+        }
+    }
+
+    private static Map<String, Integer> parseLogLevels(String androidLogTags) {
+        final Map<String, Integer> ret = new HashMap<>();
+
+        if (androidLogTags == null) {
+            return ret;
+        }
+
+        String[] tagPairs = androidLogTags.trim().split("\\s+");
+        for (String tagPair : tagPairs) {
+            String[] parts = tagPair.split(":");
+            if (parts.length == 2) {
+                String tag = parts[0];
+                try {
+                    int priority = switch (parts[1].toUpperCase(Locale.ROOT)) {
+                        case "V": yield Log.VERBOSE;
+                        case "D": yield Log.DEBUG;
+                        case "I": yield Log.INFO;
+                        case "W": yield Log.WARN;
+                        case "E": yield Log.ERROR;
+                        case "F": yield Log.ERROR + 1; // Not used in the java side.
+                        case "S": yield Integer.MAX_VALUE; // Silent
+                        default: throw new IllegalArgumentException(
+                                "Invalid priority level for tag: " + tag);
+                    };
+
+                    ret.put(tag, priority);
+                } catch (IllegalArgumentException e) {
+                    System.err.println(e.getMessage());
+                }
+            } else {
+                System.err.println("Invalid tag format: " + tagPair);
+            }
+        }
+
+        return ret;
+    }
+
+    /**
+     * Used by {@link android.platform.test.ravenwood.RavenwoodRule#setLogLevel(String, int)}
+     * via reflections. Pass NULL to {@code tag} to set the default level.
+     */
+    public static void setLogLevel(@Nullable String tag, int level) {
+        synchronized (sLock) {
+            if (tag == null) {
+                sDefaultLogLevel = level;
+            } else {
+                sTagLogLevels.put(tag, level);
+            }
+        }
+    }
+
+    /**
+     * Replaces {@link Log#isLoggable}.
+     */
+    public static boolean isLoggable(String tag, @Level int priority) {
+        synchronized (sLock) {
+            var threshold = sTagLogLevels.get(tag);
+            if (threshold == null) {
+                threshold = sDefaultLogLevel;
+            }
+            return priority >= threshold;
+        }
     }
 
     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.
+        if (!isLoggable(tag, priority)) {
+            return msg.length();
         }
 
         final String prio;
diff --git a/ravenwood/runtime-jni/ravenwood_initializer.cpp b/ravenwood/runtime-jni/ravenwood_initializer.cpp
index dbbc345..391c5d56 100644
--- a/ravenwood/runtime-jni/ravenwood_initializer.cpp
+++ b/ravenwood/runtime-jni/ravenwood_initializer.cpp
@@ -140,7 +140,7 @@
     if (gVM != nullptr && gRunnerState != nullptr) {
         JNIEnv* env;
         if (gVM->GetEnv((void**)&env, JNI_VERSION_1_4) >= 0) {
-            ALOGI("%s access to system property '%s'", write ? "Write" : "Read", key);
+            ALOGV("%s access to system property '%s'", write ? "Write" : "Read", key);
             env->CallStaticVoidMethod(gRunnerState, gCheckSystemPropertyAccess,
                                       env->NewStringUTF(key), write ? JNI_TRUE : JNI_FALSE);
             return;
@@ -208,7 +208,7 @@
 };
 
 extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
-    ALOGI("%s: JNI_OnLoad", __FILE__);
+    ALOGV("%s: JNI_OnLoad", __FILE__);
 
     maybeRedirectLog();
 
diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp
index bab4c7e..8d8ed71 100644
--- a/ravenwood/runtime-jni/ravenwood_runtime.cpp
+++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp
@@ -204,7 +204,7 @@
 };
 
 extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) {
-    ALOGI("%s: JNI_OnLoad", __FILE__);
+    ALOGV("%s: JNI_OnLoad", __FILE__);
 
     JNIEnv* env = GetJNIEnvOrDie(vm);
     g_StructStat = FindGlobalClassOrDie(env, "android/system/StructStat");
diff --git a/ravenwood/scripts/extract-last-soong-commands.py b/ravenwood/scripts/extract-last-soong-commands.py
new file mode 100755
index 0000000..bdc1de0
--- /dev/null
+++ b/ravenwood/scripts/extract-last-soong-commands.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python3
+# 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.
+
+
+# This script extracts all the commands executed in the last soong run,
+# and write them into a script file, and print the filename.
+#
+# All the commands are commented out. Uncomment what you want to execute as
+# needed before running it.
+
+import datetime
+import gzip
+import os
+import re
+import shlex
+import sys
+
+re_command = re.compile(r''' ^\[.*?\]  \s*  (.*) ''', re.X)
+
+HEADER = r'''#!/bin/bash
+
+set -e # Stop on a failed command
+
+cd "${ANDROID_BUILD_TOP:?}"
+
+'''
+
+OUT_SCRIPT_DIR = "/tmp/"
+OUT_SCRIPT_FORMAT = "soong-rerun-%Y-%m-%d_%H-%M-%S.sh"
+
+def main(args):
+    log = os.environ["ANDROID_BUILD_TOP"] + "/out/verbose.log.gz"
+    outdir = "/tmp/"
+    outfile = outdir + datetime.datetime.now().strftime(OUT_SCRIPT_FORMAT)
+
+    with open(outfile, "w") as out:
+        out.write(HEADER)
+
+        with gzip.open(log) as f:
+            for line in f:
+                s = line.decode("utf-8")
+
+                if s.startswith("verbose"):
+                    continue
+                if re.match('^\[.*bootstrap blueprint', s):
+                    continue
+
+                s = s.rstrip()
+
+                m = re_command.search(s)
+                if m:
+                    command = m.groups()[0]
+
+                    out.write('#========\n')
+
+                    # Show the full command line before executing it.
+                    out.write('#echo ' + shlex.quote(command) + '\n')
+                    out.write('\n')
+
+                    # Execute the command.
+                    out.write('#' + command + '\n')
+
+                    out.write('\n')
+
+                    continue
+
+                if s.startswith("FAILED:"):
+                    break
+
+    os.chmod(outfile, 0o755)
+    print(outfile)
+
+    return 0
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:]))
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
deleted file mode 100644
index 306c2b39..0000000
--- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
+++ /dev/null
@@ -1,42 +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.ravenwoodtest.bivalenttest;
-
-import static android.platform.test.ravenwood.RavenwoodConfig.isOnRavenwood;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assume.assumeTrue;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.platform.app.InstrumentationRegistry;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test to make sure the config field is used.
- */
-@RunWith(AndroidJUnit4.class)
-public class RavenwoodConfigTest {
-    private static final String PACKAGE_NAME = "com.android.ravenwoodtest.bivalenttest";
-
-    @Test
-    public void testConfig() {
-        assumeTrue(isOnRavenwood());
-        assertEquals(PACKAGE_NAME,
-                InstrumentationRegistry.getInstrumentation().getContext().getPackageName());
-    }
-}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodLogLevelTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodLogLevelTest.java
new file mode 100644
index 0000000..74c1f3f6
--- /dev/null
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodLogLevelTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.ravenwoodtest.coretest;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.ravenwood.RavenwoodRule;
+import android.util.Log;
+
+import com.android.ravenwood.common.RavenwoodCommonUtils;
+
+import org.junit.Test;
+
+public class RavenwoodLogLevelTest {
+    /**
+     * Assert that the `priority` is loggable, but one level below is not.
+     */
+    private void assertBarelyLoggable(String tag, int priority) {
+        assertEquals(true, Log.isLoggable(tag, priority));
+        assertEquals(false, Log.isLoggable(tag, priority - 1));
+    }
+
+    @Test
+    public void testDefaultLogTags() {
+        RavenwoodRule.setAndroidLogTags(null);
+
+        // Info should always be loggable.
+        assertEquals(true, Log.isLoggable("TAG1", Log.INFO));
+        assertEquals(true, Log.isLoggable("TAG2", Log.INFO));
+
+        assertEquals(true, Log.isLoggable("TAG1", Log.DEBUG));
+        assertEquals(true, Log.isLoggable("TAG2", Log.VERBOSE));
+    }
+
+    @Test
+    public void testAllVerbose() {
+        RavenwoodRule.setAndroidLogTags("*:V");
+
+        assertEquals(true, Log.isLoggable("TAG1", Log.INFO));
+        assertEquals(true, Log.isLoggable("TAG2", Log.INFO));
+
+        assertEquals(true, Log.isLoggable("TAG1", Log.DEBUG));
+        assertEquals(true, Log.isLoggable("TAG2", Log.VERBOSE));
+    }
+
+    @Test
+    public void testAllSilent() {
+        RavenwoodRule.setAndroidLogTags("*:S");
+
+        assertEquals(false, Log.isLoggable("TAG1", Log.ASSERT));
+        assertEquals(false, Log.isLoggable("TAG2", Log.ASSERT));
+    }
+
+    @Test
+    public void testComplex() {
+        RavenwoodRule.setAndroidLogTags("TAG1:W TAG2:D *:I");
+
+        assertBarelyLoggable("TAG1", Log.WARN);
+        assertBarelyLoggable("TAG2", Log.DEBUG);
+        assertBarelyLoggable("TAG3", Log.INFO);
+    }
+
+    @Test
+    public void testAllVerbose_setLogLevel() {
+        RavenwoodRule.setAndroidLogTags(null);
+        RavenwoodRule.setLogLevel(null, Log.VERBOSE);
+
+        assertEquals(true, Log.isLoggable("TAG1", Log.INFO));
+        assertEquals(true, Log.isLoggable("TAG2", Log.INFO));
+
+        assertEquals(true, Log.isLoggable("TAG1", Log.DEBUG));
+        assertEquals(true, Log.isLoggable("TAG2", Log.VERBOSE));
+    }
+
+    @Test
+    public void testAllSilent_setLogLevel() {
+        RavenwoodRule.setAndroidLogTags(null);
+        RavenwoodRule.setLogLevel(null, Log.ASSERT + 1);
+
+        assertEquals(false, Log.isLoggable("TAG1", Log.ASSERT));
+        assertEquals(false, Log.isLoggable("TAG2", Log.ASSERT));
+    }
+
+    @Test
+    public void testComplex_setLogLevel() {
+        RavenwoodRule.setAndroidLogTags(null);
+        RavenwoodRule.setLogLevel(null, Log.INFO);
+        RavenwoodRule.setLogLevel("TAG1", Log.WARN);
+        RavenwoodRule.setLogLevel("TAG2", Log.DEBUG);
+
+        assertBarelyLoggable("TAG1", Log.WARN);
+        assertBarelyLoggable("TAG2", Log.DEBUG);
+        assertBarelyLoggable("TAG3", Log.INFO);
+    }
+}
diff --git a/ravenwood/texts/ravenwood-common-policies.txt b/ravenwood/texts/ravenwood-common-policies.txt
index 08f53977..83c3151 100644
--- a/ravenwood/texts/ravenwood-common-policies.txt
+++ b/ravenwood/texts/ravenwood-common-policies.txt
@@ -14,7 +14,7 @@
 
 # Support APIs not available in standard JRE
 class java.io.FileDescriptor keep
-    method getInt$ ()I @com.android.ravenwood.RavenwoodJdkPatch.getInt$
-    method setInt$ (I)V @com.android.ravenwood.RavenwoodJdkPatch.setInt$
+    method getInt$ @com.android.ravenwood.RavenwoodJdkPatch.getInt$
+    method setInt$ @com.android.ravenwood.RavenwoodJdkPatch.setInt$
 class java.util.LinkedHashMap keep
-    method eldest ()Ljava/util/Map$Entry; @com.android.ravenwood.RavenwoodJdkPatch.eldest
+    method eldest @com.android.ravenwood.RavenwoodJdkPatch.eldest
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
index 59fa464..fc885d6 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
@@ -66,6 +66,9 @@
         methodName: String,
         descriptor: String
     ) {
+        if (descriptor == "*") {
+            return
+        }
         if (classes.findMethod(className, methodName, descriptor) == null) {
             log.w("Unknown method $className.$methodName$descriptor")
         }
@@ -92,7 +95,8 @@
             descriptor: String,
             ): FilterPolicyWithReason {
         return mPolicies[getMethodKey(className, methodName, descriptor)]
-                ?: super.getPolicyForMethod(className, methodName, descriptor)
+            ?: mPolicies[getMethodKey(className, methodName, "*")]
+            ?: super.getPolicyForMethod(className, methodName, descriptor)
     }
 
     fun setPolicyForMethod(
@@ -107,7 +111,8 @@
 
     override fun getRenameTo(className: String, methodName: String, descriptor: String): String? {
         return mRenames[getMethodKey(className, methodName, descriptor)]
-                ?: super.getRenameTo(className, methodName, descriptor)
+            ?: mRenames[getMethodKey(className, methodName, "*")]
+            ?: super.getRenameTo(className, methodName, descriptor)
     }
 
     fun setRenameTo(className: String, methodName: String, descriptor: String, toName: String) {
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
index caf80eb..7462a8c 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
@@ -303,12 +303,21 @@
     }
 
     private fun parseMethod(fields: Array<String>) {
-        if (fields.size < 4) {
-            throw ParseException("Method ('m') expects 3 fields.")
+        if (fields.size < 3 || fields.size > 4) {
+            throw ParseException("Method ('m') expects 3 or 4 fields.")
         }
         val name = fields[1]
-        val signature = fields[2]
-        val policy = parsePolicy(fields[3])
+        val signature: String
+        val policyStr: String
+        if (fields.size <= 3) {
+            signature = "*"
+            policyStr = fields[2]
+        } else {
+            signature = fields[2]
+            policyStr = fields[3]
+        }
+
+        val policy = parsePolicy(policyStr)
 
         if (!policy.isUsableWithMethods) {
             throw ParseException("Method can't have policy '$policy'")
@@ -321,7 +330,7 @@
             policy.withReason(FILTER_REASON)
         )
         if (policy == FilterPolicy.Substitute) {
-            val fromName = fields[3].substring(1)
+            val fromName = policyStr.substring(1)
 
             if (fromName == name) {
                 throw ParseException(
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt
index d45f414..a3f934c 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/filters/TextFilePolicyMethodReplaceFilter.kt
@@ -48,10 +48,11 @@
         // Maybe use 'Tri' if we end up having too many replacements.
         spec.forEach {
             if (className == it.fromClass &&
-                methodName == it.fromMethod &&
-                descriptor == it.fromDescriptor
+                methodName == it.fromMethod
                 ) {
-                return MethodReplaceTarget(it.toClass, it.toMethod)
+                if (it.fromDescriptor == "*" || descriptor == it.fromDescriptor) {
+                    return MethodReplaceTarget(it.toClass, it.toMethod)
+                }
             }
         }
         return null
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt b/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
index 3c138d2..2f35d35 100644
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
@@ -3,11 +3,11 @@
   # field remove	remove # Implicitly remove
   method <init>	()V	            keep
   method addOne	(I)I	        keep
-  method addOneInner	(I)I	keep
+  method addOneInner	keep
   method toBeRemoved	(Ljava/lang/String;)V	remove
   method addTwo	(I)I	        @addTwo_host
   # method addTwo_host	(I)I	# used as a substitute
-  method nativeAddThree	(I)I	@addThree_host
+  method nativeAddThree	        @addThree_host
   # method addThree_host	(I)I	# used as a substitute
   method unsupportedMethod	()Ljava/lang/String;	throw
   method visibleButUsesUnsupportedMethod	()Ljava/lang/String;	keep
diff --git a/services/core/Android.bp b/services/core/Android.bp
index f08c876..349f3ee 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -233,7 +233,6 @@
         "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/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 43774bbc..b0dae6a 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -90,6 +90,7 @@
      */
     public static final int RESOLVE_NON_RESOLVER_ONLY = 0x00000002;
 
+    @Deprecated
     @IntDef(value = {
             INTEGRITY_VERIFICATION_ALLOW,
             INTEGRITY_VERIFICATION_REJECT,
@@ -97,18 +98,10 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface IntegrityVerificationResult {}
 
-    /**
-     * Used as the {@code verificationCode} argument for
-     * {@link PackageManagerInternal#setIntegrityVerificationResult(int, int)} to indicate that the
-     * integrity component allows the install to proceed.
-     */
+    @Deprecated
     public static final int INTEGRITY_VERIFICATION_ALLOW = 1;
 
-    /**
-     * Used as the {@code verificationCode} argument for
-     * {@link PackageManagerInternal#setIntegrityVerificationResult(int, int)} to indicate that the
-     * integrity component does not allow install to proceed.
-     */
+    @Deprecated
     public static final int INTEGRITY_VERIFICATION_REJECT = 0;
 
     /**
@@ -1131,17 +1124,13 @@
     public abstract boolean isPermissionUpgradeNeeded(@UserIdInt int userId);
 
     /**
-     * Allows the integrity component to respond to the
-     * {@link Intent#ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION package verification
-     * broadcast} to respond to the package manager. The response must include
-     * the {@code verificationCode} which is one of
-     * {@link #INTEGRITY_VERIFICATION_ALLOW} and {@link #INTEGRITY_VERIFICATION_REJECT}.
+     * Used to allow the integrity component to respond to the
+     * ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION package verification
+     * broadcast to respond to the package manager.
      *
-     * @param verificationId pending package identifier as passed via the
-     *            {@link PackageManager#EXTRA_VERIFICATION_ID} Intent extra.
-     * @param verificationResult either {@link #INTEGRITY_VERIFICATION_ALLOW}
-     *            or {@link #INTEGRITY_VERIFICATION_REJECT}.
+     * Deprecated.
      */
+    @Deprecated
     public abstract void setIntegrityVerificationResult(int verificationId,
             @IntegrityVerificationResult int verificationResult);
 
diff --git a/services/core/java/com/android/server/SecurityStateManagerService.java b/services/core/java/com/android/server/SecurityStateManagerService.java
index 98039be..fe21fbd 100644
--- a/services/core/java/com/android/server/SecurityStateManagerService.java
+++ b/services/core/java/com/android/server/SecurityStateManagerService.java
@@ -22,6 +22,7 @@
 
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.ISecurityStateManager;
@@ -56,6 +57,15 @@
 
     @Override
     public Bundle getGlobalSecurityState() {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return getGlobalSecurityStateInternal();
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    private Bundle getGlobalSecurityStateInternal() {
         Bundle globalSecurityState = new Bundle();
         globalSecurityState.putString(KEY_SYSTEM_SPL, Build.VERSION.SECURITY_PATCH);
         globalSecurityState.putString(KEY_VENDOR_SPL,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4a4a1b4..0152f94 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7609,7 +7609,7 @@
     }
 
     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo,
-            ApplicationInfo sdkSandboxClientApp) {
+            ApplicationInfo sdkSandboxClientApp, int profileType) {
         synchronized (mAppProfiler.mProfilerLock) {
             if (!Build.IS_DEBUGGABLE) {
                 boolean isAppDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
@@ -7625,7 +7625,7 @@
                             + "and not profileable by shell: " + app.packageName);
                 }
             }
-            mAppProfiler.setProfileAppLPf(processName, profilerInfo);
+            mAppProfiler.setProfileAppLPf(processName, profilerInfo, profileType);
         }
     }
 
@@ -17883,7 +17883,8 @@
                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
         }
 
-        if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
+        if (start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR
+                && (profilerInfo == null || profilerInfo.profileFd == null)) {
             throw new IllegalArgumentException("null profile info or fd");
         }
 
@@ -19499,7 +19500,9 @@
                     }
 
                     if (profilerInfo != null) {
-                        setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null);
+                        // We only support normal method tracing along with app startup for now.
+                        setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo,
+                                null, /*profileType= */ ProfilerInfo.PROFILE_TYPE_REGULAR);
                     }
                     wmLock.notify();
                 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 955437b..1853973 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -1081,7 +1081,7 @@
         String profileFile = null;
         boolean start = false;
         int userId = UserHandle.USER_CURRENT;
-        int profileType = 0;
+        int profileType = ProfilerInfo.PROFILE_TYPE_REGULAR;
         mSamplingInterval = 0;
         mStreaming = false;
         mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT;
@@ -1123,6 +1123,18 @@
                 }
             }
             process = getNextArgRequired();
+        } else if ("lowoverhead".equals(cmd)) {
+            // This is an experimental low overhead profiling.
+            profileType = ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD;
+            cmd = getNextArgRequired();
+            if ("start".equals(cmd)) {
+                start = true;
+            } else if ("stop".equals(cmd)) {
+                start = false;
+            } else {
+                throw new IllegalArgumentException("Profile command not valid");
+            }
+            process = getNextArgRequired();
         } else {
             // Compatibility with old syntax: process is specified first.
             process = cmd;
@@ -1142,7 +1154,12 @@
         ParcelFileDescriptor fd = null;
         ProfilerInfo profilerInfo = null;
 
-        if (start) {
+        // For regular method tracing  profileFile should be provided with the start command. For
+        // low overhead method tracing the profileFile is optional and provided with the stop
+        // command.
+        if ((start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR)
+                || (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD
+                  && !start && getRemainingArgsCount() > 0)) {
             profileFile = getNextArgRequired();
             fd = openFileForSystem(profileFile, "w");
             if (fd == null) {
diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java
index dda48ad..79a0d73 100644
--- a/services/core/java/com/android/server/am/AppProfiler.java
+++ b/services/core/java/com/android/server/am/AppProfiler.java
@@ -1990,7 +1990,7 @@
     }
 
     @GuardedBy("mProfilerLock")
-    private void stopProfilerLPf(ProcessRecord proc, int profileType) {
+    private void stopProfilerLPf(ProcessRecord proc, ProfilerInfo profilerInfo, int profileType) {
         if (proc == null || proc == mProfileData.getProfileProc()) {
             proc = mProfileData.getProfileProc();
             profileType = mProfileType;
@@ -2004,7 +2004,7 @@
             return;
         }
         try {
-            thread.profilerControl(false, null, profileType);
+            thread.profilerControl(false, profilerInfo, profileType);
         } catch (RemoteException e) {
             throw new IllegalStateException("Process disappeared");
         }
@@ -2039,41 +2039,58 @@
             ProfilerInfo profilerInfo, int profileType) {
         try {
             if (start) {
-                stopProfilerLPf(null, 0);
+                boolean needsFile = (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR);
+                stopProfilerLPf(null, null, 0);
                 mService.setProfileApp(proc.info, proc.processName, profilerInfo,
-                        proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null);
+                        proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null, profileType);
                 mProfileData.setProfileProc(proc);
                 mProfileType = profileType;
-                ParcelFileDescriptor fd = profilerInfo.profileFd;
-                try {
-                    fd = fd.dup();
-                } catch (IOException e) {
-                    fd = null;
-                }
-                profilerInfo.profileFd = fd;
-                proc.mProfile.getThread().profilerControl(start, profilerInfo, profileType);
-                fd = null;
-                try {
-                    mProfileData.getProfilerInfo().profileFd.close();
-                } catch (IOException e) {
-                }
-                mProfileData.getProfilerInfo().profileFd = null;
 
-                if (proc.getPid() == mService.MY_PID) {
-                    // When profiling the system server itself, avoid closing the file
-                    // descriptor, as profilerControl will not create a copy.
-                    // Note: it is also not correct to just set profileFd to null, as the
-                    //       whole ProfilerInfo instance is passed down!
-                    profilerInfo = null;
-                }
-            } else {
-                stopProfilerLPf(proc, profileType);
-                if (profilerInfo != null && profilerInfo.profileFd != null) {
+                ParcelFileDescriptor fd = null;
+                if (needsFile) {
+                    fd = profilerInfo.profileFd;
                     try {
-                        profilerInfo.profileFd.close();
+                        fd = fd.dup();
+                    } catch (IOException e) {
+                        fd = null;
+                    }
+                    profilerInfo.profileFd = fd;
+                }
+
+                proc.mProfile.getThread().profilerControl(start, profilerInfo, profileType);
+
+                if (needsFile) {
+                    fd = null;
+                    try {
+                        mProfileData.getProfilerInfo().profileFd.close();
                     } catch (IOException e) {
                     }
+                    mProfileData.getProfilerInfo().profileFd = null;
+
+                    if (proc.getPid() == mService.MY_PID) {
+                        // When profiling the system server itself, avoid closing the file
+                        // descriptor, as profilerControl will not create a copy.
+                        // Note: it is also not correct to just set profileFd to null, as the
+                        //       whole ProfilerInfo instance is passed down!
+                        profilerInfo = null;
+                    }
                 }
+            } else {
+                boolean mayNeedFile = (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD);
+                if (profilerInfo != null && profilerInfo.profileFd != null) {
+                    ParcelFileDescriptor fd = profilerInfo.profileFd;
+                    try {
+                        if (mayNeedFile) {
+                            fd = fd.dup();
+                        } else {
+                            fd.close();
+                        }
+                    } catch (IOException e) {
+                        fd = null;
+                    }
+                    profilerInfo.profileFd = fd;
+                }
+                stopProfilerLPf(proc, profilerInfo, profileType);
             }
 
             return true;
@@ -2090,7 +2107,7 @@
     }
 
     @GuardedBy("mProfilerLock")
-    void setProfileAppLPf(String processName, ProfilerInfo profilerInfo) {
+    void setProfileAppLPf(String processName, ProfilerInfo profilerInfo, int profileType) {
         mProfileData.setProfileApp(processName);
 
         if (mProfileData.getProfilerInfo() != null) {
@@ -2101,8 +2118,10 @@
                 }
             }
         }
-        mProfileData.setProfilerInfo(new ProfilerInfo(profilerInfo));
-        mProfileType = 0;
+        if (profilerInfo != null) {
+            mProfileData.setProfilerInfo(new ProfilerInfo(profilerInfo));
+        }
+        mProfileType = profileType;
     }
 
     @GuardedBy("mProfilerLock")
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 90f92b0..f79256d 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -39,7 +39,6 @@
 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;
@@ -392,8 +391,7 @@
     static ProtoInputStream sendAconfigdRequests(ProtoOutputStream requests) {
         // connect to aconfigd socket
         LocalSocket client = new LocalSocket();
-        String socketName = enableSystemAconfigdRust()
-                    ? "aconfigd_system" : "aconfigd";
+        String socketName = "aconfigd_system";
         try {
             client.connect(new LocalSocketAddress(
                 socketName, LocalSocketAddress.Namespace.RESERVED));
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index a132876b..0914b7e 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -93,29 +93,6 @@
         mContext = context;
         mPackageManagerInternal = packageManagerInternal;
         mHandler = handler;
-
-        IntentFilter integrityVerificationFilter = new IntentFilter();
-        integrityVerificationFilter.addAction(ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
-        try {
-            integrityVerificationFilter.addDataType(PACKAGE_MIME_TYPE);
-        } catch (IntentFilter.MalformedMimeTypeException e) {
-            throw new RuntimeException("Mime type malformed: should never happen.", e);
-        }
-
-        mContext.registerReceiver(
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        if (!ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION.equals(
-                                intent.getAction())) {
-                            return;
-                        }
-                        mHandler.post(() -> handleIntegrityVerification(intent));
-                    }
-                },
-                integrityVerificationFilter,
-                /* broadcastPermission= */ null,
-                mHandler);
     }
 
     @Override
@@ -157,10 +134,4 @@
     public List<String> getWhitelistedRuleProviders() {
         return Collections.emptyList();
     }
-
-    private void handleIntegrityVerification(Intent intent) {
-        int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1);
-        mPackageManagerInternal.setIntegrityVerificationResult(
-                verificationId, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
-    }
 }
diff --git a/services/core/java/com/android/server/pm/PackageHandler.java b/services/core/java/com/android/server/pm/PackageHandler.java
index 0a0882d..4ea4054 100644
--- a/services/core/java/com/android/server/pm/PackageHandler.java
+++ b/services/core/java/com/android/server/pm/PackageHandler.java
@@ -18,7 +18,6 @@
 
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 
-import static com.android.server.pm.PackageManagerService.CHECK_PENDING_INTEGRITY_VERIFICATION;
 import static com.android.server.pm.PackageManagerService.CHECK_PENDING_VERIFICATION;
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
 import static com.android.server.pm.PackageManagerService.DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD;
@@ -29,7 +28,6 @@
 import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_STATUS;
 import static com.android.server.pm.PackageManagerService.ENABLE_ROLLBACK_TIMEOUT;
 import static com.android.server.pm.PackageManagerService.INSTANT_APP_RESOLUTION_PHASE_TWO;
-import static com.android.server.pm.PackageManagerService.INTEGRITY_VERIFICATION_COMPLETE;
 import static com.android.server.pm.PackageManagerService.PACKAGE_VERIFIED;
 import static com.android.server.pm.PackageManagerService.POST_INSTALL;
 import static com.android.server.pm.PackageManagerService.PRUNE_UNUSED_STATIC_SHARED_LIBRARIES;
@@ -149,42 +147,6 @@
 
                 break;
             }
-            case CHECK_PENDING_INTEGRITY_VERIFICATION: {
-                final int verificationId = msg.arg1;
-                final PackageVerificationState state = mPm.mPendingVerification.get(verificationId);
-
-                if (state != null && !state.isIntegrityVerificationComplete()) {
-                    final VerifyingSession verifyingSession = state.getVerifyingSession();
-                    final Uri originUri = Uri.fromFile(verifyingSession.mOriginInfo.mResolvedFile);
-
-                    String errorMsg = "Integrity verification timed out for " + originUri;
-                    Slog.i(TAG, errorMsg);
-
-                    state.setIntegrityVerificationResult(
-                            getDefaultIntegrityVerificationResponse());
-
-                    if (getDefaultIntegrityVerificationResponse()
-                            == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
-                        Slog.i(TAG, "Integrity check times out, continuing with " + originUri);
-                    } else {
-                        verifyingSession.setReturnCode(
-                                PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
-                                errorMsg);
-                    }
-
-                    if (state.areAllVerificationsComplete()) {
-                        mPm.mPendingVerification.remove(verificationId);
-                    }
-
-                    Trace.asyncTraceEnd(
-                            TRACE_TAG_PACKAGE_MANAGER,
-                            "integrity_verification",
-                            verificationId);
-
-                    verifyingSession.handleIntegrityVerificationFinished();
-                }
-                break;
-            }
             case PACKAGE_VERIFIED: {
                 final int verificationId = msg.arg1;
 
@@ -205,42 +167,6 @@
 
                 break;
             }
-            case INTEGRITY_VERIFICATION_COMPLETE: {
-                final int verificationId = msg.arg1;
-
-                final PackageVerificationState state = mPm.mPendingVerification.get(verificationId);
-                if (state == null) {
-                    Slog.w(TAG, "Integrity verification with id " + verificationId
-                            + " not found. It may be invalid or overridden by verifier");
-                    break;
-                }
-
-                final int response = (Integer) msg.obj;
-                final VerifyingSession verifyingSession = state.getVerifyingSession();
-                final Uri originUri = Uri.fromFile(verifyingSession.mOriginInfo.mResolvedFile);
-
-                state.setIntegrityVerificationResult(response);
-
-                if (response == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
-                    Slog.i(TAG, "Integrity check passed for " + originUri);
-                } else {
-                    verifyingSession.setReturnCode(
-                            PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE,
-                            "Integrity check failed for " + originUri);
-                }
-
-                if (state.areAllVerificationsComplete()) {
-                    mPm.mPendingVerification.remove(verificationId);
-                }
-
-                Trace.asyncTraceEnd(
-                        TRACE_TAG_PACKAGE_MANAGER,
-                        "integrity_verification",
-                        verificationId);
-
-                verifyingSession.handleIntegrityVerificationFinished();
-                break;
-            }
             case INSTANT_APP_RESOLUTION_PHASE_TWO: {
                 InstantAppResolver.doInstantAppResolutionPhaseTwo(mPm.mContext,
                         mPm.snapshotComputer(),
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f9c1037..b22bc2b 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -922,8 +922,8 @@
     static final int ENABLE_ROLLBACK_TIMEOUT = 22;
     static final int DEFERRED_NO_KILL_POST_DELETE = 23;
     static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
-    static final int INTEGRITY_VERIFICATION_COMPLETE = 25;
-    static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
+    // static final int UNUSED = 25;
+    // static final int UNUSED = 26;
     static final int DOMAIN_VERIFICATION = 27;
     static final int PRUNE_UNUSED_STATIC_SHARED_LIBRARIES = 28;
     static final int DEFERRED_PENDING_KILL_INSTALL_OBSERVER = 29;
@@ -7023,12 +7023,10 @@
             return mSettings.isPermissionUpgradeNeeded(userId);
         }
 
+        @Deprecated
         @Override
         public void setIntegrityVerificationResult(int verificationId, int verificationResult) {
-            final Message msg = mHandler.obtainMessage(INTEGRITY_VERIFICATION_COMPLETE);
-            msg.arg1 = verificationId;
-            msg.obj = verificationResult;
-            mHandler.sendMessage(msg);
+          // Do nothing.
         }
 
         @Override
diff --git a/services/core/java/com/android/server/pm/PackageVerificationState.java b/services/core/java/com/android/server/pm/PackageVerificationState.java
index 0b6ccc4..63c2ee2 100644
--- a/services/core/java/com/android/server/pm/PackageVerificationState.java
+++ b/services/core/java/com/android/server/pm/PackageVerificationState.java
@@ -43,8 +43,6 @@
 
     private boolean mRequiredVerificationPassed;
 
-    private boolean mIntegrityVerificationComplete;
-
     /**
      * Create a new package verification state where {@code requiredVerifierUid} is the user ID for
      * the package that must reply affirmative before things can continue.
@@ -213,15 +211,7 @@
         return mExtendedTimeoutUids.get(uid, false);
     }
 
-    void setIntegrityVerificationResult(int code) {
-        mIntegrityVerificationComplete = true;
-    }
-
-    boolean isIntegrityVerificationComplete() {
-        return mIntegrityVerificationComplete;
-    }
-
     boolean areAllVerificationsComplete() {
-        return mIntegrityVerificationComplete && isVerificationComplete();
+        return isVerificationComplete();
     }
 }
diff --git a/services/core/java/com/android/server/pm/VerifyingSession.java b/services/core/java/com/android/server/pm/VerifyingSession.java
index f7eb29f..542ae8e 100644
--- a/services/core/java/com/android/server/pm/VerifyingSession.java
+++ b/services/core/java/com/android/server/pm/VerifyingSession.java
@@ -28,7 +28,6 @@
 import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
 import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
 
-import static com.android.server.pm.PackageManagerService.CHECK_PENDING_INTEGRITY_VERIFICATION;
 import static com.android.server.pm.PackageManagerService.CHECK_PENDING_VERIFICATION;
 import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
 import static com.android.server.pm.PackageManagerService.DEBUG_VERIFY;
@@ -87,11 +86,6 @@
      * Whether verification is enabled by default.
      */
     private static final boolean DEFAULT_VERIFY_ENABLE = true;
-
-    /**
-     * Whether integrity verification is enabled by default.
-     */
-    private static final boolean DEFAULT_INTEGRITY_VERIFY_ENABLE = true;
     /**
      * The default maximum time to wait for the integrity verification to return in
      * milliseconds.
@@ -129,7 +123,6 @@
     private final boolean mUserActionRequired;
     private final int mUserActionRequiredType;
     private boolean mWaitForVerificationToComplete;
-    private boolean mWaitForIntegrityVerificationToComplete;
     private boolean mWaitForEnableRollbackToComplete;
     private int mRet = PackageManager.INSTALL_SUCCEEDED;
     private String mErrorMessage = null;
@@ -217,7 +210,6 @@
                 new PackageVerificationState(this);
         mPm.mPendingVerification.append(verificationId, verificationState);
 
-        sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
         sendPackageVerificationRequest(
                 verificationId, pkgLite, verificationState);
 
@@ -270,89 +262,6 @@
         mPm.mHandler.sendMessageDelayed(msg, rollbackTimeout);
     }
 
-    /**
-     * Send a request to check the integrity of the package.
-     */
-    void sendIntegrityVerificationRequest(
-            int verificationId,
-            PackageInfoLite pkgLite,
-            PackageVerificationState verificationState) {
-        if (!isIntegrityVerificationEnabled()) {
-            // Consider the integrity check as passed.
-            verificationState.setIntegrityVerificationResult(
-                    PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
-            return;
-        }
-
-        final Intent integrityVerification =
-                new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
-
-        integrityVerification.setDataAndType(Uri.fromFile(new File(mOriginInfo.mResolvedPath)),
-                PACKAGE_MIME_TYPE);
-
-        final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
-                | Intent.FLAG_RECEIVER_REGISTERED_ONLY
-                | Intent.FLAG_RECEIVER_FOREGROUND;
-        integrityVerification.addFlags(flags);
-
-        integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
-        integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
-        integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
-        integrityVerification.putExtra(EXTRA_LONG_VERSION_CODE, pkgLite.getLongVersionCode());
-        populateInstallerExtras(integrityVerification);
-
-        // send to integrity component only.
-        integrityVerification.setPackage("android");
-
-        final BroadcastOptions options = BroadcastOptions.makeBasic();
-
-        mPm.mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
-                /* receiverPermission= */ null,
-                /* appOp= */ AppOpsManager.OP_NONE,
-                /* options= */ options.toBundle(),
-                new BroadcastReceiver() {
-                    @Override
-                    public void onReceive(Context context, Intent intent) {
-                        final Message msg =
-                                mPm.mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
-                        msg.arg1 = verificationId;
-                        mPm.mHandler.sendMessageDelayed(msg, getIntegrityVerificationTimeout());
-                    }
-                }, /* scheduler= */ null,
-                /* initialCode= */ 0,
-                /* initialData= */ null,
-                /* initialExtras= */ null);
-
-        Trace.asyncTraceBegin(
-                TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);
-
-        // stop the copy until verification succeeds.
-        mWaitForIntegrityVerificationToComplete = true;
-    }
-
-
-    /**
-     * Get the integrity verification timeout.
-     *
-     * @return verification timeout in milliseconds
-     */
-    private long getIntegrityVerificationTimeout() {
-        long timeout = Settings.Global.getLong(mPm.mContext.getContentResolver(),
-                Settings.Global.APP_INTEGRITY_VERIFICATION_TIMEOUT,
-                DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
-        // The setting can be used to increase the timeout but not decrease it, since that is
-        // equivalent to disabling the integrity component.
-        return Math.max(timeout, DEFAULT_INTEGRITY_VERIFICATION_TIMEOUT);
-    }
-
-    /**
-     * Check whether or not integrity verification has been enabled.
-     */
-    private boolean isIntegrityVerificationEnabled() {
-        // We are not exposing this as a user-configurable setting because we don't want to provide
-        // an easy way to get around the integrity check.
-        return DEFAULT_INTEGRITY_VERIFY_ENABLE;
-    }
 
     /**
      * Send a request to verifier(s) to verify the package if necessary.
@@ -827,11 +736,6 @@
         handleReturnCode();
     }
 
-    void handleIntegrityVerificationFinished() {
-        mWaitForIntegrityVerificationToComplete = false;
-        handleReturnCode();
-    }
-
     void handleRollbackEnabled() {
         // TODO(b/112431924): Consider halting the install if we
         // couldn't enable rollback.
@@ -840,7 +744,7 @@
     }
 
     void handleReturnCode() {
-        if (mWaitForVerificationToComplete || mWaitForIntegrityVerificationToComplete
+        if (mWaitForVerificationToComplete
                 || mWaitForEnableRollbackToComplete) {
             return;
         }
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index e49dc82..976999c 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -426,6 +426,7 @@
     private static final int TRON_COMPILATION_REASON_PREBUILT = 23;
     private static final int TRON_COMPILATION_REASON_VDEX = 24;
     private static final int TRON_COMPILATION_REASON_BOOT_AFTER_MAINLINE_UPDATE = 25;
+    private static final int TRON_COMPILATION_REASON_CLOUD = 26;
 
     // The annotation to add as a suffix to the compilation reason when dexopt was
     // performed with dex metadata.
@@ -460,6 +461,8 @@
                 return TRON_COMPILATION_REASON_INSTALL_BULK_DOWNGRADED;
             case "install-bulk-secondary-downgraded" :
                 return TRON_COMPILATION_REASON_INSTALL_BULK_SECONDARY_DOWNGRADED;
+            case "cloud":
+                return TRON_COMPILATION_REASON_CLOUD;
             // These are special markers for dex metadata installation that do not
             // have an equivalent as a system property.
             case "install" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION :
diff --git a/services/core/java/com/android/server/vcn/TEST_MAPPING b/services/core/java/com/android/server/vcn/TEST_MAPPING
deleted file mode 100644
index 5b04d88..0000000
--- a/services/core/java/com/android/server/vcn/TEST_MAPPING
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "FrameworksVcnTests"
-    },
-    {
-      "name": "CtsVcnTestCases"
-    }
-  ]
-}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 227b6b4..a0dca94 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -31,6 +31,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.IActivityManager;
 import android.app.SynchronousUserSwitchObserver;
 import android.app.UidObserver;
 import android.content.BroadcastReceiver;
@@ -73,6 +74,7 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /** Controls all the system settings related to vibration. */
@@ -146,9 +148,6 @@
                     PowerManager.GO_TO_SLEEP_REASON_INATTENTIVE,
                     PowerManager.GO_TO_SLEEP_REASON_TIMEOUT));
 
-    private static final IntentFilter INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER =
-            new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
-
     /** Listener for changes on vibration settings. */
     interface OnVibratorSettingsChanged {
         /** Callback triggered when any of the vibrator settings change. */
@@ -157,15 +156,18 @@
 
     private final Object mLock = new Object();
     private final Context mContext;
-    private final String mSystemUiPackage;
     @VisibleForTesting
     final SettingsContentObserver mSettingObserver;
     @VisibleForTesting
-    final SettingsBroadcastReceiver mSettingChangeReceiver;
+    final RingerModeBroadcastReceiver mRingerModeBroadcastReceiver;
+    @VisibleForTesting
+    final BatteryBroadcastReceiver mBatteryBroadcastReceiver;
     @VisibleForTesting
     final VibrationUidObserver mUidObserver;
     @VisibleForTesting
     final VibrationUserSwitchObserver mUserSwitchObserver;
+    @VisibleForTesting
+    final VibrationLowPowerModeListener mLowPowerModeListener;
 
     @GuardedBy("mLock")
     private final List<OnVibratorSettingsChanged> mListeners = new ArrayList<>();
@@ -179,10 +181,13 @@
     @GuardedBy("mLock")
     @Nullable
     private PowerManagerInternal mPowerManagerInternal;
+    @GuardedBy("mLock")
     @Nullable
     private VirtualDeviceManagerInternal mVirtualDeviceManagerInternal;
 
     @GuardedBy("mLock")
+    private String mSystemUiPackage;
+    @GuardedBy("mLock")
     private boolean mVibrateInputDevices;
     @GuardedBy("mLock")
     private SparseIntArray mCurrentVibrationIntensities = new SparseIntArray();
@@ -206,11 +211,11 @@
         mContext = context;
         mVibrationConfig = config;
         mSettingObserver = new SettingsContentObserver(handler);
-        mSettingChangeReceiver = new SettingsBroadcastReceiver();
+        mRingerModeBroadcastReceiver = new RingerModeBroadcastReceiver();
+        mBatteryBroadcastReceiver = new BatteryBroadcastReceiver();
         mUidObserver = new VibrationUidObserver();
         mUserSwitchObserver = new VibrationUserSwitchObserver();
-        mSystemUiPackage = LocalServices.getService(PackageManagerInternal.class)
-                .getSystemUiServiceComponent().getPackageName();
+        mLowPowerModeListener = new VibrationLowPowerModeListener();
 
         VibrationEffect clickEffect = createEffectFromResource(
                 com.android.internal.R.array.config_virtualKeyVibePattern);
@@ -234,18 +239,34 @@
     }
 
     public void onSystemReady() {
-        PowerManagerInternal pm = LocalServices.getService(PowerManagerInternal.class);
-        AudioManager am = mContext.getSystemService(AudioManager.class);
-        int ringerMode = (am == null) ? mRingerMode : am.getRingerModeInternal();
+        onSystemReady(LocalServices.getService(PackageManagerInternal.class),
+                LocalServices.getService(PowerManagerInternal.class),
+                ActivityManager.getService(),
+                LocalServices.getService(VirtualDeviceManagerInternal.class),
+                mContext.getSystemService(AudioManager.class));
+    }
+
+    @VisibleForTesting
+    void onSystemReady(PackageManagerInternal packageManagerInternal,
+            PowerManagerInternal powerManagerInternal,
+            IActivityManager activityManagerInternal,
+            @Nullable VirtualDeviceManagerInternal virtualDeviceManagerInternal,
+            @Nullable AudioManager audioManager) {
+        int ringerMode = (audioManager == null)
+                ? AudioManager.RINGER_MODE_NORMAL
+                : audioManager.getRingerModeInternal();
+        String sysUiPackage = packageManagerInternal.getSystemUiServiceComponent().getPackageName();
 
         synchronized (mLock) {
-            mPowerManagerInternal = pm;
-            mAudioManager = am;
+            mPowerManagerInternal = powerManagerInternal;
+            mVirtualDeviceManagerInternal = virtualDeviceManagerInternal;
+            mAudioManager = audioManager;
             mRingerMode = ringerMode;
+            mSystemUiPackage = sysUiPackage;
         }
 
         try {
-            ActivityManager.getService().registerUidObserver(mUidObserver,
+            activityManagerInternal.registerUidObserver(mUidObserver,
                     ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
                     ActivityManager.PROCESS_STATE_UNKNOWN, /* callingPackage= */ null);
         } catch (RemoteException e) {
@@ -253,32 +274,16 @@
         }
 
         try {
-            ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
+            activityManagerInternal.registerUserSwitchObserver(mUserSwitchObserver, TAG);
         } catch (RemoteException e) {
             // ignored; both services live in system_server
         }
 
-        pm.registerLowPowerModeObserver(
-                new PowerManagerInternal.LowPowerModeListener() {
-                    @Override
-                    public int getServiceType() {
-                        return PowerManager.ServiceType.VIBRATION;
-                    }
+        powerManagerInternal.registerLowPowerModeObserver(mLowPowerModeListener);
 
-                    @Override
-                    public void onLowPowerModeChanged(PowerSaveState result) {
-                        boolean shouldNotifyListeners;
-                        synchronized (mLock) {
-                            shouldNotifyListeners = result.batterySaverEnabled != mBatterySaverMode;
-                            mBatterySaverMode = result.batterySaverEnabled;
-                        }
-                        if (shouldNotifyListeners) {
-                            notifyListeners();
-                        }
-                    }
-                });
-
-        registerSettingsChangeReceiver(INTERNAL_RINGER_MODE_CHANGED_INTENT_FILTER);
+        mContext.registerReceiver(mRingerModeBroadcastReceiver,
+                new IntentFilter(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION),
+                Context.RECEIVER_EXPORTED_UNAUDITED);
 
         // Listen to all settings that might affect the result of Vibrator.getVibrationIntensity.
         registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
@@ -302,12 +307,7 @@
 
         if (mVibrationConfig.ignoreVibrationsOnWirelessCharger()) {
             Intent batteryStatus = mContext.registerReceiver(
-                    new BroadcastReceiver() {
-                        @Override
-                        public void onReceive(Context context, Intent intent) {
-                            updateBatteryInfo(intent);
-                        }
-                    },
+                    mBatteryBroadcastReceiver,
                     new IntentFilter(Intent.ACTION_BATTERY_CHANGED),
                     Context.RECEIVER_NOT_EXPORTED);
             // After registering the receiver for battery status, process the sticky broadcast that
@@ -477,8 +477,10 @@
     public boolean shouldCancelVibrationOnScreenOff(@NonNull Vibration.CallerInfo callerInfo,
             long vibrationStartUptimeMillis) {
         PowerManagerInternal pm;
+        String sysUiPackageName;
         synchronized (mLock) {
             pm = mPowerManagerInternal;
+            sysUiPackageName = mSystemUiPackage;
         }
         if (pm != null) {
             // The SleepData from PowerManager may refer to a more recent sleep than the broadcast
@@ -502,7 +504,7 @@
         }
         // Only allow vibrations from System packages to continue vibrating when the screen goes off
         return callerInfo.uid != Process.SYSTEM_UID && callerInfo.uid != 0
-                && !mSystemUiPackage.equals(callerInfo.opPkg);
+                && !Objects.equals(sysUiPackageName, callerInfo.opPkg);
     }
 
     /**
@@ -785,11 +787,6 @@
                 UserHandle.USER_ALL);
     }
 
-    private void registerSettingsChangeReceiver(IntentFilter intentFilter) {
-        mContext.registerReceiver(mSettingChangeReceiver, intentFilter,
-                Context.RECEIVER_EXPORTED_UNAUDITED);
-    }
-
     @Nullable
     private VibrationEffect createEffectFromResource(int resId) {
         return createEffectFromResource(mContext.getResources(), resId);
@@ -836,12 +833,11 @@
     }
 
     private boolean isAppRunningOnAnyVirtualDevice(int uid) {
-        if (mVirtualDeviceManagerInternal == null) {
-            mVirtualDeviceManagerInternal =
-                    LocalServices.getService(VirtualDeviceManagerInternal.class);
+        VirtualDeviceManagerInternal vdm;
+        synchronized (mLock) {
+            vdm = mVirtualDeviceManagerInternal;
         }
-        return mVirtualDeviceManagerInternal != null
-                && mVirtualDeviceManagerInternal.isAppRunningOnAnyVirtualDevice(uid);
+        return vdm != null && vdm.isAppRunningOnAnyVirtualDevice(uid);
     }
 
     /** Implementation of {@link ContentObserver} to be registered to a setting {@link Uri}. */
@@ -860,7 +856,7 @@
 
     /** Implementation of {@link BroadcastReceiver} to update on ringer mode change. */
     @VisibleForTesting
-    final class SettingsBroadcastReceiver extends BroadcastReceiver {
+    final class RingerModeBroadcastReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
@@ -871,6 +867,18 @@
         }
     }
 
+    /** Implementation of {@link BroadcastReceiver} to update on battery mode change. */
+    @VisibleForTesting
+    final class BatteryBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+                updateBatteryInfo(intent);
+            }
+        }
+    }
+
     /** Implementation of {@link ContentObserver} to be registered to a setting {@link Uri}. */
     @VisibleForTesting
     final class VibrationUidObserver extends UidObserver {
@@ -916,4 +924,25 @@
             update();
         }
     }
+
+    /** Implementation of {@link PowerManagerInternal.LowPowerModeListener} for low battery. */
+    @VisibleForTesting
+    final class VibrationLowPowerModeListener implements PowerManagerInternal.LowPowerModeListener {
+        @Override
+        public int getServiceType() {
+            return PowerManager.ServiceType.VIBRATION;
+        }
+
+        @Override
+        public void onLowPowerModeChanged(PowerSaveState result) {
+            boolean shouldNotifyListeners;
+            synchronized (mLock) {
+                shouldNotifyListeners = result.batterySaverEnabled != mBatterySaverMode;
+                mBatterySaverMode = result.batterySaverEnabled;
+            }
+            if (shouldNotifyListeners) {
+                notifyListeners();
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 84df11a..9ff9e34 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1337,7 +1337,16 @@
         // Commit wallpaper visibility after activity, because usually the wallpaper target token is
         // an activity, and wallpaper's visibility depends on activity's visibility.
         for (int i = mParticipants.size() - 1; i >= 0; --i) {
-            final WallpaperWindowToken wt = mParticipants.valueAt(i).asWallpaperToken();
+            final WindowContainer<?> wc = mParticipants.valueAt(i);
+            WallpaperWindowToken wt = wc.asWallpaperToken();
+            if (!Flags.ensureWallpaperInTransitions()) {
+                if (wt == null) {
+                    final WindowState windowState = wc.asWindowState();
+                    if (windowState != null) {
+                        wt = windowState.mToken.asWallpaperToken();
+                    }
+                }
+            }
             if (wt == null) continue;
             final WindowState target = wt.mDisplayContent.mWallpaperController.getWallpaperTarget();
             final boolean isTargetInvisible = target == null || !target.mToken.isVisible();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index fc7d3dc..673d82d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2728,7 +2728,7 @@
      * Expands the given rectangle by the region of window resize handle for freeform window.
      * @param inOutRect The rectangle to update.
      */
-    private void adjustRegionInFreefromWindowMode(Rect inOutRect) {
+    private void adjustRegionInFreeformWindowMode(Rect inOutRect) {
         if (!inFreeformWindowingMode()) {
             return;
         }
@@ -2772,7 +2772,7 @@
                 }
             }
         }
-        adjustRegionInFreefromWindowMode(mTmpRect);
+        adjustRegionInFreeformWindowMode(mTmpRect);
         outRegion.set(mTmpRect);
         cropRegionToRootTaskBoundsIfNeeded(outRegion);
     }
@@ -3546,7 +3546,7 @@
         }
 
         rootTask.getDimBounds(mTmpRect);
-        adjustRegionInFreefromWindowMode(mTmpRect);
+        adjustRegionInFreeformWindowMode(mTmpRect);
         region.op(mTmpRect, Region.Op.INTERSECT);
     }
 
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 688312e..0718f04 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -411,6 +411,8 @@
             "/apex/com.android.tethering/javalib/service-connectivity.jar";
     private static final String CONNECTIVITY_SERVICE_INITIALIZER_CLASS =
             "com.android.server.ConnectivityServiceInitializer";
+    private static final String CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS =
+            "com.android.server.ConnectivityServiceInitializerB";
     private static final String NETWORK_STATS_SERVICE_INITIALIZER_CLASS =
             "com.android.server.NetworkStatsServiceInitializer";
     private static final String UWB_APEX_SERVICE_JAR_PATH =
@@ -1447,7 +1449,6 @@
         IStorageManager storageManager = null;
         NetworkManagementService networkManagement = null;
         VpnManagerService vpnManager = null;
-        VcnManagementService vcnManagement = null;
         NetworkPolicyManagerService networkPolicy = null;
         WindowManagerService wm = null;
         NetworkTimeUpdateService networkTimeUpdater = null;
@@ -2145,8 +2146,10 @@
 
             t.traceBegin("StartVcnManagementService");
             try {
-                vcnManagement = VcnManagementService.create(context);
-                ServiceManager.addService(Context.VCN_MANAGEMENT_SERVICE, vcnManagement);
+                // TODO: b/375213246 When VCN is in mainline module, load it from the apex path.
+                // Whether VCN will be in apex or in the platform will be gated by a build system
+                // flag.
+                mSystemServiceManager.startService(CONNECTIVITY_SERVICE_INITIALIZER_B_CLASS);
             } catch (Throwable e) {
                 reportWtf("starting VCN Management Service", e);
             }
@@ -3038,7 +3041,6 @@
         final MediaRouterService mediaRouterF = mediaRouter;
         final MmsServiceBroker mmsServiceF = mmsService;
         final VpnManagerService vpnManagerF = vpnManager;
-        final VcnManagementService vcnManagementF = vcnManagement;
         final WindowManagerService windowManagerF = wm;
         final ConnectivityManager connectivityF = (ConnectivityManager)
                 context.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -3165,15 +3167,6 @@
                 reportWtf("making VpnManagerService ready", e);
             }
             t.traceEnd();
-            t.traceBegin("MakeVcnManagementServiceReady");
-            try {
-                if (vcnManagementF != null) {
-                    vcnManagementF.systemReady();
-                }
-            } catch (Throwable e) {
-                reportWtf("making VcnManagementService ready", e);
-            }
-            t.traceEnd();
             t.traceBegin("MakeNetworkPolicyServiceReady");
             try {
                 if (networkPolicyF != null) {
diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageVerificationStateTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageVerificationStateTest.java
index a93e8ad..97f1bd4 100644
--- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageVerificationStateTest.java
+++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/PackageVerificationStateTest.java
@@ -574,57 +574,16 @@
         assertTrue(state.isInstallAllowed());
     }
 
-    public void testAreAllVerificationsComplete_onlyVerificationPasses() {
+    public void testAreAllVerificationsComplete() {
         PackageVerificationState state = new PackageVerificationState(null);
         state.addRequiredVerifierUid(REQUIRED_UID_1);
         assertFalse(state.areAllVerificationsComplete());
 
         state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_ALLOW);
 
-        assertFalse(state.areAllVerificationsComplete());
-    }
-
-    public void testAreAllVerificationsComplete_onlyIntegrityCheckPasses() {
-        PackageVerificationState state = new PackageVerificationState(null);
-        state.addRequiredVerifierUid(REQUIRED_UID_1);
-        assertFalse(state.areAllVerificationsComplete());
-
-        state.setIntegrityVerificationResult(PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
-
-        assertFalse(state.areAllVerificationsComplete());
-    }
-
-    public void testAreAllVerificationsComplete_bothPasses() {
-        PackageVerificationState state = new PackageVerificationState(null);
-        state.addRequiredVerifierUid(REQUIRED_UID_1);
-        assertFalse(state.areAllVerificationsComplete());
-
-        state.setIntegrityVerificationResult(PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
-        state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_ALLOW);
-
         assertTrue(state.areAllVerificationsComplete());
     }
 
-    public void testAreAllVerificationsComplete_onlyVerificationFails() {
-        PackageVerificationState state = new PackageVerificationState(null);
-        state.addRequiredVerifierUid(REQUIRED_UID_1);
-        assertFalse(state.areAllVerificationsComplete());
-
-        state.setVerifierResponse(REQUIRED_UID_1, PackageManager.VERIFICATION_REJECT);
-
-        assertFalse(state.areAllVerificationsComplete());
-    }
-
-    public void testAreAllVerificationsComplete_onlyIntegrityCheckFails() {
-        PackageVerificationState state = new PackageVerificationState(null);
-        state.addRequiredVerifierUid(REQUIRED_UID_1);
-        assertFalse(state.areAllVerificationsComplete());
-
-        state.setIntegrityVerificationResult(PackageManagerInternal.INTEGRITY_VERIFICATION_REJECT);
-
-        assertFalse(state.areAllVerificationsComplete());
-    }
-
     private void processOnTimeout(PackageVerificationState state, int code, int uid) {
         // CHECK_PENDING_VERIFICATION handler.
         assertFalse("Verification should not be marked as complete yet",
diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
deleted file mode 100644
index fd22118..0000000
--- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (C) 2019 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.integrity;
-
-import static android.content.integrity.AppIntegrityManager.EXTRA_STATUS;
-import static android.content.integrity.AppIntegrityManager.STATUS_FAILURE;
-import static android.content.integrity.AppIntegrityManager.STATUS_SUCCESS;
-import static android.content.integrity.InstallerAllowedByManifestFormula.INSTALLER_CERTIFICATE_NOT_EVALUATED;
-import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
-import static android.content.pm.PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE;
-import static android.content.pm.PackageManager.EXTRA_VERIFICATION_INSTALLER_UID;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.integrity.AppInstallMetadata;
-import android.content.integrity.AtomicFormula;
-import android.content.integrity.IntegrityFormula;
-import android.content.integrity.Rule;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
-import android.content.pm.ParceledListSlice;
-import android.content.res.Resources;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.Settings;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.R;
-import com.android.server.compat.PlatformCompat;
-import com.android.server.testutils.TestUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
-
-/** Unit test for {@link com.android.server.integrity.AppIntegrityManagerServiceImpl} */
-@RunWith(JUnit4.class)
-public class AppIntegrityManagerServiceImplTest {
-    private static final String TEST_APP_PATH =
-            "AppIntegrityManagerServiceImplTest/AppIntegrityManagerServiceTestApp.apk";
-
-    private static final String TEST_APP_TWO_CERT_PATH =
-            "AppIntegrityManagerServiceImplTest/DummyAppTwoCerts.apk";
-
-    private static final String TEST_APP_SOURCE_STAMP_PATH =
-            "AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk";
-
-    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
-    private static final String VERSION = "version";
-    private static final String TEST_FRAMEWORK_PACKAGE = "com.android.frameworks.servicestests";
-
-    private static final String PACKAGE_NAME = "com.test.app";
-
-    private static final long VERSION_CODE = 100;
-    private static final String INSTALLER = "com.long.random.test.installer.name";
-
-    // These are obtained by running the test and checking logcat.
-    private static final String APP_CERT =
-            "F14CFECF5070874C05D3D2FA98E046BE20BDE02A0DC74BAF6B59C6A0E4C06850";
-    // We use SHA256 for package names longer than 32 characters.
-    private static final String INSTALLER_SHA256 =
-            "30F41A7CBF96EE736A54DD6DF759B50ED3CC126ABCEF694E167C324F5976C227";
-    private static final String SOURCE_STAMP_CERTIFICATE_HASH =
-            "C6E737809CEF2B08CC6694892215F82A5E8FBC3C2A0F6212770310B90622D2D9";
-
-    private static final String DUMMY_APP_TWO_CERTS_CERT_1 =
-            "C0369C2A1096632429DFA8433068AECEAD00BAC337CA92A175036D39CC9AFE94";
-    private static final String DUMMY_APP_TWO_CERTS_CERT_2 =
-            "94366E0A80F3A3F0D8171A15760B88E228CD6E1101F0414C98878724FBE70147";
-
-    private static final String PLAY_STORE_PKG = "com.android.vending";
-    private static final String ADB_INSTALLER = "adb";
-    private static final String PLAY_STORE_CERT = "play_store_cert";
-
-    @org.junit.Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
-
-    @Mock PackageManagerInternal mPackageManagerInternal;
-    @Mock PlatformCompat mPlatformCompat;
-    @Mock Context mMockContext;
-    @Mock Resources mMockResources;
-    @Mock Handler mHandler;
-
-    private final Context mRealContext = InstrumentationRegistry.getTargetContext();
-
-    private PackageManager mSpyPackageManager;
-    private File mTestApk;
-    private File mTestApkTwoCerts;
-    private File mTestApkSourceStamp;
-
-    // under test
-    private AppIntegrityManagerServiceImpl mService;
-
-    @Before
-    public void setup() throws Exception {
-        mTestApk = File.createTempFile("AppIntegrity", ".apk");
-        try (InputStream inputStream = mRealContext.getAssets().open(TEST_APP_PATH)) {
-            Files.copy(inputStream, mTestApk.toPath(), REPLACE_EXISTING);
-        }
-
-        mTestApkTwoCerts = File.createTempFile("AppIntegrityTwoCerts", ".apk");
-        try (InputStream inputStream = mRealContext.getAssets().open(TEST_APP_TWO_CERT_PATH)) {
-            Files.copy(inputStream, mTestApkTwoCerts.toPath(), REPLACE_EXISTING);
-        }
-
-        mTestApkSourceStamp = File.createTempFile("AppIntegritySourceStamp", ".apk");
-        try (InputStream inputStream = mRealContext.getAssets().open(TEST_APP_SOURCE_STAMP_PATH)) {
-            Files.copy(inputStream, mTestApkSourceStamp.toPath(), REPLACE_EXISTING);
-        }
-
-        mService =
-                new AppIntegrityManagerServiceImpl(
-                        mMockContext,
-                        mPackageManagerInternal,
-                        mHandler);
-
-        mSpyPackageManager = spy(mRealContext.getPackageManager());
-        // setup mocks to prevent NPE
-        when(mMockContext.getPackageManager()).thenReturn(mSpyPackageManager);
-        when(mMockContext.getResources()).thenReturn(mMockResources);
-        when(mMockResources.getStringArray(anyInt())).thenReturn(new String[] {});
-        // These are needed to override the Settings.Global.get result.
-        when(mMockContext.getContentResolver()).thenReturn(mRealContext.getContentResolver());
-        setIntegrityCheckIncludesRuleProvider(true);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mTestApk.delete();
-        mTestApkTwoCerts.delete();
-        mTestApkSourceStamp.delete();
-    }
-
-    @Test
-    public void broadcastReceiverRegistration() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-        ArgumentCaptor<IntentFilter> intentFilterCaptor =
-                ArgumentCaptor.forClass(IntentFilter.class);
-
-        verify(mMockContext).registerReceiver(any(), intentFilterCaptor.capture(), any(), any());
-        assertEquals(1, intentFilterCaptor.getValue().countActions());
-        assertEquals(
-                Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION,
-                intentFilterCaptor.getValue().getAction(0));
-        assertEquals(1, intentFilterCaptor.getValue().countDataTypes());
-        assertEquals(PACKAGE_MIME_TYPE, intentFilterCaptor.getValue().getDataType(0));
-    }
-
-    @Test
-    public void handleBroadcast_allow() throws Exception {
-        allowlistUsAsRuleProvider();
-        makeUsSystemApp();
-        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mMockContext)
-                .registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
-        Intent intent = makeVerificationIntent();
-
-        broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
-        runJobInHandler();
-
-        verify(mPackageManagerInternal)
-                .setIntegrityVerificationResult(
-                        1, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
-    }
-
-    private void allowlistUsAsRuleProvider() {
-        Resources mockResources = mock(Resources.class);
-        when(mockResources.getStringArray(R.array.config_integrityRuleProviderPackages))
-                .thenReturn(new String[] {TEST_FRAMEWORK_PACKAGE});
-        when(mMockContext.getResources()).thenReturn(mockResources);
-    }
-
-    private void runJobInHandler() {
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-        // sendMessageAtTime is the first non-final method in the call chain when "post" is invoked.
-        verify(mHandler).sendMessageAtTime(messageCaptor.capture(), anyLong());
-        messageCaptor.getValue().getCallback().run();
-    }
-
-    private void makeUsSystemApp() throws Exception {
-        makeUsSystemApp(true);
-    }
-
-    private void makeUsSystemApp(boolean isSystemApp) throws Exception {
-        PackageInfo packageInfo =
-                mRealContext.getPackageManager().getPackageInfo(TEST_FRAMEWORK_PACKAGE, 0);
-        if (isSystemApp) {
-            packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
-        } else {
-            packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
-        }
-        doReturn(packageInfo)
-                .when(mSpyPackageManager)
-                .getPackageInfo(eq(TEST_FRAMEWORK_PACKAGE), anyInt());
-        when(mMockContext.getPackageManager()).thenReturn(mSpyPackageManager);
-    }
-
-    private Intent makeVerificationIntent() throws Exception {
-        PackageInfo packageInfo =
-                mRealContext
-                        .getPackageManager()
-                        .getPackageInfo(
-                                TEST_FRAMEWORK_PACKAGE, PackageManager.GET_SIGNING_CERTIFICATES);
-        doReturn(packageInfo).when(mSpyPackageManager).getPackageInfo(eq(INSTALLER), anyInt());
-        doReturn(1).when(mSpyPackageManager).getPackageUid(eq(INSTALLER), anyInt());
-        doReturn(new String[]{INSTALLER}).when(mSpyPackageManager).getPackagesForUid(anyInt());
-        return makeVerificationIntent(INSTALLER);
-    }
-
-    private Intent makeVerificationIntent(String installer) throws Exception {
-        Intent intent = new Intent();
-        intent.setDataAndType(Uri.fromFile(mTestApk), PACKAGE_MIME_TYPE);
-        intent.setAction(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
-        intent.putExtra(EXTRA_VERIFICATION_ID, 1);
-        intent.putExtra(Intent.EXTRA_PACKAGE_NAME, PACKAGE_NAME);
-        intent.putExtra(EXTRA_VERIFICATION_INSTALLER_PACKAGE, installer);
-        intent.putExtra(
-                EXTRA_VERIFICATION_INSTALLER_UID,
-                mMockContext.getPackageManager().getPackageUid(installer, /* flags= */ 0));
-        intent.putExtra(Intent.EXTRA_LONG_VERSION_CODE, VERSION_CODE);
-        return intent;
-    }
-
-    private void setIntegrityCheckIncludesRuleProvider(boolean shouldInclude) throws Exception {
-        int value = shouldInclude ? 1 : 0;
-        Settings.Global.putInt(
-                mRealContext.getContentResolver(),
-                Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER,
-                value);
-        assertThat(
-                        Settings.Global.getInt(
-                                        mRealContext.getContentResolver(),
-                                        Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER,
-                                        -1)
-                                == 1)
-                .isEqualTo(shouldInclude);
-    }
-}
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
index 21604df..0f20178 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -43,7 +43,8 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -51,12 +52,14 @@
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
+import android.app.IActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.PackageManagerInternal;
 import android.media.AudioManager;
 import android.os.Handler;
@@ -80,10 +83,8 @@
 
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.internal.util.test.FakeSettingsProviderRule;
-import com.android.server.LocalServices;
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -100,8 +101,7 @@
     @Rule
     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
-    private static final int OLD_USER_ID = 123;
-    private static final int NEW_USER_ID = 456;
+    private static final int USER_ID = 123;
     private static final int UID = 1;
     private static final int VIRTUAL_DEVICE_ID = 1;
     private static final String SYSUI_PACKAGE_NAME = "sysui";
@@ -130,13 +130,12 @@
     @Mock private VirtualDeviceManagerInternal mVirtualDeviceManagerInternalMock;
     @Mock private PackageManagerInternal mPackageManagerInternalMock;
     @Mock private AudioManager mAudioManagerMock;
+    @Mock private IActivityManager mActivityManagerMock;
     @Mock private VibrationConfig mVibrationConfigMock;
 
     private TestLooper mTestLooper;
     private ContextWrapper mContextSpy;
     private VibrationSettings mVibrationSettings;
-    private PowerManagerInternal.LowPowerModeListener mRegisteredPowerModeListener;
-    private BroadcastReceiver mRegisteredBatteryBroadcastReceiver;
 
     @Before
     public void setUp() throws Exception {
@@ -144,24 +143,20 @@
         mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
 
         ContentResolver contentResolver = mSettingsProviderRule.mockContentResolver(mContextSpy);
-        when(mContextSpy.getContentResolver()).thenReturn(contentResolver);
-        when(mContextSpy.getSystemService(eq(Context.AUDIO_SERVICE))).thenReturn(mAudioManagerMock);
-        doAnswer(invocation -> {
-            mRegisteredPowerModeListener = invocation.getArgument(0);
-            return null;
-        }).when(mPowerManagerInternalMock).registerLowPowerModeObserver(any());
+        doReturn(contentResolver).when(mContextSpy).getContentResolver();
+
+        // Make sure broadcast receivers are not registered for this test, to avoid flakes.
+        doReturn(null).when(mContextSpy)
+                .registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class), anyInt());
         when(mPackageManagerInternalMock.getSystemUiServiceComponent())
                 .thenReturn(new ComponentName(SYSUI_PACKAGE_NAME, ""));
 
-        removeServicesForTest();
-        addServicesForTest();
-
         setDefaultIntensity(VIBRATION_INTENSITY_MEDIUM);
 
         setIgnoreVibrationsOnWirelessCharger(false);
-        createSystemReadyVibrationSettings();
 
         mockGoToSleep(/* goToSleepTime= */ 0, PowerManager.GO_TO_SLEEP_REASON_TIMEOUT);
+        createSystemReadyVibrationSettings();
     }
 
     private void createSystemReadyVibrationSettings() {
@@ -175,38 +170,18 @@
         setUserSetting(Settings.System.APPLY_RAMPING_RINGER, 0);
         setRingerMode(AudioManager.RINGER_MODE_NORMAL);
 
-        mVibrationSettings.onSystemReady();
-    }
-
-    private void removeServicesForTest() {
-        LocalServices.removeServiceForTest(PowerManagerInternal.class);
-        LocalServices.removeServiceForTest(PackageManagerInternal.class);
-        LocalServices.removeServiceForTest(VirtualDeviceManagerInternal.class);
-    }
-
-    private void addServicesForTest() {
-        LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
-        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
-        LocalServices.addService(VirtualDeviceManagerInternal.class,
-                mVirtualDeviceManagerInternalMock);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        removeServicesForTest();
+        mVibrationSettings.onSystemReady(mPackageManagerInternalMock, mPowerManagerInternalMock,
+                mActivityManagerMock, mVirtualDeviceManagerInternalMock, mAudioManagerMock);
     }
 
     @Test
     public void create_withOnlyRequiredSystemServices() {
-        // The only core services that we depend on are PowerManager and PackageManager
-        removeServicesForTest();
-        LocalServices.addService(PowerManagerInternal.class, mPowerManagerInternalMock);
-        LocalServices.addService(PackageManagerInternal.class, mPackageManagerInternalMock);
-        when(mContextSpy.getSystemService(eq(Context.AUDIO_SERVICE))).thenReturn(null);
-
         VibrationSettings minimalVibrationSettings = new VibrationSettings(mContextSpy,
                 new Handler(mTestLooper.getLooper()), mVibrationConfigMock);
-        minimalVibrationSettings.onSystemReady();
+
+        // The only core services that we depend on are Power, Package and Activity managers
+        minimalVibrationSettings.onSystemReady(mPackageManagerInternalMock,
+                mPowerManagerInternalMock, mActivityManagerMock, null, null);
     }
 
     @Test
@@ -214,8 +189,8 @@
         mVibrationSettings.addListener(mListenerMock);
 
         // Testing the broadcast flow manually.
-        mVibrationSettings.mUserSwitchObserver.onUserSwitching(NEW_USER_ID);
-        mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(NEW_USER_ID);
+        mVibrationSettings.mUserSwitchObserver.onUserSwitching(USER_ID);
+        mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(USER_ID);
 
         verify(mListenerMock, times(2)).onChange();
     }
@@ -225,9 +200,9 @@
         mVibrationSettings.addListener(mListenerMock);
 
         // Testing the broadcast flow manually.
-        mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+        mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
                 new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
-        mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+        mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
                 new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
 
         verify(mListenerMock, times(2)).onChange();
@@ -249,9 +224,9 @@
         mVibrationSettings.addListener(mListenerMock);
 
         // Testing the broadcast flow manually.
-        mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
-        mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
-        mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE); // No change.
+        mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
+        mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
+        mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE); // Noop.
 
         verify(mListenerMock, times(2)).onChange();
     }
@@ -266,10 +241,9 @@
         mVibrationSettings.removeListener(mListenerMock);
 
         // Trigger multiple observers manually.
-        mVibrationSettings.mSettingObserver.onChange(false);
-        mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
-        mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(NEW_USER_ID);
-        mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+        mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
+        mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(USER_ID);
+        mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
                 new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
 
         verifyNoMoreInteractions(mListenerMock);
@@ -310,11 +284,12 @@
 
     @Test
     public void wirelessChargingVibrationsEnabled_doesNotRegisterBatteryReceiver_allowsAnyUsage() {
-        setBatteryReceiverRegistrationResult(getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS));
         setIgnoreVibrationsOnWirelessCharger(false);
         createSystemReadyVibrationSettings();
 
-        assertNull(mRegisteredBatteryBroadcastReceiver);
+        verify(mContextSpy, never()).registerReceiver(any(BroadcastReceiver.class),
+                argThat(filter -> filter.matchAction(Intent.ACTION_BATTERY_CHANGED)), anyInt());
+
         for (int usage : ALL_USAGES) {
             assertVibrationNotIgnoredForUsage(usage);
         }
@@ -322,7 +297,6 @@
 
     @Test
     public void shouldIgnoreVibration_noBatteryIntentWhenSystemReady_allowsAnyUsage() {
-        setBatteryReceiverRegistrationResult(null);
         setIgnoreVibrationsOnWirelessCharger(true);
         createSystemReadyVibrationSettings();
 
@@ -334,7 +308,9 @@
     @Test
     public void shouldIgnoreVibration_onNonWirelessChargerWhenSystemReady_allowsAnyUsage() {
         Intent nonWirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_USB);
-        setBatteryReceiverRegistrationResult(nonWirelessChargingIntent);
+        doReturn(nonWirelessChargingIntent).when(mContextSpy).registerReceiver(
+                any(BroadcastReceiver.class),
+                argThat(filter -> filter.matchAction(Intent.ACTION_BATTERY_CHANGED)), anyInt());
         setIgnoreVibrationsOnWirelessCharger(true);
         createSystemReadyVibrationSettings();
 
@@ -346,7 +322,9 @@
     @Test
     public void shouldIgnoreVibration_onWirelessChargerWhenSystemReady_doesNotAllowFromAnyUsage() {
         Intent wirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS);
-        setBatteryReceiverRegistrationResult(wirelessChargingIntent);
+        doReturn(wirelessChargingIntent).when(mContextSpy).registerReceiver(
+                any(BroadcastReceiver.class),
+                argThat(filter -> filter.matchAction(Intent.ACTION_BATTERY_CHANGED)), anyInt());
         setIgnoreVibrationsOnWirelessCharger(true);
         createSystemReadyVibrationSettings();
 
@@ -357,13 +335,12 @@
 
     @Test
     public void shouldIgnoreVibration_receivesWirelessChargingIntent_doesNotAllowFromAnyUsage() {
-        Intent nonWirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_USB);
-        setBatteryReceiverRegistrationResult(nonWirelessChargingIntent);
         setIgnoreVibrationsOnWirelessCharger(true);
         createSystemReadyVibrationSettings();
 
         Intent wirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS);
-        mRegisteredBatteryBroadcastReceiver.onReceive(mContextSpy, wirelessChargingIntent);
+        mVibrationSettings.mBatteryBroadcastReceiver.onReceive(
+                mContextSpy, wirelessChargingIntent);
 
         for (int usage : ALL_USAGES) {
             assertVibrationIgnoredForUsage(usage, Vibration.Status.IGNORED_ON_WIRELESS_CHARGER);
@@ -372,17 +349,21 @@
 
     @Test
     public void shouldIgnoreVibration_receivesNonWirelessChargingIntent_allowsAnyUsage() {
-        Intent wirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS);
-        setBatteryReceiverRegistrationResult(wirelessChargingIntent);
         setIgnoreVibrationsOnWirelessCharger(true);
         createSystemReadyVibrationSettings();
+
+        Intent wirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_WIRELESS);
+        mVibrationSettings.mBatteryBroadcastReceiver.onReceive(
+                mContextSpy, wirelessChargingIntent);
+
         // Check that initially, all usages are ignored due to the wireless charging.
         for (int usage : ALL_USAGES) {
             assertVibrationIgnoredForUsage(usage, Vibration.Status.IGNORED_ON_WIRELESS_CHARGER);
         }
 
         Intent nonWirelessChargingIntent = getBatteryChangedIntent(BATTERY_PLUGGED_USB);
-        mRegisteredBatteryBroadcastReceiver.onReceive(mContextSpy, nonWirelessChargingIntent);
+        mVibrationSettings.mBatteryBroadcastReceiver.onReceive(
+                mContextSpy, nonWirelessChargingIntent);
 
         for (int usage : ALL_USAGES) {
             assertVibrationNotIgnoredForUsage(usage);
@@ -399,7 +380,7 @@
                 USAGE_HARDWARE_FEEDBACK
         ));
 
-        mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
+        mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
 
         for (int usage : ALL_USAGES) {
             if (expectedAllowedVibrations.contains(usage)) {
@@ -412,7 +393,7 @@
 
     @Test
     public void shouldIgnoreVibration_notInBatterySaverMode_allowsAnyUsage() {
-        mRegisteredPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
+        mVibrationSettings.mLowPowerModeListener.onLowPowerModeChanged(NORMAL_POWER_STATE);
 
         for (int usage : ALL_USAGES) {
             assertVibrationNotIgnoredForUsage(usage);
@@ -605,7 +586,7 @@
 
         // Testing the broadcast flow manually.
         when(mAudioManagerMock.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
-        mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+        mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
                 new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
 
         assertVibrationIgnoredForUsage(USAGE_RINGTONE, Vibration.Status.IGNORED_FOR_RINGER_MODE);
@@ -868,16 +849,15 @@
                 mVibrationSettings.getCurrentIntensity(USAGE_RINGTONE));
 
         // Test early update of settings based on new user id.
-        putUserSetting(Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_LOW,
-                NEW_USER_ID);
-        mVibrationSettings.mUserSwitchObserver.onUserSwitching(NEW_USER_ID);
+        putUserSetting(Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_LOW, USER_ID);
+        mVibrationSettings.mUserSwitchObserver.onUserSwitching(USER_ID);
         assertEquals(VIBRATION_INTENSITY_LOW,
                 mVibrationSettings.getCurrentIntensity(USAGE_RINGTONE));
 
         // Test later update of settings for UserHandle.USER_CURRENT.
         putUserSetting(Settings.System.RING_VIBRATION_INTENSITY, VIBRATION_INTENSITY_LOW,
                 UserHandle.USER_CURRENT);
-        mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(NEW_USER_ID);
+        mVibrationSettings.mUserSwitchObserver.onUserSwitchComplete(USER_ID);
         assertEquals(VIBRATION_INTENSITY_LOW,
                 mVibrationSettings.getCurrentIntensity(USAGE_RINGTONE));
     }
@@ -1010,7 +990,7 @@
     private void setRingerMode(int ringerMode) {
         when(mAudioManagerMock.getRingerModeInternal()).thenReturn(ringerMode);
         // Mock AudioManager broadcast of internal ringer mode change.
-        mVibrationSettings.mSettingChangeReceiver.onReceive(mContextSpy,
+        mVibrationSettings.mRingerModeBroadcastReceiver.onReceive(mContextSpy,
                 new Intent(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION));
     }
 
@@ -1025,14 +1005,6 @@
         return new Vibration.CallerInfo(attrs, uid, VIRTUAL_DEVICE_ID, opPkg, null);
     }
 
-    private void setBatteryReceiverRegistrationResult(Intent result) {
-        doAnswer(invocation -> {
-            mRegisteredBatteryBroadcastReceiver = invocation.getArgument(0);
-            return result;
-        }).when(mContextSpy).registerReceiver(any(BroadcastReceiver.class),
-                argThat(filter -> filter.matchAction(Intent.ACTION_BATTERY_CHANGED)), anyInt());
-    }
-
     private Intent getBatteryChangedIntent(int extraPluggedValue) {
         Intent batteryIntent = new Intent(Intent.ACTION_BATTERY_CHANGED);
         batteryIntent.putExtra(EXTRA_PLUGGED, extraPluggedValue);
diff --git a/tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml b/tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml
new file mode 100644
index 0000000..67d4397a
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/ct_domains.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+      <certificateTransparency enabled="true" />
+  </base-config>
+  <domain-config>
+    <domain>android.com</domain>
+    <trust-anchors>
+      <certificates src="system" />
+    </trust-anchors>
+  </domain-config>
+  <domain-config>
+    <domain>subdomain_user.android.com</domain>
+    <trust-anchors>
+      <certificates src="user" />
+    </trust-anchors>
+  </domain-config>
+  <domain-config>
+    <certificateTransparency enabled="true" />
+    <domain>subdomain_user_ct.android.com</domain>
+    <trust-anchors>
+      <certificates src="user" />
+    </trust-anchors>
+  </domain-config>
+  <domain-config>
+    <domain>subdomain_inline.android.com</domain>
+    <trust-anchors>
+      <certificates src="@raw/ca_certs_pem" />
+    </trust-anchors>
+  </domain-config>
+  <domain-config>
+    <certificateTransparency enabled="true" />
+    <domain>subdomain_inline_ct.android.com</domain>
+    <trust-anchors>
+      <certificates src="@raw/ca_certs_pem" />
+    </trust-anchors>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/res/xml/ct_users.xml b/tests/NetworkSecurityConfigTest/res/xml/ct_users.xml
new file mode 100644
index 0000000..c35fd71
--- /dev/null
+++ b/tests/NetworkSecurityConfigTest/res/xml/ct_users.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<network-security-config>
+  <base-config>
+    <trust-anchors>
+      <certificates src="user" />
+    </trust-anchors>
+  </base-config>
+  <domain-config>
+    <domain>android.com</domain>
+  </domain-config>
+  <domain-config>
+    <certificateTransparency enabled="true" />
+    <domain>subdomain.android.com</domain>
+  </domain-config>
+</network-security-config>
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
index 0494f17..c6fe068 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/NetworkSecurityConfigTests.java
@@ -111,7 +111,8 @@
     private NetworkSecurityConfig getSystemStoreConfig() {
         return new NetworkSecurityConfig.Builder()
                 .addCertificatesEntryRef(
-                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+                        new CertificatesEntryRef(
+                              SystemCertificateSource.getInstance(), false, false))
                 .build();
     }
 
@@ -141,7 +142,8 @@
         NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
                 .setPinSet(new PinSet(pins, Long.MAX_VALUE))
                 .addCertificatesEntryRef(
-                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+                        new CertificatesEntryRef(
+                              SystemCertificateSource.getInstance(), false, false))
                 .build();
         ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
                 = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
@@ -159,7 +161,8 @@
         NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
                 .setPinSet(new PinSet(pins, Long.MAX_VALUE))
                 .addCertificatesEntryRef(
-                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+                        new CertificatesEntryRef(
+                              SystemCertificateSource.getInstance(), false, false))
                 .build();
         ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
                 = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
@@ -178,7 +181,8 @@
         NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
                 .setPinSet(new PinSet(pins, Long.MAX_VALUE))
                 .addCertificatesEntryRef(
-                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), true))
+                        new CertificatesEntryRef(
+                              SystemCertificateSource.getInstance(), true, false))
                 .build();
         ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
                 = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
@@ -245,7 +249,8 @@
         NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder()
                 .setPinSet(new PinSet(pins, Long.MAX_VALUE))
                 .addCertificatesEntryRef(
-                        new CertificatesEntryRef(SystemCertificateSource.getInstance(), false))
+                        new CertificatesEntryRef(
+                              SystemCertificateSource.getInstance(), false, false))
                 .build();
         ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap
                 = new ArraySet<Pair<Domain, NetworkSecurityConfig>>();
diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
index 81e05c1..542465d 100644
--- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
+++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java
@@ -502,4 +502,47 @@
         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
         TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
     }
+
+    public void testCertificateTransparencyDomainConfig() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.ct_domains,
+                TestUtils.makeApplicationInfo());
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+        assertNotNull(config);
+        // Check defaults.
+        assertTrue(config.isCertificateTransparencyVerificationRequired());
+
+        config = appConfig.getConfigForHostname("android.com");
+        assertTrue(config.isCertificateTransparencyVerificationRequired());
+
+        config = appConfig.getConfigForHostname("subdomain_user.android.com");
+        assertFalse(config.isCertificateTransparencyVerificationRequired());
+
+        config = appConfig.getConfigForHostname("subdomain_user_ct.android.com");
+        assertTrue(config.isCertificateTransparencyVerificationRequired());
+
+        config = appConfig.getConfigForHostname("subdomain_inline.android.com");
+        assertFalse(config.isCertificateTransparencyVerificationRequired());
+
+        config = appConfig.getConfigForHostname("subdomain_inline_ct.android.com");
+        assertTrue(config.isCertificateTransparencyVerificationRequired());
+    }
+
+    public void testCertificateTransparencyUserConfig() throws Exception {
+        XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.ct_users,
+                TestUtils.makeApplicationInfo());
+        ApplicationConfig appConfig = new ApplicationConfig(source);
+        assertTrue(appConfig.hasPerDomainConfigs());
+        NetworkSecurityConfig config = appConfig.getConfigForHostname("");
+        assertNotNull(config);
+        // Check defaults.
+        assertFalse(config.isCertificateTransparencyVerificationRequired());
+
+        config = appConfig.getConfigForHostname("android.com");
+        assertFalse(config.isCertificateTransparencyVerificationRequired());
+
+        config = appConfig.getConfigForHostname("subdomain.android.com");
+        assertTrue(config.isCertificateTransparencyVerificationRequired());
+    }
 }
diff --git a/tests/vcn/Android.bp b/tests/vcn/Android.bp
index b16ba15..51a300b 100644
--- a/tests/vcn/Android.bp
+++ b/tests/vcn/Android.bp
@@ -14,21 +14,24 @@
 
 android_test {
     name: "FrameworksVcnTests",
+    // For access hidden connectivity methods in tests
+    defaults: ["framework-connectivity-test-defaults"],
     srcs: [
         "java/**/*.java",
         "java/**/*.kt",
     ],
     platform_apis: true,
-    defaults: ["framework-connectivity-test-defaults"],
     test_suites: ["device-tests"],
     certificate: "platform",
     static_libs: [
+        "android.net.vcn.flags-aconfig-java-export",
         "androidx.test.rules",
         "frameworks-base-testutils",
         "framework-protos",
         "mockito-target-minus-junit4",
         "net-tests-utils",
         "platform-test-annotations",
+        "service-connectivity-b-pre-jarjar",
         "services.core",
         "service-connectivity-tiramisu-pre-jarjar",
         "flag-junit",
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index b999475..77f82f0 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -55,7 +55,6 @@
 import android.content.IntentFilter;
 import android.net.vcn.VcnManager;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
 import android.os.test.TestLooper;
@@ -72,6 +71,8 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.modules.utils.HandlerExecutor;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 76be232..74db6a5 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -659,7 +659,6 @@
 
     private void verifySetSafeModeAlarm(
             boolean safeModeEnabledByCaller,
-            boolean safeModeConfigFlagEnabled,
             boolean expectingSafeModeEnabled)
             throws Exception {
         final VcnGatewayConnectionConfig config =
@@ -670,7 +669,6 @@
                 mock(VcnGatewayConnection.Dependencies.class);
         setUpWakeupMessage(
                 mSafeModeTimeoutAlarm, VcnGatewayConnection.SAFEMODE_TIMEOUT_ALARM, deps);
-        doReturn(safeModeConfigFlagEnabled).when(mFeatureFlags).safeModeConfig();
 
         final VcnGatewayConnection connection =
                 new VcnGatewayConnection(
@@ -694,37 +692,19 @@
     }
 
     @Test
-    public void testSafeModeEnabled_configFlagEnabled() throws Exception {
+    public void testSafeModeEnabled() throws Exception {
         verifySetSafeModeAlarm(
                 true /* safeModeEnabledByCaller */,
-                true /* safeModeConfigFlagEnabled */,
                 true /* expectingSafeModeEnabled */);
     }
 
     @Test
-    public void testSafeModeEnabled_configFlagDisabled() throws Exception {
-        verifySetSafeModeAlarm(
-                true /* safeModeEnabledByCaller */,
-                false /* safeModeConfigFlagEnabled */,
-                true /* expectingSafeModeEnabled */);
-    }
-
-    @Test
-    public void testSafeModeDisabled_configFlagEnabled() throws Exception {
+    public void testSafeModeDisabled() throws Exception {
         verifySetSafeModeAlarm(
                 false /* safeModeEnabledByCaller */,
-                true /* safeModeConfigFlagEnabled */,
                 false /* expectingSafeModeEnabled */);
     }
 
-    @Test
-    public void testSafeModeDisabled_configFlagDisabled() throws Exception {
-        verifySetSafeModeAlarm(
-                false /* safeModeEnabledByCaller */,
-                false /* safeModeConfigFlagEnabled */,
-                true /* expectingSafeModeEnabled */);
-    }
-
     private Consumer<VcnNetworkAgent> setupNetworkAndGetUnwantedCallback() {
         triggerChildOpened();
         mTestLooper.dispatchAll();