Merge "Support converting IkeTrafficSelector to/from PersistableBundle"
diff --git a/Android.bp b/Android.bp
index 4f248d9..0d7deb1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -333,7 +333,6 @@
     srcs: [
         // Java/AIDL sources under frameworks/base
         ":framework-blobstore-sources",
-        ":framework-connectivity-sources", // framework-connectivity is not yet a module
         ":framework-core-sources",
         ":framework-drm-sources",
         ":framework-graphics-sources",
@@ -395,6 +394,7 @@
 filegroup {
     name: "framework-updatable-sources",
     srcs: [
+        ":framework-connectivity-sources",
         ":framework-mediaprovider-sources",
         ":framework-permission-sources",
         ":framework-sdkextensions-sources",
@@ -525,6 +525,7 @@
         "android.hardware.vibrator-V1.3-java",
         "android.security.apc-java",
         "android.security.authorization-java",
+        "android.security.usermanager-java",
         "android.system.keystore2-V1-java",
         "android.system.suspend.control.internal-java",
         "devicepolicyprotosnano",
@@ -579,6 +580,7 @@
     defaults: ["framework-aidl-export-defaults"],
     srcs: [
         ":framework-non-updatable-sources",
+        ":framework-connectivity-sources",
         "core/java/**/*.logtags",
     ],
     // See comment on framework-atb-backward-compatibility module below
@@ -627,6 +629,8 @@
     apex_available: ["//apex_available:platform"],
     visibility: [
         "//frameworks/base",
+        // TODO: remove when framework-connectivity can build against API
+        "//frameworks/base/packages/Connectivity/framework",
         // TODO(b/147128803) remove the below lines
         "//frameworks/base/apex/blobstore/framework",
         "//frameworks/base/apex/jobscheduler/framework",
@@ -1280,6 +1284,7 @@
     ],
     libs: [
         "framework-annotations-lib",
+        "framework-connectivity",
         "unsupportedappusage",
     ],
     visibility: [
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 6cece60..d866116 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -57,6 +57,9 @@
     aidl: {
         local_include_dirs: [
             "apex/media/aidl/stable",
+            // TODO: move to include-dirs for packages/modules/Connectivity when this moves out of
+            // frameworks/base
+            "packages/Connectivity/framework/aidl-export",
             "telephony/java",
         ],
     },
@@ -306,6 +309,7 @@
         "android.net.ipsec.ike.stubs",
         "art.module.public.api.stubs",
         "conscrypt.module.public.api.stubs",
+        "framework-connectivity.stubs",
         "framework-media.stubs",
         "framework-mediaprovider.stubs",
         "framework-permission.stubs",
@@ -326,6 +330,7 @@
         "android.net.ipsec.ike.stubs.system",
         "art.module.public.api.stubs",
         "conscrypt.module.public.api.stubs",
+        "framework-connectivity.stubs.system",
         "framework-media.stubs.system",
         "framework-mediaprovider.stubs.system",
         "framework-permission.stubs.system",
@@ -362,6 +367,7 @@
         "android.net.ipsec.ike.stubs.system",
         "art.module.public.api.stubs",
         "conscrypt.module.public.api.stubs",
+        "framework-connectivity.stubs.system",
         "framework-media.stubs.system",
         "framework-mediaprovider.stubs.system",
         "framework-permission.stubs.system",
diff --git a/api/Android.bp b/api/Android.bp
index 2c2bb65..485255f 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -39,6 +39,7 @@
         ":android.net.ipsec.ike{.public.api.txt}",
         ":art.module.public.api{.public.api.txt}",
         ":conscrypt.module.public.api{.public.api.txt}",
+        ":framework-connectivity{.public.api.txt}",
         ":framework-media{.public.api.txt}",
         ":framework-mediaprovider{.public.api.txt}",
         ":framework-permission{.public.api.txt}",
@@ -90,6 +91,7 @@
         ":api-stubs-docs-non-updatable",
         ":art.module.public.api{.public.stubs.source}",
         ":conscrypt.module.public.api{.public.stubs.source}",
+        ":framework-connectivity{.public.stubs.source}",
         ":framework-media{.public.stubs.source}",
         ":framework-mediaprovider{.public.stubs.source}",
         ":framework-permission{.public.stubs.source}",
@@ -111,6 +113,7 @@
         ":android.net.ipsec.ike{.public.removed-api.txt}",
         ":art.module.public.api{.public.removed-api.txt}",
         ":conscrypt.module.public.api{.public.removed-api.txt}",
+        ":framework-connectivity{.public.removed-api.txt}",
         ":framework-media{.public.removed-api.txt}",
         ":framework-mediaprovider{.public.removed-api.txt}",
         ":framework-permission{.public.removed-api.txt}",
@@ -142,6 +145,7 @@
     name: "frameworks-base-api-system-current.txt",
     srcs: [
         ":android.net.ipsec.ike{.system.api.txt}",
+        ":framework-connectivity{.system.api.txt}",
         ":framework-media{.system.api.txt}",
         ":framework-mediaprovider{.system.api.txt}",
         ":framework-permission{.system.api.txt}",
@@ -191,6 +195,7 @@
     name: "frameworks-base-api-system-removed.txt",
     srcs: [
         ":android.net.ipsec.ike{.system.removed-api.txt}",
+        ":framework-connectivity{.system.removed-api.txt}",
         ":framework-media{.system.removed-api.txt}",
         ":framework-mediaprovider{.system.removed-api.txt}",
         ":framework-permission{.system.removed-api.txt}",
@@ -222,6 +227,7 @@
     name: "frameworks-base-api-module-lib-current.txt",
     srcs: [
         ":android.net.ipsec.ike{.module-lib.api.txt}",
+        ":framework-connectivity{.module-lib.api.txt}",
         ":framework-media{.module-lib.api.txt}",
         ":framework-mediaprovider{.module-lib.api.txt}",
         ":framework-permission{.module-lib.api.txt}",
@@ -273,6 +279,7 @@
     name: "frameworks-base-api-module-lib-removed.txt",
     srcs: [
         ":android.net.ipsec.ike{.module-lib.removed-api.txt}",
+        ":framework-connectivity{.module-lib.removed-api.txt}",
         ":framework-media{.module-lib.removed-api.txt}",
         ":framework-mediaprovider{.module-lib.removed-api.txt}",
         ":framework-permission{.module-lib.removed-api.txt}",
@@ -312,3 +319,49 @@
     out: ["combined-removed-dex.txt"],
     cmd: "$(location gen_combined_removed_dex.sh) $(location metalava) $(genDir) $(in) > $(out)",
 }
+
+genrule {
+    name: "services-system-server-current.txt",
+    srcs: [
+        ":service-permission{.system-server.api.txt}",
+        ":non-updatable-system-server-current.txt",
+    ],
+    out: ["system-server-current.txt"],
+    tools: ["metalava"],
+    cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)",
+    dists: [
+        {
+            targets: ["droidcore"],
+            dir: "api",
+            dest: "system-server-current.txt",
+        },
+        {
+            targets: ["sdk", "win_sdk"],
+            dir: "apistubs/android/system-server/api",
+            dest: "merge-android.txt",
+        },
+    ],
+}
+
+genrule {
+    name: "services-system-server-removed.txt",
+    srcs: [
+        ":service-permission{.system-server.removed-api.txt}",
+        ":non-updatable-system-server-removed.txt",
+    ],
+    out: ["system-server-removed.txt"],
+    tools: ["metalava"],
+    cmd: "$(location metalava) --no-banner --format=v2 $(in) --api $(out)",
+    dists: [
+        {
+            targets: ["droidcore"],
+            dir: "api",
+            dest: "system-server-removed.txt",
+        },
+        {
+            targets: ["sdk", "win_sdk"],
+            dir: "apistubs/android/system-server/api",
+            dest: "merge-removed.txt",
+        },
+    ],
+}
diff --git a/cmds/hid/OWNERS b/cmds/hid/OWNERS
new file mode 100644
index 0000000..d701f23
--- /dev/null
+++ b/cmds/hid/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/hardware/input/OWNERS
diff --git a/config/dirty-image-objects b/config/dirty-image-objects
index 2dfe019..dfd091c 100644
--- a/config/dirty-image-objects
+++ b/config/dirty-image-objects
@@ -28,359 +28,359 @@
 # Then, grep for lines containing "Private dirty object" from the output.
 # This particular file was generated by dumping systemserver and systemui.
 #
-android.accounts.Account
-android.accounts.OnAccountsUpdateListener
-android.animation.LayoutTransition
-android.app.ActivityManager
-android.app.ActivityManager$OnUidImportanceListener
-android.app.ActivityTaskManager
-android.app.ActivityThread
-android.app.admin.DevicePolicyManager
-android.app.AlarmManager
-android.app.Application
-android.app.AppOpsManager
-android.app.backup.BackupManager
-android.app.ContextImpl
-android.app.INotificationManager
-android.app.Notification$BigPictureStyle
-android.app.Notification$BigTextStyle
-android.app.Notification$InboxStyle
-android.app.NotificationChannel
-android.app.NotificationChannelGroup
-android.app.NotificationManager
-android.app.PendingIntent
-android.app.PendingIntent$OnFinished
-android.app.QueuedWork
-android.app.ResourcesManager
-android.app.WallpaperManager
-android.app.WindowConfiguration
-android.bluetooth.BluetoothAdapter
-android.bluetooth.BluetoothDevice
-android.bluetooth.BluetoothProfile
-android.bluetooth.IBluetoothA2dp
-android.bluetooth.IBluetoothHeadsetPhone
-android.bluetooth.IBluetoothHidDevice
-android.bluetooth.IBluetoothHidHost
-android.bluetooth.IBluetoothMap
-android.bluetooth.IBluetoothPan
-android.bluetooth.IBluetoothPbap
-android.bluetooth.IBluetoothSap
-android.content.ClipboardManager$OnPrimaryClipChangedListener
-android.content.ComponentName
-android.content.ContentProvider$PipeDataWriter
-android.content.ContentResolver
-android.content.Context
-android.content.Intent
-android.content.pm.PackageManager$OnPermissionsChangedListener
-android.content.pm.VersionedPackage
-android.content.res.Configuration
-android.content.SharedPreferences$OnSharedPreferenceChangeListener
-android.database.CursorWindow
-android.database.sqlite.SQLiteCompatibilityWalFlags
-android.database.sqlite.SQLiteDatabase$CursorFactory
-android.database.sqlite.SQLiteGlobal
-android.database.sqlite.SQLiteTransactionListener
-android.ddm.DdmHandleAppName
-android.graphics.Bitmap
-android.graphics.Canvas
-android.graphics.drawable.AdaptiveIconDrawable
-android.graphics.drawable.ColorDrawable
-android.graphics.drawable.GradientDrawable
-android.graphics.drawable.Icon
-android.graphics.drawable.InsetDrawable
-android.graphics.drawable.RippleDrawable
-android.graphics.drawable.VectorDrawable$VGroup
-android.graphics.ImageDecoder
-android.graphics.Rect
-android.graphics.TemporaryBuffer
-android.hardware.biometrics.BiometricSourceType
-android.hardware.display.ColorDisplayManager$ColorDisplayManagerInternal
-android.hardware.display.DisplayManagerGlobal
-android.hardware.display.NightDisplayListener$Callback
-android.hardware.input.InputManager
-android.hardware.input.InputManager$InputDeviceListener
-android.hardware.SensorPrivacyManager
-android.hardware.SystemSensorManager
-android.icu.impl.OlsonTimeZone
-android.icu.text.BreakIterator
-android.icu.text.Collator
-android.icu.text.DateFormat$BooleanAttribute
-android.icu.text.DateTimePatternGenerator$DTPGflags
-android.icu.text.PluralRules$Operand
-android.icu.util.TimeZone
-android.location.GpsStatus$Listener
-android.location.LocationListener
-android.media.AudioManager
-android.media.MediaRouter
-android.media.PlayerBase
-android.media.session.MediaSessionManager
-android.net.apf.ApfCapabilities
-android.net.ConnectivityManager
-android.net.ConnectivityManager$OnNetworkActiveListener
-android.net.ConnectivityThread$Singleton
-android.net.IpConfiguration$IpAssignment
-android.net.IpConfiguration$ProxySettings
-android.net.IpPrefix
-android.net.LinkAddress
-android.net.LinkProperties
-android.net.Network
-android.net.NetworkCapabilities
-android.net.NetworkInfo
-android.net.NetworkInfo$State
-android.net.NetworkRequest
-android.net.NetworkRequest$Type
-android.net.RouteInfo
-android.net.StringNetworkSpecifier
-android.net.TrafficStats
-android.net.UidRange
-android.net.Uri$HierarchicalUri
-android.net.Uri$StringUri
-android.net.wifi.WifiManager
-android.net.wifi.WifiManager$SoftApCallback
-android.os.AsyncResult
-android.os.AsyncTask
-android.os.BinderProxy
-android.os.Bundle
-android.os.DeadObjectException
-android.os.Environment
-android.os.FileObserver
-android.os.Handler
-android.os.IDeviceIdleController
-android.os.LocaleList
-android.os.Looper
-android.os.Message
-android.os.ParcelUuid
-android.os.Process
-android.os.RecoverySystem
-android.os.ServiceManager
-android.os.storage.StorageManager
-android.os.StrictMode
-android.os.Trace
-android.os.WorkSource
-android.os.WorkSource$WorkChain
-android.permission.PermissionManager
-android.provider.FontsContract
-android.provider.Settings$SettingNotFoundException
-android.renderscript.RenderScriptCacheDir
-android.security.IKeyChainService
-android.security.keystore.AndroidKeyStoreProvider
-android.security.net.config.ApplicationConfig
-android.security.net.config.SystemCertificateSource$NoPreloadHolder
-android.telecom.PhoneAccountHandle
-android.telephony.AnomalyReporter
-android.telephony.CellSignalStrengthCdma
-android.telephony.CellSignalStrengthGsm
-android.telephony.CellSignalStrengthLte
-android.telephony.CellSignalStrengthNr
-android.telephony.CellSignalStrengthTdscdma
-android.telephony.CellSignalStrengthWcdma
-android.telephony.DataSpecificRegistrationInfo
-android.telephony.emergency.EmergencyNumber
-android.telephony.ims.ImsMmTelManager$CapabilityCallback$CapabilityBinder
-android.telephony.ims.ImsMmTelManager$RegistrationCallback$RegistrationBinder
-android.telephony.ims.ImsReasonInfo
-android.telephony.ims.ProvisioningManager$Callback$CallbackBinder
-android.telephony.ModemActivityInfo
-android.telephony.ModemInfo
-android.telephony.NetworkRegistrationInfo
-android.telephony.NetworkService
-android.telephony.TelephonyManager
-android.telephony.VoiceSpecificRegistrationInfo
-android.text.format.DateFormat
-android.text.method.SingleLineTransformationMethod
-android.text.Selection$MemoryTextWatcher
-android.text.SpanWatcher
-android.text.style.AlignmentSpan
-android.text.style.CharacterStyle
-android.text.style.LeadingMarginSpan
-android.text.style.LineBackgroundSpan
-android.text.style.LineHeightSpan
-android.text.style.MetricAffectingSpan
-android.text.style.ReplacementSpan
-android.text.style.SuggestionSpan
-android.text.style.TabStopSpan
-android.text.TextUtils
-android.text.TextWatcher
-android.transition.ChangeClipBounds
-android.transition.ChangeImageTransform
-android.transition.ChangeTransform
-android.util.ArrayMap
-android.util.ArraySet
-android.util.DisplayMetrics
-android.util.EventLog
-android.util.Log
-android.util.Patterns
-android.view.AbsSavedState$1
-android.view.accessibility.AccessibilityManager
-android.view.accessibility.AccessibilityManager$AccessibilityServicesStateChangeListener
-android.view.accessibility.AccessibilityManager$TouchExplorationStateChangeListener
-android.view.accessibility.AccessibilityNodeIdManager
-android.view.autofill.AutofillManager
-android.view.autofill.Helper
-android.view.Choreographer
-android.view.inputmethod.InputMethodManager
-android.view.IWindowManager
-android.view.PointerIcon
-android.view.RemoteAnimationAdapter
-android.view.ThreadedRenderer
-android.view.View
-android.view.View$OnHoverListener
-android.view.ViewRootImpl
-android.view.ViewStub
-android.view.ViewStub$OnInflateListener
-android.view.ViewTreeObserver
-android.view.WindowManager$LayoutParams
-android.view.WindowManagerGlobal
-android.widget.ActionMenuPresenter$OverflowMenuButton
-android.widget.ActionMenuView
-android.widget.Button
-android.widget.CheckBox
-android.widget.FrameLayout
-android.widget.ImageButton
-android.widget.ImageView
-android.widget.LinearLayout
-android.widget.RelativeLayout
-android.widget.SeekBar
-android.widget.Space
-android.widget.TextView
-android.widget.Toolbar
-byte[]
-com.android.ims.ImsManager
-com.android.internal.logging.MetricsLogger
-com.android.internal.os.BackgroundThread
-com.android.internal.os.BinderInternal
-com.android.internal.os.BinderInternal$BinderProxyLimitListener
-com.android.internal.os.RuntimeInit
-com.android.internal.os.SomeArgs
-com.android.internal.policy.DecorView
-com.android.internal.statusbar.IStatusBarService
-com.android.internal.telephony.AppSmsManager
-android.telephony.CallerInfoAsyncQuery$OnQueryCompleteListener
-com.android.internal.telephony.CarrierActionAgent
-com.android.internal.telephony.cat.CatService
-com.android.internal.telephony.cat.IconLoader
-com.android.internal.telephony.cat.RilMessageDecoder
-com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager
-com.android.internal.telephony.cdma.EriManager
-com.android.internal.telephony.CellularNetworkValidator
-com.android.internal.telephony.CommandException
-com.android.internal.telephony.dataconnection.DataConnection$DcActivatingState
-com.android.internal.telephony.dataconnection.DataConnection$DcActiveState
-com.android.internal.telephony.dataconnection.DataConnection$DcInactiveState
-com.android.internal.telephony.dataconnection.DataEnabledSettings
-com.android.internal.telephony.dataconnection.DcTracker
-com.android.internal.telephony.euicc.EuiccCardController
-com.android.internal.telephony.euicc.EuiccController
-com.android.internal.telephony.GsmAlphabet
-com.android.internal.telephony.GsmCdmaCallTracker
-com.android.internal.telephony.GsmCdmaPhone
-com.android.internal.telephony.IccPhoneBookInterfaceManager
-com.android.internal.telephony.IccSmsInterfaceManager
-com.android.internal.telephony.ims.ImsResolver
-com.android.internal.telephony.imsphone.ImsExternalCallTracker
-com.android.internal.telephony.imsphone.ImsPhone
-com.android.internal.telephony.imsphone.ImsPhoneCallTracker
-com.android.internal.telephony.ims.RcsMessageStoreController
-com.android.internal.telephony.IntentBroadcaster
-com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy
-com.android.internal.telephony.metrics.TelephonyMetrics
-com.android.internal.telephony.MultiSimSettingController
-com.android.internal.telephony.nano.CarrierIdProto$CarrierAttribute
-com.android.internal.telephony.nano.CarrierIdProto$CarrierId
-com.android.internal.telephony.nano.TelephonyProto$RilDataCall
-com.android.internal.telephony.nano.TelephonyProto$SmsSession$Event
-com.android.internal.telephony.nano.TelephonyProto$TelephonyCallSession$Event$RilCall
-com.android.internal.telephony.NitzStateMachine
-com.android.internal.telephony.PhoneConfigurationManager
-com.android.internal.telephony.PhoneFactory
-com.android.internal.telephony.PhoneSwitcher
-com.android.internal.telephony.ProxyController
-com.android.internal.telephony.RadioConfig
-com.android.internal.telephony.RIL
-com.android.internal.telephony.RILRequest
-com.android.internal.telephony.RilWakelockInfo
-com.android.internal.telephony.ServiceStateTracker
-com.android.internal.telephony.SimActivationTracker
-com.android.internal.telephony.SmsApplication
-com.android.internal.telephony.SmsBroadcastUndelivered
-com.android.internal.telephony.SmsStorageMonitor
-com.android.internal.telephony.SmsUsageMonitor
-com.android.internal.telephony.SubscriptionController
-com.android.internal.telephony.SubscriptionInfoUpdater
-com.android.internal.telephony.TelephonyComponentFactory
-com.android.internal.telephony.TelephonyDevController
-com.android.internal.telephony.TelephonyTester
-com.android.internal.telephony.uicc.AdnRecordCache
-com.android.internal.telephony.uicc.UiccCardApplication
-com.android.internal.telephony.uicc.UiccController
-com.android.internal.telephony.uicc.UiccProfile
-com.android.internal.telephony.uicc.UiccStateChangedLauncher
-com.android.internal.telephony.uicc.UsimFileHandler
-com.android.internal.telephony.uicc.VoiceMailConstants
-com.android.internal.util.LatencyTracker
-com.android.internal.util.StateMachine$SmHandler
-com.android.okhttp.OkHttpClient
-com.android.okhttp.okio.AsyncTimeout
-com.android.okhttp.okio.SegmentPool
-com.android.phone.ecc.nano.ProtobufEccData$CountryInfo
-com.android.phone.ecc.nano.ProtobufEccData$EccInfo
-com.android.server.sip.SipWakeupTimer
-com.android.server.SystemConfig
-dalvik.system.BaseDexClassLoader
-dalvik.system.BlockGuard
-dalvik.system.CloseGuard
-dalvik.system.RuntimeHooks
-dalvik.system.SocketTagger
-java.io.BufferedReader
-java.lang.AssertionError
-java.lang.Boolean
-java.lang.Byte
-java.lang.Character
-java.lang.CharSequence
-java.lang.Class
-java.lang.IllegalAccessException
-java.lang.IllegalStateException
-java.lang.NoSuchMethodException
-java.lang.NullPointerException
-java.lang.Object
-java.lang.Object[]
-java.lang.ref.FinalizerReference
-java.lang.Runnable
-java.lang.SecurityException
-java.lang.Short
-java.lang.String[]
-java.lang.System
-java.lang.Thread
-java.lang.Throwable
-java.lang.UnsatisfiedLinkError
-java.net.Inet6Address
-java.net.Socket
-java.net.SocketException
-java.nio.Bits
-java.nio.charset.Charset
-java.security.interfaces.RSAPrivateKey
-java.security.Provider
-java.util.Collections
-java.util.concurrent.Executor
-java.util.GregorianCalendar
-java.util.Locale
-java.util.Locale$NoImagePreloadHolder
-java.util.Scanner
-java.util.Set
-java.util.TimeZone
-javax.net.SocketFactory
-javax.net.ssl.HttpsURLConnection
-javax.net.ssl.HttpsURLConnection$NoPreloadHolder
-javax.net.ssl.SSLContext
-javax.net.ssl.SSLSessionContext
-javax.net.ssl.SSLSocketFactory
-libcore.io.Libcore
-libcore.io.Memory
-libcore.net.NetworkSecurityPolicy
-libcore.timezone.TimeZoneFinder
-org.apache.http.params.HttpParams
-sun.misc.Cleaner
-sun.nio.ch.FileChannelImpl
-sun.nio.ch.FileChannelImpl$Unmapper
-sun.nio.fs.UnixChannelFactory
-sun.security.jca.Providers
+Landroid/accounts/Account;
+Landroid/accounts/OnAccountsUpdateListener;
+Landroid/animation/LayoutTransition;
+Landroid/app/ActivityManager;
+Landroid/app/ActivityManager$OnUidImportanceListener;
+Landroid/app/ActivityTaskManager;
+Landroid/app/ActivityThread;
+Landroid/app/admin/DevicePolicyManager;
+Landroid/app/AlarmManager;
+Landroid/app/Application;
+Landroid/app/AppOpsManager;
+Landroid/app/backup/BackupManager;
+Landroid/app/ContextImpl;
+Landroid/app/INotificationManager;
+Landroid/app/Notification$BigPictureStyle;
+Landroid/app/Notification$BigTextStyle;
+Landroid/app/Notification$InboxStyle;
+Landroid/app/NotificationChannel;
+Landroid/app/NotificationChannelGroup;
+Landroid/app/NotificationManager;
+Landroid/app/PendingIntent;
+Landroid/app/PendingIntent$OnFinished;
+Landroid/app/QueuedWork;
+Landroid/app/ResourcesManager;
+Landroid/app/WallpaperManager;
+Landroid/app/WindowConfiguration;
+Landroid/bluetooth/BluetoothAdapter;
+Landroid/bluetooth/BluetoothDevice;
+Landroid/bluetooth/BluetoothProfile;
+Landroid/bluetooth/IBluetoothA2dp;
+Landroid/bluetooth/IBluetoothHeadsetPhone;
+Landroid/bluetooth/IBluetoothHidDevice;
+Landroid/bluetooth/IBluetoothHidHost;
+Landroid/bluetooth/IBluetoothMap;
+Landroid/bluetooth/IBluetoothPan;
+Landroid/bluetooth/IBluetoothPbap;
+Landroid/bluetooth/IBluetoothSap;
+Landroid/content/ClipboardManager$OnPrimaryClipChangedListener;
+Landroid/content/ComponentName;
+Landroid/content/ContentProvider$PipeDataWriter;
+Landroid/content/ContentResolver;
+Landroid/content/Context;
+Landroid/content/Intent;
+Landroid/content/pm/PackageManager$OnPermissionsChangedListener;
+Landroid/content/pm/VersionedPackage;
+Landroid/content/res/Configuration;
+Landroid/content/SharedPreferences$OnSharedPreferenceChangeListener;
+Landroid/database/CursorWindow;
+Landroid/database/sqlite/SQLiteCompatibilityWalFlags;
+Landroid/database/sqlite/SQLiteDatabase$CursorFactory;
+Landroid/database/sqlite/SQLiteGlobal;
+Landroid/database/sqlite/SQLiteTransactionListener;
+Landroid/ddm/DdmHandleAppName;
+Landroid/graphics/Bitmap;
+Landroid/graphics/Canvas;
+Landroid/graphics/drawable/AdaptiveIconDrawable;
+Landroid/graphics/drawable/ColorDrawable;
+Landroid/graphics/drawable/GradientDrawable;
+Landroid/graphics/drawable/Icon;
+Landroid/graphics/drawable/InsetDrawable;
+Landroid/graphics/drawable/RippleDrawable;
+Landroid/graphics/drawable/VectorDrawable$VGroup;
+Landroid/graphics/ImageDecoder;
+Landroid/graphics/Rect;
+Landroid/graphics/TemporaryBuffer;
+Landroid/hardware/biometrics/BiometricSourceType;
+Landroid/hardware/display/ColorDisplayManager$ColorDisplayManagerInternal;
+Landroid/hardware/display/DisplayManagerGlobal;
+Landroid/hardware/display/NightDisplayListener$Callback;
+Landroid/hardware/input/InputManager;
+Landroid/hardware/input/InputManager$InputDeviceListener;
+Landroid/hardware/SensorPrivacyManager;
+Landroid/hardware/SystemSensorManager;
+Landroid/icu/impl/OlsonTimeZone;
+Landroid/icu/text/BreakIterator;
+Landroid/icu/text/Collator;
+Landroid/icu/text/DateFormat$BooleanAttribute;
+Landroid/icu/text/DateTimePatternGenerator$DTPGflags;
+Landroid/icu/text/PluralRules$Operand;
+Landroid/icu/util/TimeZone;
+Landroid/location/GpsStatus$Listener;
+Landroid/location/LocationListener;
+Landroid/media/AudioManager;
+Landroid/media/MediaRouter;
+Landroid/media/PlayerBase;
+Landroid/media/session/MediaSessionManager;
+Landroid/net/apf/ApfCapabilities;
+Landroid/net/ConnectivityManager;
+Landroid/net/ConnectivityManager$OnNetworkActiveListener;
+Landroid/net/ConnectivityThread$Singleton;
+Landroid/net/IpConfiguration$IpAssignment;
+Landroid/net/IpConfiguration$ProxySettings;
+Landroid/net/IpPrefix;
+Landroid/net/LinkAddress;
+Landroid/net/LinkProperties;
+Landroid/net/Network;
+Landroid/net/NetworkCapabilities;
+Landroid/net/NetworkInfo;
+Landroid/net/NetworkInfo$State;
+Landroid/net/NetworkRequest;
+Landroid/net/NetworkRequest$Type;
+Landroid/net/RouteInfo;
+Landroid/net/StringNetworkSpecifier;
+Landroid/net/TrafficStats;
+Landroid/net/UidRange;
+Landroid/net/Uri$HierarchicalUri;
+Landroid/net/Uri$StringUri;
+Landroid/net/wifi/WifiManager;
+Landroid/net/wifi/WifiManager$SoftApCallback;
+Landroid/os/AsyncResult;
+Landroid/os/AsyncTask;
+Landroid/os/BinderProxy;
+Landroid/os/Bundle;
+Landroid/os/DeadObjectException;
+Landroid/os/Environment;
+Landroid/os/FileObserver;
+Landroid/os/Handler;
+Landroid/os/IDeviceIdleController;
+Landroid/os/LocaleList;
+Landroid/os/Looper;
+Landroid/os/Message;
+Landroid/os/ParcelUuid;
+Landroid/os/Process;
+Landroid/os/RecoverySystem;
+Landroid/os/ServiceManager;
+Landroid/os/storage/StorageManager;
+Landroid/os/StrictMode;
+Landroid/os/Trace;
+Landroid/os/WorkSource;
+Landroid/os/WorkSource$WorkChain;
+Landroid/permission/PermissionManager;
+Landroid/provider/FontsContract;
+Landroid/provider/Settings$SettingNotFoundException;
+Landroid/renderscript/RenderScriptCacheDir;
+Landroid/security/IKeyChainService;
+Landroid/security/keystore/AndroidKeyStoreProvider;
+Landroid/security/net/config/ApplicationConfig;
+Landroid/security/net/config/SystemCertificateSource$NoPreloadHolder;
+Landroid/telecom/PhoneAccountHandle;
+Landroid/telephony/AnomalyReporter;
+Landroid/telephony/CellSignalStrengthCdma;
+Landroid/telephony/CellSignalStrengthGsm;
+Landroid/telephony/CellSignalStrengthLte;
+Landroid/telephony/CellSignalStrengthNr;
+Landroid/telephony/CellSignalStrengthTdscdma;
+Landroid/telephony/CellSignalStrengthWcdma;
+Landroid/telephony/DataSpecificRegistrationInfo;
+Landroid/telephony/emergency/EmergencyNumber;
+Landroid/telephony/ims/ImsMmTelManager$CapabilityCallback$CapabilityBinder;
+Landroid/telephony/ims/ImsMmTelManager$RegistrationCallback$RegistrationBinder;
+Landroid/telephony/ims/ImsReasonInfo;
+Landroid/telephony/ims/ProvisioningManager$Callback$CallbackBinder;
+Landroid/telephony/ModemActivityInfo;
+Landroid/telephony/ModemInfo;
+Landroid/telephony/NetworkRegistrationInfo;
+Landroid/telephony/NetworkService;
+Landroid/telephony/TelephonyManager;
+Landroid/telephony/VoiceSpecificRegistrationInfo;
+Landroid/text/format/DateFormat;
+Landroid/text/method/SingleLineTransformationMethod;
+Landroid/text/Selection$MemoryTextWatcher;
+Landroid/text/SpanWatcher;
+Landroid/text/style/AlignmentSpan;
+Landroid/text/style/CharacterStyle;
+Landroid/text/style/LeadingMarginSpan;
+Landroid/text/style/LineBackgroundSpan;
+Landroid/text/style/LineHeightSpan;
+Landroid/text/style/MetricAffectingSpan;
+Landroid/text/style/ReplacementSpan;
+Landroid/text/style/SuggestionSpan;
+Landroid/text/style/TabStopSpan;
+Landroid/text/TextUtils;
+Landroid/text/TextWatcher;
+Landroid/transition/ChangeClipBounds;
+Landroid/transition/ChangeImageTransform;
+Landroid/transition/ChangeTransform;
+Landroid/util/ArrayMap;
+Landroid/util/ArraySet;
+Landroid/util/DisplayMetrics;
+Landroid/util/EventLog;
+Landroid/util/Log;
+Landroid/util/Patterns;
+Landroid/view/AbsSavedState$1;
+Landroid/view/accessibility/AccessibilityManager;
+Landroid/view/accessibility/AccessibilityManager$AccessibilityServicesStateChangeListener;
+Landroid/view/accessibility/AccessibilityManager$TouchExplorationStateChangeListener;
+Landroid/view/accessibility/AccessibilityNodeIdManager;
+Landroid/view/autofill/AutofillManager;
+Landroid/view/autofill/Helper;
+Landroid/view/Choreographer;
+Landroid/view/inputmethod/InputMethodManager;
+Landroid/view/IWindowManager;
+Landroid/view/PointerIcon;
+Landroid/view/RemoteAnimationAdapter;
+Landroid/view/ThreadedRenderer;
+Landroid/view/View;
+Landroid/view/View$OnHoverListener;
+Landroid/view/ViewRootImpl;
+Landroid/view/ViewStub;
+Landroid/view/ViewStub$OnInflateListener;
+Landroid/view/ViewTreeObserver;
+Landroid/view/WindowManager$LayoutParams;
+Landroid/view/WindowManagerGlobal;
+Landroid/widget/ActionMenuPresenter$OverflowMenuButton;
+Landroid/widget/ActionMenuView;
+Landroid/widget/Button;
+Landroid/widget/CheckBox;
+Landroid/widget/FrameLayout;
+Landroid/widget/ImageButton;
+Landroid/widget/ImageView;
+Landroid/widget/LinearLayout;
+Landroid/widget/RelativeLayout;
+Landroid/widget/SeekBar;
+Landroid/widget/Space;
+Landroid/widget/TextView;
+Landroid/widget/Toolbar;
+[B
+Lcom/android/ims/ImsManager;
+Lcom/android/internal/logging/MetricsLogger;
+Lcom/android/internal/os/BackgroundThread;
+Lcom/android/internal/os/BinderInternal;
+Lcom/android/internal/os/BinderInternal$BinderProxyLimitListener;
+Lcom/android/internal/os/RuntimeInit;
+Lcom/android/internal/os/SomeArgs;
+Lcom/android/internal/policy/DecorView;
+Lcom/android/internal/statusbar/IStatusBarService;
+Lcom/android/internal/telephony/AppSmsManager;
+Landroid/telephony/CallerInfoAsyncQuery$OnQueryCompleteListener;
+Lcom/android/internal/telephony/CarrierActionAgent;
+Lcom/android/internal/telephony/cat/CatService;
+Lcom/android/internal/telephony/cat/IconLoader;
+Lcom/android/internal/telephony/cat/RilMessageDecoder;
+Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager;
+Lcom/android/internal/telephony/cdma/EriManager;
+Lcom/android/internal/telephony/CellularNetworkValidator;
+Lcom/android/internal/telephony/CommandException;
+Lcom/android/internal/telephony/dataconnection/DataConnection$DcActivatingState;
+Lcom/android/internal/telephony/dataconnection/DataConnection$DcActiveState;
+Lcom/android/internal/telephony/dataconnection/DataConnection$DcInactiveState;
+Lcom/android/internal/telephony/dataconnection/DataEnabledSettings;
+Lcom/android/internal/telephony/dataconnection/DcTracker;
+Lcom/android/internal/telephony/euicc/EuiccCardController;
+Lcom/android/internal/telephony/euicc/EuiccController;
+Lcom/android/internal/telephony/GsmAlphabet;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;
+Lcom/android/internal/telephony/GsmCdmaPhone;
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;
+Lcom/android/internal/telephony/ims/ImsResolver;
+Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker;
+Lcom/android/internal/telephony/imsphone/ImsPhone;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;
+Lcom/android/internal/telephony/ims/RcsMessageStoreController;
+Lcom/android/internal/telephony/IntentBroadcaster;
+Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;
+Lcom/android/internal/telephony/metrics/TelephonyMetrics;
+Lcom/android/internal/telephony/MultiSimSettingController;
+Lcom/android/internal/telephony/nano/CarrierIdProto$CarrierAttribute;
+Lcom/android/internal/telephony/nano/CarrierIdProto$CarrierId;
+Lcom/android/internal/telephony/nano/TelephonyProto$RilDataCall;
+Lcom/android/internal/telephony/nano/TelephonyProto$SmsSession$Event;
+Lcom/android/internal/telephony/nano/TelephonyProto$TelephonyCallSession$Event$RilCall;
+Lcom/android/internal/telephony/NitzStateMachine;
+Lcom/android/internal/telephony/PhoneConfigurationManager;
+Lcom/android/internal/telephony/PhoneFactory;
+Lcom/android/internal/telephony/PhoneSwitcher;
+Lcom/android/internal/telephony/ProxyController;
+Lcom/android/internal/telephony/RadioConfig;
+Lcom/android/internal/telephony/RIL;
+Lcom/android/internal/telephony/RILRequest;
+Lcom/android/internal/telephony/RilWakelockInfo;
+Lcom/android/internal/telephony/ServiceStateTracker;
+Lcom/android/internal/telephony/SimActivationTracker;
+Lcom/android/internal/telephony/SmsApplication;
+Lcom/android/internal/telephony/SmsBroadcastUndelivered;
+Lcom/android/internal/telephony/SmsStorageMonitor;
+Lcom/android/internal/telephony/SmsUsageMonitor;
+Lcom/android/internal/telephony/SubscriptionController;
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;
+Lcom/android/internal/telephony/TelephonyComponentFactory;
+Lcom/android/internal/telephony/TelephonyDevController;
+Lcom/android/internal/telephony/TelephonyTester;
+Lcom/android/internal/telephony/uicc/AdnRecordCache;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/uicc/UiccController;
+Lcom/android/internal/telephony/uicc/UiccProfile;
+Lcom/android/internal/telephony/uicc/UiccStateChangedLauncher;
+Lcom/android/internal/telephony/uicc/UsimFileHandler;
+Lcom/android/internal/telephony/uicc/VoiceMailConstants;
+Lcom/android/internal/util/LatencyTracker;
+Lcom/android/internal/util/StateMachine$SmHandler;
+Lcom/android/okhttp/OkHttpClient;
+Lcom/android/okhttp/okio/AsyncTimeout;
+Lcom/android/okhttp/okio/SegmentPool;
+Lcom/android/phone/ecc/nano/ProtobufEccData$CountryInfo;
+Lcom/android/phone/ecc/nano/ProtobufEccData$EccInfo;
+Lcom/android/server/sip/SipWakeupTimer;
+Lcom/android/server/SystemConfig;
+Ldalvik/system/BaseDexClassLoader;
+Ldalvik/system/BlockGuard;
+Ldalvik/system/CloseGuard;
+Ldalvik/system/RuntimeHooks;
+Ldalvik/system/SocketTagger;
+Ljava/io/BufferedReader;
+Ljava/lang/AssertionError;
+Ljava/lang/Boolean;
+Ljava/lang/Byte;
+Ljava/lang/Character;
+Ljava/lang/CharSequence;
+Ljava/lang/Class;
+Ljava/lang/IllegalAccessException;
+Ljava/lang/IllegalStateException;
+Ljava/lang/NoSuchMethodException;
+Ljava/lang/NullPointerException;
+Ljava/lang/Object;
+[Ljava/lang/Object;
+Ljava/lang/ref/FinalizerReference;
+Ljava/lang/Runnable;
+Ljava/lang/SecurityException;
+Ljava/lang/Short;
+[Ljava/lang/String;
+Ljava/lang/System;
+Ljava/lang/Thread;
+Ljava/lang/Throwable;
+Ljava/lang/UnsatisfiedLinkError;
+Ljava/net/Inet6Address;
+Ljava/net/Socket;
+Ljava/net/SocketException;
+Ljava/nio/Bits;
+Ljava/nio/charset/Charset;
+Ljava/security/interfaces/RSAPrivateKey;
+Ljava/security/Provider;
+Ljava/util/Collections;
+Ljava/util/concurrent/Executor;
+Ljava/util/GregorianCalendar;
+Ljava/util/Locale;
+Ljava/util/Locale$NoImagePreloadHolder;
+Ljava/util/Scanner;
+Ljava/util/Set;
+Ljava/util/TimeZone;
+Ljavax/net/SocketFactory;
+Ljavax/net/ssl/HttpsURLConnection;
+Ljavax/net/ssl/HttpsURLConnection$NoPreloadHolder;
+Ljavax/net/ssl/SSLContext;
+Ljavax/net/ssl/SSLSessionContext;
+Ljavax/net/ssl/SSLSocketFactory;
+Llibcore/io/Libcore;
+Llibcore/io/Memory;
+Llibcore/net/NetworkSecurityPolicy;
+Llibcore/timezone/TimeZoneFinder;
+Lorg/apache/http/params/HttpParams;
+Lsun/misc/Cleaner;
+Lsun/nio/ch/FileChannelImpl;
+Lsun/nio/ch/FileChannelImpl$Unmapper;
+Lsun/nio/fs/UnixChannelFactory;
+Lsun/security/jca/Providers;
diff --git a/core/api/current.txt b/core/api/current.txt
index eb3330c..80f8e0d 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -954,6 +954,7 @@
     field public static final int measureWithLargestChild = 16843476; // 0x10102d4
     field public static final int mediaRouteButtonStyle = 16843693; // 0x10103ad
     field public static final int mediaRouteTypes = 16843694; // 0x10103ae
+    field public static final int memtagMode = 16844313; // 0x1010619
     field public static final int menuCategory = 16843230; // 0x10101de
     field public static final int mimeGroup = 16844309; // 0x1010615
     field public static final int mimeType = 16842790; // 0x1010026
@@ -977,6 +978,7 @@
     field public static final int multiArch = 16843918; // 0x101048e
     field public static final int multiprocess = 16842771; // 0x1010013
     field public static final int name = 16842755; // 0x1010003
+    field public static final int nativeHeapZeroInit = 16844314; // 0x101061a
     field public static final int navigationBarColor = 16843858; // 0x1010452
     field public static final int navigationBarDividerColor = 16844141; // 0x101056d
     field public static final int navigationContentDescription = 16843969; // 0x10104c1
@@ -11461,6 +11463,8 @@
     method public void dump(android.util.Printer, String);
     method public static CharSequence getCategoryTitle(android.content.Context, int);
     method public int getGwpAsanMode();
+    method public int getMemtagMode();
+    method @Nullable public Boolean isNativeHeapZeroInit();
     method public boolean isProfileableByShell();
     method public boolean isResourceOverlay();
     method public boolean isVirtualPreload();
@@ -11510,6 +11514,10 @@
     field public static final int GWP_ASAN_ALWAYS = 1; // 0x1
     field public static final int GWP_ASAN_DEFAULT = -1; // 0xffffffff
     field public static final int GWP_ASAN_NEVER = 0; // 0x0
+    field public static final int MEMTAG_ASYNC = 1; // 0x1
+    field public static final int MEMTAG_DEFAULT = -1; // 0xffffffff
+    field public static final int MEMTAG_OFF = 0; // 0x0
+    field public static final int MEMTAG_SYNC = 2; // 0x2
     field public String appComponentFactory;
     field public String backupAgentName;
     field public int category;
@@ -12039,6 +12047,7 @@
     method public boolean getSyntheticAppDetailsActivityEnabled(@NonNull String);
     method @NonNull public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
     method @Nullable public abstract String[] getSystemSharedLibraryNames();
+    method @IntRange(from=0) public int getTargetSdkVersion(@NonNull String) throws android.content.pm.PackageManager.NameNotFoundException;
     method @Nullable public abstract CharSequence getText(@NonNull String, @StringRes int, @Nullable android.content.pm.ApplicationInfo);
     method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int);
     method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle);
@@ -24821,161 +24830,6 @@
 
 package android.net {
 
-  public class CaptivePortal implements android.os.Parcelable {
-    method public int describeContents();
-    method public void ignoreNetwork();
-    method public void reportCaptivePortalDismissed();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortal> CREATOR;
-  }
-
-  public class ConnectivityDiagnosticsManager {
-    method public void registerConnectivityDiagnosticsCallback(@NonNull android.net.NetworkRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback);
-    method public void unregisterConnectivityDiagnosticsCallback(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback);
-  }
-
-  public abstract static class ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback {
-    ctor public ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback();
-    method public void onConnectivityReportAvailable(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityReport);
-    method public void onDataStallSuspected(@NonNull android.net.ConnectivityDiagnosticsManager.DataStallReport);
-    method public void onNetworkConnectivityReported(@NonNull android.net.Network, boolean);
-  }
-
-  public static final class ConnectivityDiagnosticsManager.ConnectivityReport implements android.os.Parcelable {
-    ctor public ConnectivityDiagnosticsManager.ConnectivityReport(@NonNull android.net.Network, long, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkCapabilities, @NonNull android.os.PersistableBundle);
-    method public int describeContents();
-    method @NonNull public android.os.PersistableBundle getAdditionalInfo();
-    method @NonNull public android.net.LinkProperties getLinkProperties();
-    method @NonNull public android.net.Network getNetwork();
-    method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
-    method public long getReportTimestamp();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.ConnectivityDiagnosticsManager.ConnectivityReport> CREATOR;
-    field public static final String KEY_NETWORK_PROBES_ATTEMPTED_BITMASK = "networkProbesAttempted";
-    field public static final String KEY_NETWORK_PROBES_SUCCEEDED_BITMASK = "networkProbesSucceeded";
-    field public static final String KEY_NETWORK_VALIDATION_RESULT = "networkValidationResult";
-    field public static final int NETWORK_PROBE_DNS = 4; // 0x4
-    field public static final int NETWORK_PROBE_FALLBACK = 32; // 0x20
-    field public static final int NETWORK_PROBE_HTTP = 8; // 0x8
-    field public static final int NETWORK_PROBE_HTTPS = 16; // 0x10
-    field public static final int NETWORK_PROBE_PRIVATE_DNS = 64; // 0x40
-    field public static final int NETWORK_VALIDATION_RESULT_INVALID = 0; // 0x0
-    field public static final int NETWORK_VALIDATION_RESULT_PARTIALLY_VALID = 2; // 0x2
-    field public static final int NETWORK_VALIDATION_RESULT_SKIPPED = 3; // 0x3
-    field public static final int NETWORK_VALIDATION_RESULT_VALID = 1; // 0x1
-  }
-
-  public static final class ConnectivityDiagnosticsManager.DataStallReport implements android.os.Parcelable {
-    ctor public ConnectivityDiagnosticsManager.DataStallReport(@NonNull android.net.Network, long, int, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkCapabilities, @NonNull android.os.PersistableBundle);
-    method public int describeContents();
-    method public int getDetectionMethod();
-    method @NonNull public android.net.LinkProperties getLinkProperties();
-    method @NonNull public android.net.Network getNetwork();
-    method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
-    method public long getReportTimestamp();
-    method @NonNull public android.os.PersistableBundle getStallDetails();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.ConnectivityDiagnosticsManager.DataStallReport> CREATOR;
-    field public static final int DETECTION_METHOD_DNS_EVENTS = 1; // 0x1
-    field public static final int DETECTION_METHOD_TCP_METRICS = 2; // 0x2
-    field public static final String KEY_DNS_CONSECUTIVE_TIMEOUTS = "dnsConsecutiveTimeouts";
-    field public static final String KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS = "tcpMetricsCollectionPeriodMillis";
-    field public static final String KEY_TCP_PACKET_FAIL_RATE = "tcpPacketFailRate";
-  }
-
-  public class ConnectivityManager {
-    method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
-    method public boolean bindProcessToNetwork(@Nullable android.net.Network);
-    method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
-    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network getActiveNetwork();
-    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
-    method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
-    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
-    method @Deprecated public boolean getBackgroundDataSetting();
-    method @Nullable public android.net.Network getBoundNetworkForProcess();
-    method public int getConnectionOwnerUid(int, @NonNull java.net.InetSocketAddress, @NonNull java.net.InetSocketAddress);
-    method @Nullable public android.net.ProxyInfo getDefaultProxy();
-    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.LinkProperties getLinkProperties(@Nullable android.net.Network);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getMultipathPreference(@Nullable android.net.Network);
-    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkCapabilities getNetworkCapabilities(@Nullable android.net.Network);
-    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(int);
-    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(@Nullable android.net.Network);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getNetworkPreference();
-    method @Nullable public byte[] getNetworkWatchlistConfigHash();
-    method @Deprecated @Nullable public static android.net.Network getProcessDefaultNetwork();
-    method public int getRestrictBackgroundStatus();
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public boolean isActiveNetworkMetered();
-    method public boolean isDefaultNetworkActive();
-    method @Deprecated public static boolean isNetworkTypeValid(int);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
-    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.app.PendingIntent);
-    method public void releaseNetworkRequest(@NonNull android.app.PendingIntent);
-    method public void removeDefaultNetworkActiveListener(@NonNull android.net.ConnectivityManager.OnNetworkActiveListener);
-    method @Deprecated public void reportBadNetwork(@Nullable android.net.Network);
-    method public void reportNetworkConnectivity(@Nullable android.net.Network, boolean);
-    method public boolean requestBandwidthUpdate(@NonNull android.net.Network);
-    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback);
-    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
-    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, int);
-    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler, int);
-    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.app.PendingIntent);
-    method @Deprecated public void setNetworkPreference(int);
-    method @Deprecated public static boolean setProcessDefaultNetwork(@Nullable android.net.Network);
-    method public void unregisterNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback);
-    method public void unregisterNetworkCallback(@NonNull android.app.PendingIntent);
-    field @Deprecated public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
-    field public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
-    field public static final String ACTION_RESTRICT_BACKGROUND_CHANGED = "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
-    field @Deprecated public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
-    field @Deprecated public static final int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
-    field public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
-    field public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
-    field @Deprecated public static final String EXTRA_EXTRA_INFO = "extraInfo";
-    field @Deprecated public static final String EXTRA_IS_FAILOVER = "isFailover";
-    field public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
-    field @Deprecated public static final String EXTRA_NETWORK_INFO = "networkInfo";
-    field public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
-    field @Deprecated public static final String EXTRA_NETWORK_TYPE = "networkType";
-    field public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
-    field @Deprecated public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
-    field public static final String EXTRA_REASON = "reason";
-    field public static final int MULTIPATH_PREFERENCE_HANDOVER = 1; // 0x1
-    field public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 4; // 0x4
-    field public static final int MULTIPATH_PREFERENCE_RELIABILITY = 2; // 0x2
-    field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
-    field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
-    field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
-    field @Deprecated public static final int TYPE_BLUETOOTH = 7; // 0x7
-    field @Deprecated public static final int TYPE_DUMMY = 8; // 0x8
-    field @Deprecated public static final int TYPE_ETHERNET = 9; // 0x9
-    field @Deprecated public static final int TYPE_MOBILE = 0; // 0x0
-    field @Deprecated public static final int TYPE_MOBILE_DUN = 4; // 0x4
-    field @Deprecated public static final int TYPE_MOBILE_HIPRI = 5; // 0x5
-    field @Deprecated public static final int TYPE_MOBILE_MMS = 2; // 0x2
-    field @Deprecated public static final int TYPE_MOBILE_SUPL = 3; // 0x3
-    field @Deprecated public static final int TYPE_VPN = 17; // 0x11
-    field @Deprecated public static final int TYPE_WIFI = 1; // 0x1
-    field @Deprecated public static final int TYPE_WIMAX = 6; // 0x6
-  }
-
-  public static class ConnectivityManager.NetworkCallback {
-    ctor public ConnectivityManager.NetworkCallback();
-    method public void onAvailable(@NonNull android.net.Network);
-    method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
-    method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities);
-    method public void onLinkPropertiesChanged(@NonNull android.net.Network, @NonNull android.net.LinkProperties);
-    method public void onLosing(@NonNull android.net.Network, int);
-    method public void onLost(@NonNull android.net.Network);
-    method public void onUnavailable();
-  }
-
-  public static interface ConnectivityManager.OnNetworkActiveListener {
-    method public void onNetworkActive();
-  }
-
   public class Credentials {
     ctor public Credentials(int, int, int);
     method public int getGid();
@@ -24983,46 +24837,6 @@
     method public int getUid();
   }
 
-  public class DhcpInfo implements android.os.Parcelable {
-    ctor public DhcpInfo();
-    method public int describeContents();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.DhcpInfo> CREATOR;
-    field public int dns1;
-    field public int dns2;
-    field public int gateway;
-    field public int ipAddress;
-    field public int leaseDuration;
-    field public int netmask;
-    field public int serverAddress;
-  }
-
-  public final class DnsResolver {
-    method @NonNull public static android.net.DnsResolver getInstance();
-    method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
-    method public void query(@Nullable android.net.Network, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
-    method public void rawQuery(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
-    method public void rawQuery(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
-    field public static final int CLASS_IN = 1; // 0x1
-    field public static final int ERROR_PARSE = 0; // 0x0
-    field public static final int ERROR_SYSTEM = 1; // 0x1
-    field public static final int FLAG_EMPTY = 0; // 0x0
-    field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4
-    field public static final int FLAG_NO_CACHE_STORE = 2; // 0x2
-    field public static final int FLAG_NO_RETRY = 1; // 0x1
-    field public static final int TYPE_A = 1; // 0x1
-    field public static final int TYPE_AAAA = 28; // 0x1c
-  }
-
-  public static interface DnsResolver.Callback<T> {
-    method public void onAnswer(@NonNull T, int);
-    method public void onError(@NonNull android.net.DnsResolver.DnsException);
-  }
-
-  public static class DnsResolver.DnsException extends java.lang.Exception {
-    field public final int code;
-  }
-
   public final class Ikev2VpnProfile extends android.net.PlatformVpnProfile {
     method @NonNull public java.util.List<java.lang.String> getAllowedAlgorithms();
     method public int getMaxMtu();
@@ -25052,21 +24866,6 @@
     method @NonNull public android.net.Ikev2VpnProfile.Builder setProxy(@Nullable android.net.ProxyInfo);
   }
 
-  public class InetAddresses {
-    method public static boolean isNumericAddress(@NonNull String);
-    method @NonNull public static java.net.InetAddress parseNumericAddress(@NonNull String);
-  }
-
-  public final class IpPrefix implements android.os.Parcelable {
-    method public boolean contains(@NonNull java.net.InetAddress);
-    method public int describeContents();
-    method @NonNull public java.net.InetAddress getAddress();
-    method @IntRange(from=0, to=128) public int getPrefixLength();
-    method @NonNull public byte[] getRawAddress();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
-  }
-
   public final class IpSecAlgorithm implements android.os.Parcelable {
     ctor public IpSecAlgorithm(@NonNull String, @NonNull byte[]);
     ctor public IpSecAlgorithm(@NonNull String, @NonNull byte[], int);
@@ -25135,45 +24934,6 @@
     method @NonNull public android.net.IpSecTransform.Builder setIpv4Encapsulation(@NonNull android.net.IpSecManager.UdpEncapsulationSocket, int);
   }
 
-  public class LinkAddress implements android.os.Parcelable {
-    method public int describeContents();
-    method public java.net.InetAddress getAddress();
-    method public int getFlags();
-    method @IntRange(from=0, to=128) public int getPrefixLength();
-    method public int getScope();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkAddress> CREATOR;
-  }
-
-  public final class LinkProperties implements android.os.Parcelable {
-    ctor public LinkProperties();
-    method public boolean addRoute(@NonNull android.net.RouteInfo);
-    method public void clear();
-    method public int describeContents();
-    method @Nullable public java.net.Inet4Address getDhcpServerAddress();
-    method @NonNull public java.util.List<java.net.InetAddress> getDnsServers();
-    method @Nullable public String getDomains();
-    method @Nullable public android.net.ProxyInfo getHttpProxy();
-    method @Nullable public String getInterfaceName();
-    method @NonNull public java.util.List<android.net.LinkAddress> getLinkAddresses();
-    method public int getMtu();
-    method @Nullable public android.net.IpPrefix getNat64Prefix();
-    method @Nullable public String getPrivateDnsServerName();
-    method @NonNull public java.util.List<android.net.RouteInfo> getRoutes();
-    method public boolean isPrivateDnsActive();
-    method public boolean isWakeOnLanSupported();
-    method public void setDhcpServerAddress(@Nullable java.net.Inet4Address);
-    method public void setDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
-    method public void setDomains(@Nullable String);
-    method public void setHttpProxy(@Nullable android.net.ProxyInfo);
-    method public void setInterfaceName(@Nullable String);
-    method public void setLinkAddresses(@NonNull java.util.Collection<android.net.LinkAddress>);
-    method public void setMtu(int);
-    method public void setNat64Prefix(@Nullable android.net.IpPrefix);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkProperties> CREATOR;
-  }
-
   public class LocalServerSocket implements java.io.Closeable {
     ctor public LocalServerSocket(String) throws java.io.IOException;
     ctor public LocalServerSocket(java.io.FileDescriptor) throws java.io.IOException;
@@ -25229,24 +24989,6 @@
     enum_constant public static final android.net.LocalSocketAddress.Namespace RESERVED;
   }
 
-  public final class MacAddress implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public static android.net.MacAddress fromBytes(@NonNull byte[]);
-    method @NonNull public static android.net.MacAddress fromString(@NonNull String);
-    method public int getAddressType();
-    method @Nullable public java.net.Inet6Address getLinkLocalIpv6FromEui48Mac();
-    method public boolean isLocallyAssigned();
-    method public boolean matches(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
-    method @NonNull public byte[] toByteArray();
-    method @NonNull public String toOuiString();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.net.MacAddress BROADCAST_ADDRESS;
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.MacAddress> CREATOR;
-    field public static final int TYPE_BROADCAST = 3; // 0x3
-    field public static final int TYPE_MULTICAST = 2; // 0x2
-    field public static final int TYPE_UNICAST = 1; // 0x1
-  }
-
   public class MailTo {
     method public String getBody();
     method public String getCc();
@@ -25258,138 +25000,6 @@
     field public static final String MAILTO_SCHEME = "mailto:";
   }
 
-  public class Network implements android.os.Parcelable {
-    method public void bindSocket(java.net.DatagramSocket) throws java.io.IOException;
-    method public void bindSocket(java.net.Socket) throws java.io.IOException;
-    method public void bindSocket(java.io.FileDescriptor) throws java.io.IOException;
-    method public int describeContents();
-    method public static android.net.Network fromNetworkHandle(long);
-    method public java.net.InetAddress[] getAllByName(String) throws java.net.UnknownHostException;
-    method public java.net.InetAddress getByName(String) throws java.net.UnknownHostException;
-    method public long getNetworkHandle();
-    method public javax.net.SocketFactory getSocketFactory();
-    method public java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
-    method public java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException;
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.Network> CREATOR;
-  }
-
-  public final class NetworkCapabilities implements android.os.Parcelable {
-    ctor public NetworkCapabilities();
-    ctor public NetworkCapabilities(android.net.NetworkCapabilities);
-    method public int describeContents();
-    method public int getLinkDownstreamBandwidthKbps();
-    method public int getLinkUpstreamBandwidthKbps();
-    method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
-    method public int getOwnerUid();
-    method public int getSignalStrength();
-    method @Nullable public android.net.TransportInfo getTransportInfo();
-    method public boolean hasCapability(int);
-    method public boolean hasTransport(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
-    field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11
-    field public static final int NET_CAPABILITY_CBS = 5; // 0x5
-    field public static final int NET_CAPABILITY_DUN = 2; // 0x2
-    field public static final int NET_CAPABILITY_EIMS = 10; // 0xa
-    field public static final int NET_CAPABILITY_FOREGROUND = 19; // 0x13
-    field public static final int NET_CAPABILITY_FOTA = 3; // 0x3
-    field public static final int NET_CAPABILITY_IA = 7; // 0x7
-    field public static final int NET_CAPABILITY_IMS = 4; // 0x4
-    field public static final int NET_CAPABILITY_INTERNET = 12; // 0xc
-    field public static final int NET_CAPABILITY_MCX = 23; // 0x17
-    field public static final int NET_CAPABILITY_MMS = 0; // 0x0
-    field public static final int NET_CAPABILITY_NOT_CONGESTED = 20; // 0x14
-    field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
-    field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
-    field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12
-    field public static final int NET_CAPABILITY_NOT_SUSPENDED = 21; // 0x15
-    field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
-    field public static final int NET_CAPABILITY_RCS = 8; // 0x8
-    field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
-    field public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25; // 0x19
-    field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe
-    field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10
-    field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
-    field public static final int NET_CAPABILITY_XCAP = 9; // 0x9
-    field public static final int SIGNAL_STRENGTH_UNSPECIFIED = -2147483648; // 0x80000000
-    field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2
-    field public static final int TRANSPORT_CELLULAR = 0; // 0x0
-    field public static final int TRANSPORT_ETHERNET = 3; // 0x3
-    field public static final int TRANSPORT_LOWPAN = 6; // 0x6
-    field public static final int TRANSPORT_VPN = 4; // 0x4
-    field public static final int TRANSPORT_WIFI = 1; // 0x1
-    field public static final int TRANSPORT_WIFI_AWARE = 5; // 0x5
-  }
-
-  @Deprecated public class NetworkInfo implements android.os.Parcelable {
-    ctor @Deprecated public NetworkInfo(int, int, @Nullable String, @Nullable String);
-    method @Deprecated public int describeContents();
-    method @Deprecated @NonNull public android.net.NetworkInfo.DetailedState getDetailedState();
-    method @Deprecated public String getExtraInfo();
-    method @Deprecated public String getReason();
-    method @Deprecated public android.net.NetworkInfo.State getState();
-    method @Deprecated public int getSubtype();
-    method @Deprecated public String getSubtypeName();
-    method @Deprecated public int getType();
-    method @Deprecated public String getTypeName();
-    method @Deprecated public boolean isAvailable();
-    method @Deprecated public boolean isConnected();
-    method @Deprecated public boolean isConnectedOrConnecting();
-    method @Deprecated public boolean isFailover();
-    method @Deprecated public boolean isRoaming();
-    method @Deprecated public void setDetailedState(@NonNull android.net.NetworkInfo.DetailedState, @Nullable String, @Nullable String);
-    method @Deprecated public void writeToParcel(android.os.Parcel, int);
-    field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
-  }
-
-  @Deprecated public enum NetworkInfo.DetailedState {
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState AUTHENTICATING;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState BLOCKED;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CAPTIVE_PORTAL_CHECK;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CONNECTED;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CONNECTING;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState DISCONNECTED;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState DISCONNECTING;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState FAILED;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState IDLE;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState OBTAINING_IPADDR;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState SCANNING;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState SUSPENDED;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState VERIFYING_POOR_LINK;
-  }
-
-  @Deprecated public enum NetworkInfo.State {
-    enum_constant @Deprecated public static final android.net.NetworkInfo.State CONNECTED;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.State CONNECTING;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.State DISCONNECTED;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.State DISCONNECTING;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.State SUSPENDED;
-    enum_constant @Deprecated public static final android.net.NetworkInfo.State UNKNOWN;
-  }
-
-  public class NetworkRequest implements android.os.Parcelable {
-    method public boolean canBeSatisfiedBy(@Nullable android.net.NetworkCapabilities);
-    method public int describeContents();
-    method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
-    method public boolean hasCapability(int);
-    method public boolean hasTransport(int);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkRequest> CREATOR;
-  }
-
-  public static class NetworkRequest.Builder {
-    ctor public NetworkRequest.Builder();
-    method public android.net.NetworkRequest.Builder addCapability(int);
-    method public android.net.NetworkRequest.Builder addTransportType(int);
-    method public android.net.NetworkRequest build();
-    method @NonNull public android.net.NetworkRequest.Builder clearCapabilities();
-    method public android.net.NetworkRequest.Builder removeCapability(int);
-    method public android.net.NetworkRequest.Builder removeTransportType(int);
-    method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
-    method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
-  }
-
   public abstract class NetworkSpecifier {
     ctor public NetworkSpecifier();
   }
@@ -25406,44 +25016,6 @@
     field public static final int TYPE_IKEV2_IPSEC_USER_PASS = 6; // 0x6
   }
 
-  public final class Proxy {
-    ctor public Proxy();
-    method @Deprecated public static String getDefaultHost();
-    method @Deprecated public static int getDefaultPort();
-    method @Deprecated public static String getHost(android.content.Context);
-    method @Deprecated public static int getPort(android.content.Context);
-    field @Deprecated public static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
-    field public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
-  }
-
-  public class ProxyInfo implements android.os.Parcelable {
-    ctor public ProxyInfo(@Nullable android.net.ProxyInfo);
-    method public static android.net.ProxyInfo buildDirectProxy(String, int);
-    method public static android.net.ProxyInfo buildDirectProxy(String, int, java.util.List<java.lang.String>);
-    method public static android.net.ProxyInfo buildPacProxy(android.net.Uri);
-    method @NonNull public static android.net.ProxyInfo buildPacProxy(@NonNull android.net.Uri, int);
-    method public int describeContents();
-    method public String[] getExclusionList();
-    method public String getHost();
-    method public android.net.Uri getPacFileUrl();
-    method public int getPort();
-    method public boolean isValid();
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.ProxyInfo> CREATOR;
-  }
-
-  public final class RouteInfo implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public android.net.IpPrefix getDestination();
-    method @Nullable public java.net.InetAddress getGateway();
-    method @Nullable public String getInterface();
-    method public boolean hasGateway();
-    method public boolean isDefaultRoute();
-    method public boolean matches(java.net.InetAddress);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.RouteInfo> CREATOR;
-  }
-
   @Deprecated public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
     ctor @Deprecated public SSLCertificateSocketFactory(int);
     method @Deprecated public java.net.Socket createSocket(java.net.Socket, String, int, boolean) throws java.io.IOException;
@@ -25469,30 +25041,6 @@
     ctor public SSLSessionCache(android.content.Context);
   }
 
-  public abstract class SocketKeepalive implements java.lang.AutoCloseable {
-    method public final void close();
-    method public final void start(@IntRange(from=0xa, to=0xe10) int);
-    method public final void stop();
-    field public static final int ERROR_HARDWARE_ERROR = -31; // 0xffffffe1
-    field public static final int ERROR_INSUFFICIENT_RESOURCES = -32; // 0xffffffe0
-    field public static final int ERROR_INVALID_INTERVAL = -24; // 0xffffffe8
-    field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
-    field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
-    field public static final int ERROR_INVALID_NETWORK = -20; // 0xffffffec
-    field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
-    field public static final int ERROR_INVALID_SOCKET = -25; // 0xffffffe7
-    field public static final int ERROR_SOCKET_NOT_IDLE = -26; // 0xffffffe6
-    field public static final int ERROR_UNSUPPORTED = -30; // 0xffffffe2
-  }
-
-  public static class SocketKeepalive.Callback {
-    ctor public SocketKeepalive.Callback();
-    method public void onDataReceived();
-    method public void onError(int);
-    method public void onStarted();
-    method public void onStopped();
-  }
-
   public final class TelephonyNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
     method public int describeContents();
     method public int getSubscriptionId();
@@ -25550,9 +25098,6 @@
     field public static final int UNSUPPORTED = -1; // 0xffffffff
   }
 
-  public interface TransportInfo {
-  }
-
   public abstract class Uri implements java.lang.Comparable<android.net.Uri> android.os.Parcelable {
     method public abstract android.net.Uri.Builder buildUpon();
     method public int compareTo(android.net.Uri);
@@ -29659,8 +29204,8 @@
   }
 
   public final class BugreportManager {
-    method public void cancelBugreport();
-    method public void startConnectivityBugreport(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback);
+    method @WorkerThread public void cancelBugreport();
+    method @WorkerThread public void startConnectivityBugreport(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback);
   }
 
   public abstract static class BugreportManager.BugreportCallback {
@@ -39161,7 +38706,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String, android.telecom.PhoneAccountHandle);
-    method public boolean hasCompanionInCallServiceAccess();
+    method public boolean hasManageOngoingCallsPermission();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInCall();
     method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isInManagedCall();
     method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
@@ -40971,7 +40516,6 @@
 
   public final class SignalStrengthUpdateRequest implements android.os.Parcelable {
     method public int describeContents();
-    method @NonNull public android.os.IBinder getLiveToken();
     method @NonNull public java.util.Collection<android.telephony.SignalThresholdInfo> getSignalThresholdInfos();
     method public boolean isReportingRequestedWhileIdle();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index fbaa931..c0e79f6 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -10,57 +10,12 @@
 
 package android.net {
 
-  public final class ConnectivityFrameworkInitializer {
-    method public static void registerServiceWrappers();
-  }
-
-  public class ConnectivityManager {
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @Nullable android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
-  }
-
   public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
     method public int getResourceId();
   }
 
-  public final class NetworkAgentConfig implements android.os.Parcelable {
-    method @Nullable public String getSubscriberId();
-  }
-
-  public static final class NetworkAgentConfig.Builder {
-    method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String);
-  }
-
-  public final class NetworkCapabilities implements android.os.Parcelable {
-    field public static final int TRANSPORT_TEST = 7; // 0x7
-  }
-
-  public final class TcpRepairWindow {
-    ctor public TcpRepairWindow(int, int, int, int, int, int);
-    field public final int maxWindow;
-    field public final int rcvWnd;
-    field public final int rcvWndScale;
-    field public final int rcvWup;
-    field public final int sndWl1;
-    field public final int sndWnd;
-  }
-
-  public final class TestNetworkInterface implements android.os.Parcelable {
-    ctor public TestNetworkInterface(@NonNull android.os.ParcelFileDescriptor, @NonNull String);
-    method public int describeContents();
-    method @NonNull public android.os.ParcelFileDescriptor getFileDescriptor();
-    method @NonNull public String getInterfaceName();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkInterface> CREATOR;
-  }
-
-  public class TestNetworkManager {
-    method @NonNull public android.net.TestNetworkInterface createTapInterface();
-    method @NonNull public android.net.TestNetworkInterface createTunInterface(@NonNull java.util.Collection<android.net.LinkAddress>);
-    method public void setupTestNetwork(@NonNull String, @NonNull android.os.IBinder);
-    method public void teardownTestNetwork(@NonNull android.net.Network);
-    field public static final String TEST_TAP_PREFIX = "testtap";
+  public class NetworkWatchlistManager {
+    method @Nullable public byte[] getWatchlistConfigHash();
   }
 
   public final class UnderlyingNetworkInfo implements android.os.Parcelable {
@@ -73,14 +28,6 @@
     field @NonNull public final java.util.List<java.lang.String> underlyingIfaces;
   }
 
-  public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
-    ctor public VpnTransportInfo(int);
-    method public int describeContents();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
-    field public final int type;
-  }
-
 }
 
 package android.os {
diff --git a/core/api/removed.txt b/core/api/removed.txt
index 21aeef6d..f551aae 100644
--- a/core/api/removed.txt
+++ b/core/api/removed.txt
@@ -249,12 +249,6 @@
 
 package android.net {
 
-  public class ConnectivityManager {
-    method @Deprecated public boolean requestRouteToHost(int, int);
-    method @Deprecated public int startUsingNetworkFeature(int, String);
-    method @Deprecated public int stopUsingNetworkFeature(int, String);
-  }
-
   @Deprecated public class NetworkBadging {
     method @NonNull public static android.graphics.drawable.Drawable getWifiIcon(@IntRange(from=0, to=4) int, int, @Nullable android.content.res.Resources.Theme);
     field public static final int BADGING_4K = 30; // 0x1e
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 06d7f24..afdf335 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -14,6 +14,7 @@
     field public static final String ACCESS_MTP = "android.permission.ACCESS_MTP";
     field public static final String ACCESS_NETWORK_CONDITIONS = "android.permission.ACCESS_NETWORK_CONDITIONS";
     field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS";
+    field public static final String ACCESS_RCS_USER_CAPABILITY_EXCHANGE = "android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE";
     field public static final String ACCESS_SHARED_LIBRARIES = "android.permission.ACCESS_SHARED_LIBRARIES";
     field public static final String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS";
     field public static final String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
@@ -1431,7 +1432,7 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public android.bluetooth.BufferConstraints getBufferConstraints();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getDynamicBufferSupport();
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setBufferMillis(int, int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setBufferLengthMillis(int, int);
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
     field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD = 1; // 0x1
     field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING = 2; // 0x2
@@ -1546,6 +1547,10 @@
     field public static final String ACTION_CONNECTION_STATE_CHANGED = "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED";
   }
 
+  public final class BluetoothMapClient implements android.bluetooth.BluetoothProfile {
+    method @RequiresPermission(android.Manifest.permission.SEND_SMS) public boolean sendMessage(@NonNull android.bluetooth.BluetoothDevice, @NonNull java.util.Collection<android.net.Uri>, @NonNull String, @Nullable android.app.PendingIntent, @Nullable android.app.PendingIntent);
+  }
+
   public final class BluetoothPan implements android.bluetooth.BluetoothProfile {
     method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public java.util.List<android.bluetooth.BluetoothDevice> getConnectedDevices();
     method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public int getConnectionState(@NonNull android.bluetooth.BluetoothDevice);
@@ -1578,6 +1583,7 @@
     field public static final int CONNECTION_POLICY_FORBIDDEN = 0; // 0x0
     field public static final int CONNECTION_POLICY_UNKNOWN = -1; // 0xffffffff
     field public static final int HEADSET_CLIENT = 16; // 0x10
+    field public static final int MAP_CLIENT = 18; // 0x12
     field public static final int PAN = 5; // 0x5
     field public static final int PBAP_CLIENT = 17; // 0x11
     field @Deprecated public static final int PRIORITY_OFF = 0; // 0x0
@@ -1631,7 +1637,7 @@
   public final class BufferConstraints implements android.os.Parcelable {
     ctor public BufferConstraints(@NonNull java.util.List<android.bluetooth.BufferConstraint>);
     method public int describeContents();
-    method @Nullable public android.bluetooth.BufferConstraint getCodec(int);
+    method @Nullable public android.bluetooth.BufferConstraint forCodec(int);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final int BUFFER_CODEC_MAX_NUM = 32; // 0x20
     field @NonNull public static final android.os.Parcelable.Creator<android.bluetooth.BufferConstraints> CREATOR;
@@ -5992,102 +5998,6 @@
 
 package android.net {
 
-  public class CaptivePortal implements android.os.Parcelable {
-    method public void logEvent(int, @NonNull String);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void reevaluateNetwork();
-    method public void useNetwork();
-    field public static final int APP_REQUEST_REEVALUATION_REQUIRED = 100; // 0x64
-    field public static final int APP_RETURN_DISMISSED = 0; // 0x0
-    field public static final int APP_RETURN_UNWANTED = 1; // 0x1
-    field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2
-  }
-
-  public final class CaptivePortalData implements android.os.Parcelable {
-    method public int describeContents();
-    method public long getByteLimit();
-    method public long getExpiryTimeMillis();
-    method public long getRefreshTimeMillis();
-    method @Nullable public android.net.Uri getUserPortalUrl();
-    method public int getUserPortalUrlSource();
-    method @Nullable public String getVenueFriendlyName();
-    method @Nullable public android.net.Uri getVenueInfoUrl();
-    method public int getVenueInfoUrlSource();
-    method public boolean isCaptive();
-    method public boolean isSessionExtendable();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field public static final int CAPTIVE_PORTAL_DATA_SOURCE_OTHER = 0; // 0x0
-    field public static final int CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT = 1; // 0x1
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortalData> CREATOR;
-  }
-
-  public static class CaptivePortalData.Builder {
-    ctor public CaptivePortalData.Builder();
-    ctor public CaptivePortalData.Builder(@Nullable android.net.CaptivePortalData);
-    method @NonNull public android.net.CaptivePortalData build();
-    method @NonNull public android.net.CaptivePortalData.Builder setBytesRemaining(long);
-    method @NonNull public android.net.CaptivePortalData.Builder setCaptive(boolean);
-    method @NonNull public android.net.CaptivePortalData.Builder setExpiryTime(long);
-    method @NonNull public android.net.CaptivePortalData.Builder setRefreshTime(long);
-    method @NonNull public android.net.CaptivePortalData.Builder setSessionExtendable(boolean);
-    method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri);
-    method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri, int);
-    method @NonNull public android.net.CaptivePortalData.Builder setVenueFriendlyName(@Nullable String);
-    method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri);
-    method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri, int);
-  }
-
-  public class ConnectivityManager {
-    method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull android.os.ParcelFileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
-    method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCaptivePortalServerUrl();
-    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
-    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public int registerNetworkProvider(@NonNull android.net.NetworkProvider);
-    method public void registerQosCallback(@NonNull android.net.QosSocketInfo, @NonNull android.net.QosCallback, @NonNull java.util.concurrent.Executor);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
-    method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
-    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
-    method @RequiresPermission(android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE) public void setOemNetworkPreference(@NonNull android.net.OemNetworkPreferences, @Nullable java.util.concurrent.Executor, @Nullable android.net.ConnectivityManager.OnSetOemNetworkPreferenceListener);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi();
-    method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider);
-    method public void unregisterQosCallback(@NonNull android.net.QosCallback);
-    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
-    field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
-    field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
-    field public static final int TETHERING_BLUETOOTH = 2; // 0x2
-    field public static final int TETHERING_USB = 1; // 0x1
-    field public static final int TETHERING_WIFI = 0; // 0x0
-    field @Deprecated public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = 13; // 0xd
-    field @Deprecated public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
-    field @Deprecated public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
-    field public static final int TYPE_NONE = -1; // 0xffffffff
-    field @Deprecated public static final int TYPE_PROXY = 16; // 0x10
-    field @Deprecated public static final int TYPE_WIFI_P2P = 13; // 0xd
-  }
-
-  public static interface ConnectivityManager.OnSetOemNetworkPreferenceListener {
-    method public void onComplete();
-  }
-
-  @Deprecated public abstract static class ConnectivityManager.OnStartTetheringCallback {
-    ctor @Deprecated public ConnectivityManager.OnStartTetheringCallback();
-    method @Deprecated public void onTetheringFailed();
-    method @Deprecated public void onTetheringStarted();
-  }
-
-  @Deprecated public static interface ConnectivityManager.OnTetheringEntitlementResultListener {
-    method @Deprecated public void onTetheringEntitlementResult(int);
-  }
-
-  @Deprecated public abstract static class ConnectivityManager.OnTetheringEventCallback {
-    ctor @Deprecated public ConnectivityManager.OnTetheringEventCallback();
-    method @Deprecated public void onUpstreamChanged(@Nullable android.net.Network);
-  }
-
   public class DnsResolverServiceManager {
     method @NonNull @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public static android.os.IBinder getService(@NonNull android.content.Context);
   }
@@ -6105,48 +6015,6 @@
     method public void release();
   }
 
-  public final class InvalidPacketException extends java.lang.Exception {
-    ctor public InvalidPacketException(int);
-    method public int getError();
-    field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
-    field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
-    field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
-  }
-
-  public final class IpConfiguration implements android.os.Parcelable {
-    ctor public IpConfiguration();
-    ctor public IpConfiguration(@NonNull android.net.IpConfiguration);
-    method public int describeContents();
-    method @Nullable public android.net.ProxyInfo getHttpProxy();
-    method @NonNull public android.net.IpConfiguration.IpAssignment getIpAssignment();
-    method @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings();
-    method @Nullable public android.net.StaticIpConfiguration getStaticIpConfiguration();
-    method public void setHttpProxy(@Nullable android.net.ProxyInfo);
-    method public void setIpAssignment(@NonNull android.net.IpConfiguration.IpAssignment);
-    method public void setProxySettings(@NonNull android.net.IpConfiguration.ProxySettings);
-    method public void setStaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.IpConfiguration> CREATOR;
-  }
-
-  public enum IpConfiguration.IpAssignment {
-    enum_constant public static final android.net.IpConfiguration.IpAssignment DHCP;
-    enum_constant public static final android.net.IpConfiguration.IpAssignment STATIC;
-    enum_constant public static final android.net.IpConfiguration.IpAssignment UNASSIGNED;
-  }
-
-  public enum IpConfiguration.ProxySettings {
-    enum_constant public static final android.net.IpConfiguration.ProxySettings NONE;
-    enum_constant public static final android.net.IpConfiguration.ProxySettings PAC;
-    enum_constant public static final android.net.IpConfiguration.ProxySettings STATIC;
-    enum_constant public static final android.net.IpConfiguration.ProxySettings UNASSIGNED;
-  }
-
-  public final class IpPrefix implements android.os.Parcelable {
-    ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
-    ctor public IpPrefix(@NonNull String);
-  }
-
   public final class IpSecManager {
     method @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public void applyTunnelModeTransform(@NonNull android.net.IpSecManager.IpSecTunnelInterface, int, @NonNull android.net.IpSecTransform) throws java.io.IOException;
     method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecManager.IpSecTunnelInterface createIpSecTunnelInterface(@NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull android.net.Network) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
@@ -6164,68 +6032,6 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_IPSEC_TUNNELS) public android.net.IpSecTransform buildTunnelModeTransform(@NonNull java.net.InetAddress, @NonNull android.net.IpSecManager.SecurityParameterIndex) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
   }
 
-  public class KeepalivePacketData {
-    ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull byte[]) throws android.net.InvalidPacketException;
-    method @NonNull public java.net.InetAddress getDstAddress();
-    method public int getDstPort();
-    method @NonNull public byte[] getPacket();
-    method @NonNull public java.net.InetAddress getSrcAddress();
-    method public int getSrcPort();
-  }
-
-  public class LinkAddress implements android.os.Parcelable {
-    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int);
-    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int, long, long);
-    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
-    ctor public LinkAddress(@NonNull String);
-    ctor public LinkAddress(@NonNull String, int, int);
-    method public long getDeprecationTime();
-    method public long getExpirationTime();
-    method public boolean isGlobalPreferred();
-    method public boolean isIpv4();
-    method public boolean isIpv6();
-    method public boolean isSameAddressAs(@Nullable android.net.LinkAddress);
-    field public static final long LIFETIME_PERMANENT = 9223372036854775807L; // 0x7fffffffffffffffL
-    field public static final long LIFETIME_UNKNOWN = -1L; // 0xffffffffffffffffL
-  }
-
-  public final class LinkProperties implements android.os.Parcelable {
-    ctor public LinkProperties(@Nullable android.net.LinkProperties);
-    ctor public LinkProperties(@Nullable android.net.LinkProperties, boolean);
-    method public boolean addDnsServer(@NonNull java.net.InetAddress);
-    method public boolean addLinkAddress(@NonNull android.net.LinkAddress);
-    method public boolean addPcscfServer(@NonNull java.net.InetAddress);
-    method @NonNull public java.util.List<java.net.InetAddress> getAddresses();
-    method @NonNull public java.util.List<java.lang.String> getAllInterfaceNames();
-    method @NonNull public java.util.List<android.net.LinkAddress> getAllLinkAddresses();
-    method @NonNull public java.util.List<android.net.RouteInfo> getAllRoutes();
-    method @Nullable public android.net.Uri getCaptivePortalApiUrl();
-    method @Nullable public android.net.CaptivePortalData getCaptivePortalData();
-    method @NonNull public java.util.List<java.net.InetAddress> getPcscfServers();
-    method @Nullable public String getTcpBufferSizes();
-    method @NonNull public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers();
-    method public boolean hasGlobalIpv6Address();
-    method public boolean hasIpv4Address();
-    method public boolean hasIpv4DefaultRoute();
-    method public boolean hasIpv4DnsServer();
-    method public boolean hasIpv6DefaultRoute();
-    method public boolean hasIpv6DnsServer();
-    method public boolean isIpv4Provisioned();
-    method public boolean isIpv6Provisioned();
-    method public boolean isProvisioned();
-    method public boolean isReachable(@NonNull java.net.InetAddress);
-    method public boolean removeDnsServer(@NonNull java.net.InetAddress);
-    method public boolean removeLinkAddress(@NonNull android.net.LinkAddress);
-    method public boolean removeRoute(@NonNull android.net.RouteInfo);
-    method public void setCaptivePortalApiUrl(@Nullable android.net.Uri);
-    method public void setCaptivePortalData(@Nullable android.net.CaptivePortalData);
-    method public void setPcscfServers(@NonNull java.util.Collection<java.net.InetAddress>);
-    method public void setPrivateDnsServerName(@Nullable String);
-    method public void setTcpBufferSizes(@Nullable String);
-    method public void setUsePrivateDns(boolean);
-    method public void setValidatedPrivateDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
-  }
-
   public final class MatchAllNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
     ctor public MatchAllNetworkSpecifier();
     method public int describeContents();
@@ -6233,104 +6039,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.MatchAllNetworkSpecifier> CREATOR;
   }
 
-  public final class NattKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable {
-    ctor public NattKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[]) throws android.net.InvalidPacketException;
-    method public int describeContents();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.NattKeepalivePacketData> CREATOR;
-  }
-
-  public class Network implements android.os.Parcelable {
-    ctor public Network(@NonNull android.net.Network);
-    method public int getNetId();
-    method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
-  }
-
-  public abstract class NetworkAgent {
-    ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, int, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
-    method @Nullable public android.net.Network getNetwork();
-    method public void markConnected();
-    method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
-    method public void onAutomaticReconnectDisabled();
-    method public void onNetworkUnwanted();
-    method public void onQosCallbackRegistered(int, @NonNull android.net.QosFilter);
-    method public void onQosCallbackUnregistered(int);
-    method public void onRemoveKeepalivePacketFilter(int);
-    method public void onSaveAcceptUnvalidated(boolean);
-    method public void onSignalStrengthThresholdsUpdated(@NonNull int[]);
-    method public void onStartSocketKeepalive(int, @NonNull java.time.Duration, @NonNull android.net.KeepalivePacketData);
-    method public void onStopSocketKeepalive(int);
-    method public void onValidationStatus(int, @Nullable android.net.Uri);
-    method @NonNull public android.net.Network register();
-    method public final void sendLinkProperties(@NonNull android.net.LinkProperties);
-    method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
-    method public final void sendNetworkScore(@IntRange(from=0, to=99) int);
-    method public final void sendQosCallbackError(int, int);
-    method public final void sendQosSessionAvailable(int, int, @NonNull android.telephony.data.EpsBearerQosSessionAttributes);
-    method public final void sendQosSessionLost(int, int);
-    method public final void sendSocketKeepaliveEvent(int, int);
-    method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
-    method public void unregister();
-    field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
-    field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
-  }
-
-  public final class NetworkAgentConfig implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getLegacyType();
-    method @NonNull public String getLegacyTypeName();
-    method public boolean isExplicitlySelected();
-    method public boolean isPartialConnectivityAcceptable();
-    method public boolean isUnvalidatedConnectivityAcceptable();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR;
-  }
-
-  public static final class NetworkAgentConfig.Builder {
-    ctor public NetworkAgentConfig.Builder();
-    method @NonNull public android.net.NetworkAgentConfig build();
-    method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
-    method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int);
-    method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String);
-    method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean);
-    method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean);
-  }
-
-  public final class NetworkCapabilities implements android.os.Parcelable {
-    ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, boolean);
-    method @NonNull public int[] getAdministratorUids();
-    method @Nullable public String getSsid();
-    method @NonNull public int[] getTransportTypes();
-    method public boolean isPrivateDnsBroken();
-    method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
-    field public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28; // 0x1c
-    field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
-    field public static final int NET_CAPABILITY_OEM_PRIVATE = 26; // 0x1a
-    field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18
-    field public static final int NET_CAPABILITY_VEHICLE_INTERNAL = 27; // 0x1b
-  }
-
-  public static final class NetworkCapabilities.Builder {
-    ctor public NetworkCapabilities.Builder();
-    ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
-    method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
-    method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
-    method @NonNull public android.net.NetworkCapabilities build();
-    method @NonNull public android.net.NetworkCapabilities.Builder clearAll();
-    method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
-    method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
-    method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
-    method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int);
-    method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setOwnerUid(int);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int);
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
-    method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
-  }
-
   public class NetworkKey implements android.os.Parcelable {
     ctor public NetworkKey(android.net.WifiKey);
     method @Nullable public static android.net.NetworkKey createFromScanResult(@NonNull android.net.wifi.ScanResult);
@@ -6342,15 +6050,6 @@
     field public final android.net.WifiKey wifiKey;
   }
 
-  public class NetworkProvider {
-    ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String);
-    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest);
-    method public int getProviderId();
-    method public void onNetworkRequestWithdrawn(@NonNull android.net.NetworkRequest);
-    method public void onNetworkRequested(@NonNull android.net.NetworkRequest, @IntRange(from=0, to=99) int, int);
-    field public static final int ID_NONE = -1; // 0xffffffff
-  }
-
   public abstract class NetworkRecommendationProvider {
     ctor public NetworkRecommendationProvider(android.content.Context, java.util.concurrent.Executor);
     method public final android.os.IBinder getBinder();
@@ -6360,15 +6059,6 @@
   public class NetworkReleasedException extends java.lang.Exception {
   }
 
-  public class NetworkRequest implements android.os.Parcelable {
-    method @Nullable public String getRequestorPackageName();
-    method public int getRequestorUid();
-  }
-
-  public static class NetworkRequest.Builder {
-    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
-  }
-
   public class NetworkScoreManager {
     method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, android.Manifest.permission.REQUEST_NETWORK_SCORES}) public boolean clearScores() throws java.lang.SecurityException;
     method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, android.Manifest.permission.REQUEST_NETWORK_SCORES}) public void disableScoring() throws java.lang.SecurityException;
@@ -6493,16 +6183,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSocketInfo> CREATOR;
   }
 
-  public final class RouteInfo implements android.os.Parcelable {
-    ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int);
-    ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int, int);
-    method public int getMtu();
-    method public int getType();
-    field public static final int RTN_THROW = 9; // 0x9
-    field public static final int RTN_UNICAST = 1; // 0x1
-    field public static final int RTN_UNREACHABLE = 7; // 0x7
-  }
-
   public class RssiCurve implements android.os.Parcelable {
     ctor public RssiCurve(int, int, byte[]);
     ctor public RssiCurve(int, int, byte[], int);
@@ -6534,53 +6214,12 @@
     field public final android.net.RssiCurve rssiCurve;
   }
 
-  public abstract class SocketKeepalive implements java.lang.AutoCloseable {
-    field public static final int SUCCESS = 0; // 0x0
-  }
-
   public class SocketLocalAddressChangedException extends java.lang.Exception {
   }
 
   public class SocketNotBoundException extends java.lang.Exception {
   }
 
-  public final class StaticIpConfiguration implements android.os.Parcelable {
-    ctor public StaticIpConfiguration();
-    ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
-    method public void addDnsServer(@NonNull java.net.InetAddress);
-    method public void clear();
-    method public int describeContents();
-    method @NonNull public java.util.List<java.net.InetAddress> getDnsServers();
-    method @Nullable public String getDomains();
-    method @Nullable public java.net.InetAddress getGateway();
-    method @Nullable public android.net.LinkAddress getIpAddress();
-    method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
-    method public void writeToParcel(android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.StaticIpConfiguration> CREATOR;
-  }
-
-  public static final class StaticIpConfiguration.Builder {
-    ctor public StaticIpConfiguration.Builder();
-    method @NonNull public android.net.StaticIpConfiguration build();
-    method @NonNull public android.net.StaticIpConfiguration.Builder setDnsServers(@NonNull Iterable<java.net.InetAddress>);
-    method @NonNull public android.net.StaticIpConfiguration.Builder setDomains(@Nullable String);
-    method @NonNull public android.net.StaticIpConfiguration.Builder setGateway(@Nullable java.net.InetAddress);
-    method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@Nullable android.net.LinkAddress);
-  }
-
-  public final class TcpKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable {
-    ctor public TcpKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[], int, int, int, int, int, int) throws android.net.InvalidPacketException;
-    method public int describeContents();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.TcpKeepalivePacketData> CREATOR;
-    field public final int ipTos;
-    field public final int ipTtl;
-    field public final int tcpAck;
-    field public final int tcpSeq;
-    field public final int tcpWindow;
-    field public final int tcpWindowScale;
-  }
-
   public class TrafficStats {
     method public static void setThreadStatsTagApp();
     method public static void setThreadStatsTagBackup();
@@ -6593,11 +6232,6 @@
     field public static final int TAG_SYSTEM_IMPERSONATION_RANGE_START = -256; // 0xffffff00
   }
 
-  public interface TransportInfo {
-    method public default boolean hasLocationSensitiveFields();
-    method @NonNull public default android.net.TransportInfo makeCopy(boolean);
-  }
-
   public abstract class Uri implements java.lang.Comparable<android.net.Uri> android.os.Parcelable {
     method @NonNull public String toSafeString();
   }
@@ -6621,23 +6255,6 @@
 
 }
 
-package android.net.apf {
-
-  public final class ApfCapabilities implements android.os.Parcelable {
-    ctor public ApfCapabilities(int, int, int);
-    method public int describeContents();
-    method public static boolean getApfDrop8023Frames();
-    method @NonNull public static int[] getApfEtherTypeBlackList();
-    method public boolean hasDataAccess();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.net.apf.ApfCapabilities> CREATOR;
-    field public final int apfPacketFormat;
-    field public final int apfVersionSupported;
-    field public final int maximumApfProgramSize;
-  }
-
-}
-
 package android.net.metrics {
 
   @Deprecated public final class ApfProgramEvent implements android.net.metrics.IpConnectivityLog.Event {
@@ -6832,15 +6449,24 @@
 
 }
 
-package android.net.util {
+package android.net.vcn {
 
-  public final class SocketUtils {
-    method public static void bindSocketToInterface(@NonNull java.io.FileDescriptor, @NonNull String) throws android.system.ErrnoException;
-    method public static void closeSocket(@Nullable java.io.FileDescriptor) throws java.io.IOException;
-    method @NonNull public static java.net.SocketAddress makeNetlinkSocketAddress(int, int);
-    method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int);
-    method @Deprecated @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
-    method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int, @NonNull byte[]);
+  public class VcnManager {
+    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void addVcnNetworkPolicyListener(@NonNull java.util.concurrent.Executor, @NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.vcn.VcnNetworkPolicyResult applyVcnNetworkPolicy(@NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties);
+    method public void removeVcnNetworkPolicyListener(@NonNull android.net.vcn.VcnManager.VcnNetworkPolicyListener);
+  }
+
+  public static interface VcnManager.VcnNetworkPolicyListener {
+    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;
   }
 
 }
@@ -7185,7 +6811,7 @@
 
   public final class BugreportManager {
     method @RequiresPermission(android.Manifest.permission.DUMP) public void requestBugreport(@NonNull android.os.BugreportParams, @Nullable CharSequence, @Nullable CharSequence);
-    method @RequiresPermission(android.Manifest.permission.DUMP) public void startBugreport(@NonNull android.os.ParcelFileDescriptor, @Nullable android.os.ParcelFileDescriptor, @NonNull android.os.BugreportParams, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback);
+    method @RequiresPermission(android.Manifest.permission.DUMP) @WorkerThread public void startBugreport(@NonNull android.os.ParcelFileDescriptor, @Nullable android.os.ParcelFileDescriptor, @NonNull android.os.BugreportParams, @NonNull java.util.concurrent.Executor, @NonNull android.os.BugreportManager.BugreportCallback);
   }
 
   public final class BugreportParams {
@@ -10514,6 +10140,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean matchesCurrentSimOperator(@NonNull String, int, @Nullable String);
     method public boolean needsOtaServiceProvisioning();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void notifyOtaEmergencyNumberDbInstalled();
+    method @RequiresPermission(android.Manifest.permission.REBOOT) public int prepareForUnattendedReboot();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
@@ -10579,6 +10206,7 @@
     field public static final int CALL_WAITING_STATUS_ENABLED = 1; // 0x1
     field public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; // 0x4
     field public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; // 0x3
+    field public static final String CAPABILITY_ALLOWED_NETWORK_TYPES_USED = "CAPABILITY_ALLOWED_NETWORK_TYPES_USED";
     field public static final String CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE = "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE";
     field public static final int CARRIER_PRIVILEGE_STATUS_ERROR_LOADING_RULES = -2; // 0xfffffffe
     field public static final int CARRIER_PRIVILEGE_STATUS_HAS_ACCESS = 1; // 0x1
@@ -10633,6 +10261,9 @@
     field public static final int NR_DUAL_CONNECTIVITY_DISABLE = 2; // 0x2
     field public static final int NR_DUAL_CONNECTIVITY_DISABLE_IMMEDIATE = 3; // 0x3
     field public static final int NR_DUAL_CONNECTIVITY_ENABLE = 1; // 0x1
+    field public static final int PREPARE_UNATTENDED_REBOOT_ERROR = 2; // 0x2
+    field public static final int PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED = 1; // 0x1
+    field public static final int PREPARE_UNATTENDED_REBOOT_SUCCESS = 0; // 0x0
     field public static final int RADIO_POWER_OFF = 0; // 0x0
     field public static final int RADIO_POWER_ON = 1; // 0x1
     field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2
@@ -11977,8 +11608,8 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void addOnPublishStateChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.OnPublishStateChangedListener) throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getUcePublishState() throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void removeOnPublishStateChangedListener(@NonNull android.telephony.ims.RcsUceAdapter.OnPublishStateChangedListener) throws android.telephony.ims.ImsException;
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestAvailability(@NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
-    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void requestCapabilities(@NonNull java.util.List<android.net.Uri>, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestAvailability(@NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
+    method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestCapabilities(@NonNull java.util.List<android.net.Uri>, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
     field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
     field public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1; // 0x1
@@ -12263,7 +11894,7 @@
   }
 
   public static interface CapabilityExchangeEventListener.OptionsRequestCallback {
-    method public default void onRespondToCapabilityRequest(@NonNull android.telephony.ims.RcsContactUceCapability, boolean);
+    method public void onRespondToCapabilityRequest(@NonNull android.telephony.ims.RcsContactUceCapability, boolean);
     method public void onRespondToCapabilityRequestWithError(@IntRange(from=100, to=699) int, @NonNull String);
   }
 
@@ -12748,21 +12379,10 @@
 
   public final class UwbManager {
     method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public long elapsedRealtimeResolutionNanos();
-    method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public int getAngleOfArrivalSupport();
-    method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public int getMaxRemoteDevicesPerInitiatorSession();
-    method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public int getMaxRemoteDevicesPerResponderSession();
-    method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public int getMaxSimultaneousSessions();
     method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public android.os.PersistableBundle getSpecificationInfo();
-    method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public java.util.List<java.lang.Integer> getSupportedChannelNumbers();
-    method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public java.util.Set<java.lang.Integer> getSupportedPreambleCodeIndices();
-    method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public boolean isRangingSupported();
     method @NonNull @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public AutoCloseable openRangingSession(@NonNull android.os.PersistableBundle, @NonNull java.util.concurrent.Executor, @NonNull android.uwb.RangingSession.Callback);
     method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void registerAdapterStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.uwb.UwbManager.AdapterStateCallback);
     method @RequiresPermission(android.Manifest.permission.UWB_PRIVILEGED) public void unregisterAdapterStateCallback(@NonNull android.uwb.UwbManager.AdapterStateCallback);
-    field public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D = 2; // 0x2
-    field public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL = 3; // 0x3
-    field public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL = 4; // 0x4
-    field public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE = 1; // 0x1
   }
 
   public static interface UwbManager.AdapterStateCallback {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index bfde2d5..b99d5cd 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -88,7 +88,6 @@
 import android.hardware.display.DisplayManagerGlobal;
 import android.inputmethodservice.InputMethodService;
 import android.net.ConnectivityManager;
-import android.net.IConnectivityManager;
 import android.net.Proxy;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -6546,25 +6545,6 @@
         HardwareRenderer.setDebuggingEnabled(isAppDebuggable || Build.IS_DEBUGGABLE);
         HardwareRenderer.setPackageName(data.appInfo.packageName);
 
-        /**
-         * Initialize the default http proxy in this process for the reasons we set the time zone.
-         */
-        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
-        final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
-        if (b != null) {
-            // In pre-boot mode (doing initial launch to collect password), not
-            // all system is up.  This includes the connectivity service, so don't
-            // crash if we can't get it.
-            final IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
-            try {
-                Proxy.setHttpProxySystemProperty(service.getProxyForNetwork(null));
-            } catch (RemoteException e) {
-                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-                throw e.rethrowFromSystemServer();
-            }
-        }
-        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-
         // Instrumentation info affects the class loader, so load it before
         // setting up the app context.
         final InstrumentationInfo ii;
@@ -6603,6 +6583,23 @@
         updateLocaleListFromAppContext(appContext,
                 mResourcesManager.getConfiguration().getLocales());
 
+        // Initialize the default http proxy in this process.
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Setup proxies");
+        try {
+            // In pre-boot mode (doing initial launch to collect password), not all system is up.
+            // This includes the connectivity service, so trying to obtain ConnectivityManager at
+            // that point would return null. Check whether the ConnectivityService is available, and
+            // avoid crashing with a NullPointerException if it is not.
+            final IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
+            if (b != null) {
+                final ConnectivityManager cm =
+                        appContext.getSystemService(ConnectivityManager.class);
+                Proxy.setHttpProxyConfiguration(cm.getDefaultProxy());
+            }
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        }
+
         if (!Process.isIsolated()) {
             final int oldMask = StrictMode.allowThreadDiskWritesMask();
             try {
@@ -7429,8 +7426,8 @@
     }
 
     public static void updateHttpProxy(@NonNull Context context) {
-        final ConnectivityManager cm = ConnectivityManager.from(context);
-        Proxy.setHttpProxySystemProperty(cm.getDefaultProxy());
+        final ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
+        Proxy.setHttpProxyConfiguration(cm.getDefaultProxy());
     }
 
     @UnsupportedAppUsage
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 797253af..c1d9b90 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2460,9 +2460,9 @@
             false, // READ_MEDIA_AUDIO
             false, // WRITE_MEDIA_AUDIO
             false, // READ_MEDIA_VIDEO
-            false, // WRITE_MEDIA_VIDEO
+            true,  // WRITE_MEDIA_VIDEO
             false, // READ_MEDIA_IMAGES
-            false, // WRITE_MEDIA_IMAGES
+            true,  // WRITE_MEDIA_IMAGES
             true,  // LEGACY_STORAGE
             false, // ACCESS_ACCESSIBILITY
             false, // READ_DEVICE_IDENTIFIERS
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 425073c..17e527d 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -451,6 +451,19 @@
     }
 
     @Override
+    public int getTargetSdkVersion(@NonNull String packageName) throws NameNotFoundException {
+        try {
+            int version = mPM.getTargetSdkVersion(packageName);
+            if (version != -1) {
+                return version;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        throw new PackageManager.NameNotFoundException(packageName);
+    }
+
+    @Override
     public ActivityInfo getActivityInfo(ComponentName className, int flags)
             throws NameNotFoundException {
         final int userId = getUserId();
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index d7eded2..331a0b1 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -43,6 +43,7 @@
 import android.app.usage.NetworkStatsManager;
 import android.app.usage.StorageStatsManager;
 import android.app.usage.UsageStatsManager;
+import android.apphibernation.AppHibernationManager;
 import android.appwidget.AppWidgetManager;
 import android.bluetooth.BluetoothManager;
 import android.companion.CompanionDeviceManager;
@@ -1295,6 +1296,13 @@
                         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
+                    public AppHibernationManager createService(ContextImpl ctx) {
+                        IBinder b = ServiceManager.getService(Context.APP_HIBERNATION_SERVICE);
+                        return b == null ? null : new AppHibernationManager(ctx);
+                    }});
         registerService(Context.DREAM_SERVICE, DreamManager.class,
                 new CachedServiceFetcher<DreamManager>() {
                     @Override
diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java
index cd91aa9..53aaae0 100644
--- a/core/java/android/bluetooth/BluetoothA2dp.java
+++ b/core/java/android/bluetooth/BluetoothA2dp.java
@@ -943,12 +943,13 @@
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
-    public boolean setBufferMillis(@BluetoothCodecConfig.SourceCodecType int codec, int value) {
-        if (VDBG) log("setBufferMillis(" + codec + ", " + value + ")");
+    public boolean setBufferLengthMillis(@BluetoothCodecConfig.SourceCodecType int codec,
+            int value) {
+        if (VDBG) log("setBufferLengthMillis(" + codec + ", " + value + ")");
         try {
             final IBluetoothA2dp service = getService();
             if (service != null && isEnabled()) {
-                return service.setBufferMillis(codec, value);
+                return service.setBufferLengthMillis(codec, value);
             }
             if (service == null) Log.w(TAG, "Proxy not attached to service");
             return false;
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index b7203e3..cc0b22a 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -3565,12 +3565,12 @@
         }
 
         @Override
-        public void onDeviceDisconnected(BluetoothDevice device) {
+        public void onDeviceDisconnected(BluetoothDevice device, int hciReason) {
             for (Map.Entry<BluetoothConnectionCallback, Executor> callbackExecutorEntry:
                     mBluetoothConnectionCallbackExecutorMap.entrySet()) {
                 BluetoothConnectionCallback callback = callbackExecutorEntry.getKey();
                 Executor executor = callbackExecutorEntry.getValue();
-                executor.execute(() -> callback.onDeviceDisconnected(device));
+                executor.execute(() -> callback.onDeviceDisconnected(device, hciReason));
             }
         }
     };
@@ -3665,7 +3665,7 @@
      *
      * @hide
      */
-    public abstract class BluetoothConnectionCallback {
+    public abstract static class BluetoothConnectionCallback {
         /**
          * Callback triggered when a bluetooth device (classic or BLE) is connected
          * @param device is the connected bluetooth device
@@ -3675,8 +3675,155 @@
         /**
          * Callback triggered when a bluetooth device (classic or BLE) is disconnected
          * @param device is the disconnected bluetooth device
+         * @param reason is the disconnect reason
          */
-        public void onDeviceDisconnected(BluetoothDevice device) {}
+        public void onDeviceDisconnected(BluetoothDevice device, @DisconnectReason int reason) {}
+
+        /**
+         * @hide
+         */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(prefix = { "REASON_" }, value = {
+                REASON_UNKNOWN,
+                REASON_LOCAL_REQUEST,
+                REASON_REMOTE_REQUEST,
+                REASON_LOCAL_ERROR,
+                REASON_REMOTE_ERROR,
+                REASON_TIMEOUT,
+                REASON_SECURITY,
+                REASON_SYSTEM_POLICY,
+                REASON_RESOURCE_LIMIT_REACHED,
+                REASON_CONNECTION_EXISTS,
+                REASON_BAD_PARAMETERS})
+        public @interface DisconnectReason {}
+
+        /**
+         * Indicates that the ACL disconnected due to an unknown reason.
+         */
+        public static final int REASON_UNKNOWN = 0;
+
+        /**
+         * Indicates that the ACL disconnected due to an explicit request from the local device.
+         * <p>
+         * Example cause: This is a normal disconnect reason, e.g., user/app initiates
+         * disconnection.
+         */
+        public static final int REASON_LOCAL_REQUEST = 1;
+
+        /**
+         * Indicates that the ACL disconnected due to an explicit request from the remote device.
+         * <p>
+         * Example cause: This is a normal disconnect reason, e.g., user/app initiates
+         * disconnection.
+         * <p>
+         * Example solution: The app can also prompt the user to check their remote device.
+         */
+        public static final int REASON_REMOTE_REQUEST = 2;
+
+        /**
+         * Generic disconnect reason indicating the ACL disconnected due to an error on the local
+         * device.
+         * <p>
+         * Example solution: Prompt the user to check their local device (e.g., phone, car
+         * headunit).
+         */
+        public static final int REASON_LOCAL_ERROR = 3;
+
+        /**
+         * Generic disconnect reason indicating the ACL disconnected due to an error on the remote
+         * device.
+         * <p>
+         * Example solution: Prompt the user to check their remote device (e.g., headset, car
+         * headunit, watch).
+         */
+        public static final int REASON_REMOTE_ERROR = 4;
+
+        /**
+         * Indicates that the ACL disconnected due to a timeout.
+         * <p>
+         * Example cause: remote device might be out of range.
+         * <p>
+         * Example solution: Prompt user to verify their remote device is on or in
+         * connection/pairing mode.
+         */
+        public static final int REASON_TIMEOUT = 5;
+
+        /**
+         * Indicates that the ACL disconnected due to link key issues.
+         * <p>
+         * Example cause: Devices are either unpaired or remote device is refusing our pairing
+         * request.
+         * <p>
+         * Example solution: Prompt user to unpair and pair again.
+         */
+        public static final int REASON_SECURITY = 6;
+
+        /**
+         * Indicates that the ACL disconnected due to the local device's system policy.
+         * <p>
+         * Example cause: privacy policy, power management policy, permissions, etc.
+         * <p>
+         * Example solution: Prompt the user to check settings, or check with their system
+         * administrator (e.g. some corp-managed devices do not allow OPP connection).
+         */
+        public static final int REASON_SYSTEM_POLICY = 7;
+
+        /**
+         * Indicates that the ACL disconnected due to resource constraints, either on the local
+         * device or the remote device.
+         * <p>
+         * Example cause: controller is busy, memory limit reached, maximum number of connections
+         * reached.
+         * <p>
+         * Example solution: The app should wait and try again. If still failing, prompt the user
+         * to disconnect some devices, or toggle Bluetooth on the local and/or the remote device.
+         */
+        public static final int REASON_RESOURCE_LIMIT_REACHED = 8;
+
+        /**
+         * Indicates that the ACL disconnected because another ACL connection already exists.
+         */
+        public static final int REASON_CONNECTION_EXISTS = 9;
+
+        /**
+         * Indicates that the ACL disconnected due to incorrect parameters passed in from the app.
+         * <p>
+         * Example solution: Change parameters and try again. If error persists, the app can report
+         * telemetry and/or log the error in a bugreport.
+         */
+        public static final int REASON_BAD_PARAMETERS = 10;
+
+        /**
+         * Returns human-readable strings corresponding to {@link DisconnectReason}.
+         */
+        public static String disconnectReasonText(@DisconnectReason int reason) {
+            switch (reason) {
+                case REASON_UNKNOWN:
+                    return "Reason unknown";
+                case REASON_LOCAL_REQUEST:
+                    return "Local request";
+                case REASON_REMOTE_REQUEST:
+                    return "Remote request";
+                case REASON_LOCAL_ERROR:
+                    return "Local error";
+                case REASON_REMOTE_ERROR:
+                    return "Remote error";
+                case REASON_TIMEOUT:
+                    return "Timeout";
+                case REASON_SECURITY:
+                    return "Security";
+                case REASON_SYSTEM_POLICY:
+                    return "System policy";
+                case REASON_RESOURCE_LIMIT_REACHED:
+                    return "Resource constrained";
+                case REASON_CONNECTION_EXISTS:
+                    return "Connection already exists";
+                case REASON_BAD_PARAMETERS:
+                    return "Bad parameters";
+                default:
+                    return "Unrecognized disconnect reason: " + reason;
+            }
+        }
     }
 
     /**
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index ff6cffb..0312a21 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -18,7 +18,9 @@
 
 import android.Manifest;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.app.PendingIntent;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -30,6 +32,7 @@
 import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 
 /**
@@ -37,44 +40,60 @@
  *
  * @hide
  */
+@SystemApi
 public final class BluetoothMapClient implements BluetoothProfile {
 
     private static final String TAG = "BluetoothMapClient";
     private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG);
     private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
 
+    /** @hide */
     public static final String ACTION_CONNECTION_STATE_CHANGED =
             "android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED";
+    /** @hide */
     public static final String ACTION_MESSAGE_RECEIVED =
             "android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED";
     /* Actions to be used for pending intents */
+    /** @hide */
     public static final String ACTION_MESSAGE_SENT_SUCCESSFULLY =
             "android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY";
+    /** @hide */
     public static final String ACTION_MESSAGE_DELIVERED_SUCCESSFULLY =
             "android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY";
 
     /**
      * Action to notify read status changed
+     *
+     * @hide
      */
     public static final String ACTION_MESSAGE_READ_STATUS_CHANGED =
             "android.bluetooth.mapmce.profile.action.MESSAGE_READ_STATUS_CHANGED";
 
     /**
      * Action to notify deleted status changed
+     *
+     * @hide
      */
     public static final String ACTION_MESSAGE_DELETED_STATUS_CHANGED =
             "android.bluetooth.mapmce.profile.action.MESSAGE_DELETED_STATUS_CHANGED";
 
-    /* Extras used in ACTION_MESSAGE_RECEIVED intent.
-     * NOTE: HANDLE is only valid for a single session with the device. */
+    /**
+     * Extras used in ACTION_MESSAGE_RECEIVED intent.
+     * NOTE: HANDLE is only valid for a single session with the device.
+     */
+    /** @hide */
     public static final String EXTRA_MESSAGE_HANDLE =
             "android.bluetooth.mapmce.profile.extra.MESSAGE_HANDLE";
+    /** @hide */
     public static final String EXTRA_MESSAGE_TIMESTAMP =
             "android.bluetooth.mapmce.profile.extra.MESSAGE_TIMESTAMP";
+    /** @hide */
     public static final String EXTRA_MESSAGE_READ_STATUS =
             "android.bluetooth.mapmce.profile.extra.MESSAGE_READ_STATUS";
+    /** @hide */
     public static final String EXTRA_SENDER_CONTACT_URI =
             "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_URI";
+    /** @hide */
     public static final String EXTRA_SENDER_CONTACT_NAME =
             "android.bluetooth.mapmce.profile.extra.SENDER_CONTACT_NAME";
 
@@ -84,6 +103,8 @@
      * Possible values are:
      * true: deleted
      * false: undeleted
+     *
+     * @hide
      */
     public static final String EXTRA_MESSAGE_DELETED_STATUS =
             "android.bluetooth.mapmce.profile.extra.MESSAGE_DELETED_STATUS";
@@ -93,24 +114,42 @@
      * Possible values are:
      * 0: failure
      * 1: success
+     *
+     * @hide
      */
     public static final String EXTRA_RESULT_CODE =
             "android.bluetooth.device.extra.RESULT_CODE";
 
-    /** There was an error trying to obtain the state */
+    /**
+     * There was an error trying to obtain the state
+     * @hide
+     */
     public static final int STATE_ERROR = -1;
 
+    /** @hide */
     public static final int RESULT_FAILURE = 0;
+    /** @hide */
     public static final int RESULT_SUCCESS = 1;
-    /** Connection canceled before completion. */
+    /**
+     * Connection canceled before completion.
+     * @hide
+     */
     public static final int RESULT_CANCELED = 2;
-
+    /** @hide */
     private static final int UPLOADING_FEATURE_BITMASK = 0x08;
 
-    /** Parameters in setMessageStatus */
+    /*
+     * UNREAD, READ, UNDELETED, DELETED are passed as parameters
+     * to setMessageStatus to indicate the messages new state.
+     */
+
+    /** @hide */
     public static final int UNREAD = 0;
+    /** @hide */
     public static final int READ = 1;
+    /** @hide */
     public static final int UNDELETED = 2;
+    /** @hide */
     public static final int DELETED = 3;
 
     private BluetoothAdapter mAdapter;
@@ -132,19 +171,12 @@
         mProfileConnector.connect(context, listener);
     }
 
-    protected void finalize() throws Throwable {
-        try {
-            close();
-        } finally {
-            super.finalize();
-        }
-    }
-
     /**
      * Close the connection to the backing service.
      * Other public functions of BluetoothMap will return default error
      * results once close() has been called. Multiple invocations of close()
      * are ok.
+     * @hide
      */
     public void close() {
         mProfileConnector.disconnect();
@@ -158,6 +190,7 @@
      * Returns true if the specified Bluetooth device is connected.
      * Returns false if not connected, or if this proxy object is not
      * currently connected to the Map service.
+     * @hide
      */
     public boolean isConnected(BluetoothDevice device) {
         if (VDBG) Log.d(TAG, "isConnected(" + device + ")");
@@ -225,6 +258,7 @@
      * Get the list of connected devices. Currently at most one.
      *
      * @return list of connected devices
+     * @hide
      */
     @Override
     public List<BluetoothDevice> getConnectedDevices() {
@@ -246,6 +280,7 @@
      * Get the list of devices matching specified states. Currently at most one.
      *
      * @return list of matching devices
+     * @hide
      */
     @Override
     public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
@@ -267,6 +302,7 @@
      * Get connection state of device
      *
      * @return device connection state
+     * @hide
      */
     @Override
     public int getConnectionState(BluetoothDevice device) {
@@ -383,11 +419,44 @@
      * Send an SMS message to either the contacts primary number or the telephone number specified.
      *
      * @param device Bluetooth device
+     * @param contacts Uri Collection of the contacts
+     * @param message Message to be sent
+     * @param sentIntent intent issued when message is sent
+     * @param deliveredIntent intent issued when message is delivered
+     * @return true if the message is enqueued, false on error
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.SEND_SMS)
+    public boolean sendMessage(@NonNull BluetoothDevice device, @NonNull Collection<Uri> contacts,
+            @NonNull String message, @Nullable PendingIntent sentIntent,
+            @Nullable PendingIntent deliveredIntent) {
+        if (DBG) Log.d(TAG, "sendMessage(" + device + ", " + contacts + ", " + message);
+        final IBluetoothMapClient service = getService();
+        if (service != null && isEnabled() && isValidDevice(device)) {
+            try {
+                return service.sendMessage(device, contacts.toArray(new Uri[contacts.size()]),
+                        message, sentIntent, deliveredIntent);
+            } catch (RemoteException e) {
+                Log.e(TAG, Log.getStackTraceString(new Throwable()));
+                return false;
+            }
+        }
+        return false;
+    }
+
+     /**
+     * Send a message.
+     *
+     * Send an SMS message to either the contacts primary number or the telephone number specified.
+     *
+     * @param device Bluetooth device
      * @param contacts Uri[] of the contacts
      * @param message Message to be sent
      * @param sentIntent intent issued when message is sent
      * @param deliveredIntent intent issued when message is delivered
      * @return true if the message is enqueued, false on error
+     * @hide
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public boolean sendMessage(BluetoothDevice device, Uri[] contacts, String message,
@@ -410,6 +479,7 @@
      *
      * @param device Bluetooth device
      * @return true if the message is enqueued, false on error
+     * @hide
      */
     public boolean getUnreadMessages(BluetoothDevice device) {
         if (DBG) Log.d(TAG, "getUnreadMessages(" + device + ")");
@@ -431,6 +501,7 @@
      * @param device The Bluetooth device to get this value for.
      * @return Returns true if the Uploading bit value in SDP record's
      *         MapSupportedFeatures field is set. False is returned otherwise.
+     * @hide
      */
     public boolean isUploadingSupported(BluetoothDevice device) {
         final IBluetoothMapClient service = getService();
@@ -457,7 +528,7 @@
      *            "read", <code>UNDELETED</code> for "undeleted", <code>DELETED</code> for
      *            "deleted", otherwise return error
      * @return <code>true</code> if request has been sent, <code>false</code> on error
-     *
+     * @hide
      */
     @RequiresPermission(Manifest.permission.READ_SMS)
     public boolean setMessageStatus(BluetoothDevice device, String handle, int status) {
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index c31b04e..201d6c4 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -186,6 +186,7 @@
      *
      * @hide
      */
+    @SystemApi
     int MAP_CLIENT = 18;
 
     /**
diff --git a/core/java/android/bluetooth/BufferConstraints.java b/core/java/android/bluetooth/BufferConstraints.java
index 7e5ec1e..97d9723 100644
--- a/core/java/android/bluetooth/BufferConstraints.java
+++ b/core/java/android/bluetooth/BufferConstraints.java
@@ -90,7 +90,7 @@
      * @hide
      */
     @SystemApi
-    public @Nullable BufferConstraint getCodec(@BluetoothCodecConfig.SourceCodecType int codec) {
+    public @Nullable BufferConstraint forCodec(@BluetoothCodecConfig.SourceCodecType int codec) {
         return mBufferConstraints.get(codec);
     }
 }
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index e32068f..6ec1169 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -38,6 +38,8 @@
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.Parcelling;
+import com.android.internal.util.Parcelling.BuiltIn.ForBoolean;
 import com.android.server.SystemConfig;
 
 import java.lang.annotation.Retention;
@@ -56,6 +58,8 @@
  * &lt;application&gt; tag.
  */
 public class ApplicationInfo extends PackageItemInfo implements Parcelable {
+    private static ForBoolean sForBoolean = Parcelling.Cache.getOrCreate(ForBoolean.class);
+
     /**
      * Default task affinity of all activities in this application. See 
      * {@link ActivityInfo#taskAffinity} for more information.  This comes 
@@ -1336,6 +1340,51 @@
     private @GwpAsanMode int gwpAsanMode;
 
     /**
+     * Default (unspecified) setting of Memtag.
+     */
+    public static final int MEMTAG_DEFAULT = -1;
+
+    /**
+     * Do not enable Memtag in this application or process.
+     */
+    public static final int MEMTAG_OFF = 0;
+
+    /**
+     * Enable Memtag in Async mode in this application or process.
+     */
+    public static final int MEMTAG_ASYNC = 1;
+
+    /**
+     * Enable Memtag in Sync mode in this application or process.
+     */
+    public static final int MEMTAG_SYNC = 2;
+
+    /**
+     * These constants need to match the values of memtagMode in application manifest.
+     * @hide
+     */
+    @IntDef(prefix = {"MEMTAG_"}, value = {
+            MEMTAG_DEFAULT,
+            MEMTAG_OFF,
+            MEMTAG_ASYNC,
+            MEMTAG_SYNC,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MemtagMode {}
+
+    /**
+     * Indicates if the application has requested Memtag to be enabled, disabled, or left
+     * unspecified. Processes can override this setting.
+     */
+    private @MemtagMode int memtagMode;
+
+    /**
+     * Enable automatic zero-initialization of native heap memory allocations.
+     */
+    @Nullable
+    private Boolean nativeHeapZeroInit;
+
+    /**
      * Represents the default policy. The actual policy used will depend on other properties of
      * the application, e.g. the target SDK version.
      * @hide
@@ -1479,6 +1528,12 @@
             if (gwpAsanMode != GWP_ASAN_DEFAULT) {
                 pw.println(prefix + "gwpAsanMode=" + gwpAsanMode);
             }
+            if (memtagMode != MEMTAG_DEFAULT) {
+                pw.println(prefix + "memtagMode=" + memtagMode);
+            }
+            if (nativeHeapZeroInit != null) {
+                pw.println(prefix + "nativeHeapZeroInit=" + nativeHeapZeroInit);
+            }
         }
         super.dumpBack(pw, prefix);
     }
@@ -1580,6 +1635,12 @@
             if (gwpAsanMode != GWP_ASAN_DEFAULT) {
                 proto.write(ApplicationInfoProto.Detail.ENABLE_GWP_ASAN, gwpAsanMode);
             }
+            if (memtagMode != MEMTAG_DEFAULT) {
+                proto.write(ApplicationInfoProto.Detail.ENABLE_MEMTAG, memtagMode);
+            }
+            if (nativeHeapZeroInit != null) {
+                proto.write(ApplicationInfoProto.Detail.NATIVE_HEAP_ZERO_INIT, nativeHeapZeroInit);
+            }
             proto.end(detailToken);
         }
         proto.end(token);
@@ -1690,6 +1751,8 @@
         hiddenUntilInstalled = orig.hiddenUntilInstalled;
         zygotePreloadName = orig.zygotePreloadName;
         gwpAsanMode = orig.gwpAsanMode;
+        memtagMode = orig.memtagMode;
+        nativeHeapZeroInit = orig.nativeHeapZeroInit;
     }
 
     public String toString() {
@@ -1774,6 +1837,8 @@
         dest.writeInt(hiddenUntilInstalled ? 1 : 0);
         dest.writeString8(zygotePreloadName);
         dest.writeInt(gwpAsanMode);
+        dest.writeInt(memtagMode);
+        sForBoolean.parcel(nativeHeapZeroInit, dest, parcelableFlags);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<ApplicationInfo> CREATOR
@@ -1855,6 +1920,8 @@
         hiddenUntilInstalled = source.readInt() != 0;
         zygotePreloadName = source.readString8();
         gwpAsanMode = source.readInt();
+        memtagMode = source.readInt();
+        nativeHeapZeroInit = sForBoolean.unparcel(source);
     }
 
     /**
@@ -2237,6 +2304,8 @@
     /** {@hide} */ public void setBaseResourcePath(String baseResourcePath) { publicSourceDir = baseResourcePath; }
     /** {@hide} */ public void setSplitResourcePaths(String[] splitResourcePaths) { splitPublicSourceDirs = splitResourcePaths; }
     /** {@hide} */ public void setGwpAsanMode(@GwpAsanMode int value) { gwpAsanMode = value; }
+    /** {@hide} */ public void setMemtagMode(@MemtagMode int value) { memtagMode = value; }
+    /** {@hide} */ public void setNativeHeapZeroInit(@Nullable Boolean value) { nativeHeapZeroInit = value; }
 
     /** {@hide} */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -2250,4 +2319,8 @@
     /** {@hide} */ public String[] getSplitResourcePaths() { return splitPublicSourceDirs; }
     @GwpAsanMode
     public int getGwpAsanMode() { return gwpAsanMode; }
+    @MemtagMode
+    public int getMemtagMode() { return memtagMode; }
+    @Nullable
+    public Boolean isNativeHeapZeroInit() { return nativeHeapZeroInit; }
 }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 5f8754e..7e082d5 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -82,6 +82,11 @@
     @UnsupportedAppUsage
     ApplicationInfo getApplicationInfo(String packageName, int flags ,int userId);
 
+    /**
+     * @return the target SDK for the given package name, or -1 if it cannot be retrieved
+     */
+    int getTargetSdkVersion(String packageName);
+
     @UnsupportedAppUsage
     ActivityInfo getActivityInfo(in ComponentName className, int flags, int userId);
 
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 443ae35..8744a0e 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4256,6 +4256,15 @@
     }
 
     /**
+     * @return The target SDK version for the given package name.
+     * @throws NameNotFoundException if a package with the given name cannot be found on the system.
+     */
+    @IntRange(from = 0)
+    public int getTargetSdkVersion(@NonNull String packageName) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
      * Retrieve all of the information we know about a particular activity
      * class.
      *
diff --git a/core/java/android/content/pm/ProcessInfo.java b/core/java/android/content/pm/ProcessInfo.java
index d45ff98..3dd5ee1 100644
--- a/core/java/android/content/pm/ProcessInfo.java
+++ b/core/java/android/content/pm/ProcessInfo.java
@@ -53,16 +53,30 @@
      */
     public @ApplicationInfo.GwpAsanMode int gwpAsanMode;
 
+    /**
+     * Indicates if the process has requested Memtag to be enabled (in sync or async mode),
+     * disabled, or left unspecified.
+     */
+    public @ApplicationInfo.MemtagMode int memtagMode;
+
+    /**
+     * Enable automatic zero-initialization of native heap memory allocations.
+     */
+    @Nullable
+    public Boolean nativeHeapZeroInit;
+
     @Deprecated
     public ProcessInfo(@NonNull ProcessInfo orig) {
         this.name = orig.name;
         this.deniedPermissions = orig.deniedPermissions;
         this.gwpAsanMode = orig.gwpAsanMode;
+        this.memtagMode = orig.memtagMode;
+        this.nativeHeapZeroInit = orig.nativeHeapZeroInit;
     }
 
 
 
-    // Code below generated by codegen v1.0.15.
+    // Code below generated by codegen v1.0.22.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -84,12 +98,19 @@
      *   If non-null, these are permissions that are not allowed in this process.
      * @param gwpAsanMode
      *   Indicates if the process has requested GWP-ASan to be enabled, disabled, or left unspecified.
+     * @param memtagMode
+     *   Indicates if the process has requested Memtag to be enabled (in sync or async mode),
+     *   disabled, or left unspecified.
+     * @param nativeHeapZeroInit
+     *   Enable automatic zero-initialization of native heap memory allocations.
      */
     @DataClass.Generated.Member
     public ProcessInfo(
             @NonNull String name,
             @Nullable ArraySet<String> deniedPermissions,
-            @ApplicationInfo.GwpAsanMode int gwpAsanMode) {
+            @ApplicationInfo.GwpAsanMode int gwpAsanMode,
+            @ApplicationInfo.MemtagMode int memtagMode,
+            @Nullable Boolean nativeHeapZeroInit) {
         this.name = name;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, name);
@@ -97,6 +118,10 @@
         this.gwpAsanMode = gwpAsanMode;
         com.android.internal.util.AnnotationValidations.validate(
                 ApplicationInfo.GwpAsanMode.class, null, gwpAsanMode);
+        this.memtagMode = memtagMode;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.MemtagMode.class, null, memtagMode);
+        this.nativeHeapZeroInit = nativeHeapZeroInit;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -120,10 +145,13 @@
 
         byte flg = 0;
         if (deniedPermissions != null) flg |= 0x2;
+        if (nativeHeapZeroInit != null) flg |= 0x10;
         dest.writeByte(flg);
         dest.writeString(name);
         sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags);
         dest.writeInt(gwpAsanMode);
+        dest.writeInt(memtagMode);
+        if (nativeHeapZeroInit != null) dest.writeBoolean(nativeHeapZeroInit);
     }
 
     @Override
@@ -141,6 +169,8 @@
         String _name = in.readString();
         ArraySet<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in);
         int _gwpAsanMode = in.readInt();
+        int _memtagMode = in.readInt();
+        Boolean _nativeHeapZeroInit = (flg & 0x10) == 0 ? null : (Boolean) in.readBoolean();
 
         this.name = _name;
         com.android.internal.util.AnnotationValidations.validate(
@@ -149,6 +179,10 @@
         this.gwpAsanMode = _gwpAsanMode;
         com.android.internal.util.AnnotationValidations.validate(
                 ApplicationInfo.GwpAsanMode.class, null, gwpAsanMode);
+        this.memtagMode = _memtagMode;
+        com.android.internal.util.AnnotationValidations.validate(
+                ApplicationInfo.MemtagMode.class, null, memtagMode);
+        this.nativeHeapZeroInit = _nativeHeapZeroInit;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -168,10 +202,10 @@
     };
 
     @DataClass.Generated(
-            time = 1584555730519L,
-            codegenVersion = "1.0.15",
+            time = 1611614699049L,
+            codegenVersion = "1.0.22",
             sourceFile = "frameworks/base/core/java/android/content/pm/ProcessInfo.java",
-            inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
+            inputSignatures = "public @android.annotation.NonNull java.lang.String name\npublic @android.annotation.Nullable @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringArraySet.class) android.util.ArraySet<java.lang.String> deniedPermissions\npublic @android.content.pm.ApplicationInfo.GwpAsanMode int gwpAsanMode\npublic @android.content.pm.ApplicationInfo.MemtagMode int memtagMode\npublic @android.annotation.Nullable java.lang.Boolean nativeHeapZeroInit\nclass ProcessInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java
index 2ee0ad6..983a02c 100644
--- a/core/java/android/content/pm/parsing/ParsingPackage.java
+++ b/core/java/android/content/pm/parsing/ParsingPackage.java
@@ -241,6 +241,10 @@
 
     ParsingPackage setGwpAsanMode(int gwpAsanMode);
 
+    ParsingPackage setMemtagMode(int memtagMode);
+
+    ParsingPackage setNativeHeapZeroInit(@Nullable Boolean nativeHeapZeroInit);
+
     ParsingPackage setCrossProfile(boolean crossProfile);
 
     ParsingPackage setFullBackupContent(int fullBackupContent);
diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
index f932bc2..ffc78f3 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java
@@ -416,6 +416,11 @@
     private boolean preserveLegacyExternalStorage;
 
     protected int gwpAsanMode;
+    protected int memtagMode;
+
+    @Nullable
+    @DataClass.ParcelWith(ForBoolean.class)
+    private Boolean nativeHeapZeroInit;
 
     // TODO(chiuwinson): Non-null
     @Nullable
@@ -926,6 +931,8 @@
         appInfo.zygotePreloadName = zygotePreloadName;
         appInfo.crossProfile = isCrossProfile();
         appInfo.setGwpAsanMode(gwpAsanMode);
+        appInfo.setMemtagMode(memtagMode);
+        appInfo.setNativeHeapZeroInit(nativeHeapZeroInit);
         appInfo.setBaseCodePath(baseCodePath);
         appInfo.setBaseResourcePath(baseCodePath);
         appInfo.setCodePath(codePath);
@@ -1110,6 +1117,8 @@
         dest.writeArraySet(this.mimeGroups);
         dest.writeInt(this.gwpAsanMode);
         dest.writeSparseIntArray(this.minExtensionVersions);
+        dest.writeInt(this.memtagMode);
+        sForBoolean.parcel(this.nativeHeapZeroInit, dest, flags);
     }
 
     public ParsingPackageImpl(Parcel in) {
@@ -1270,6 +1279,8 @@
         this.mimeGroups = (ArraySet<String>) in.readArraySet(boot);
         this.gwpAsanMode = in.readInt();
         this.minExtensionVersions = in.readSparseIntArray();
+        this.memtagMode = in.readInt();
+        this.nativeHeapZeroInit = sForBoolean.unparcel(in);
     }
 
     public static final Parcelable.Creator<ParsingPackageImpl> CREATOR =
@@ -2003,6 +2014,17 @@
     }
 
     @Override
+    public int getMemtagMode() {
+        return memtagMode;
+    }
+
+    @Nullable
+    @Override
+    public Boolean isNativeHeapZeroInit() {
+        return nativeHeapZeroInit;
+    }
+
+    @Override
     public boolean isPartiallyDirectBootAware() {
         return partiallyDirectBootAware;
     }
@@ -2475,6 +2497,18 @@
     }
 
     @Override
+    public ParsingPackageImpl setMemtagMode(int value) {
+        memtagMode = value;
+        return this;
+    }
+
+    @Override
+    public ParsingPackageImpl setNativeHeapZeroInit(@Nullable Boolean value) {
+        nativeHeapZeroInit = value;
+        return this;
+    }
+
+    @Override
     public ParsingPackageImpl setPartiallyDirectBootAware(boolean value) {
         partiallyDirectBootAware = value;
         return this;
diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java
index 5b53c18..cd91e28 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageRead.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java
@@ -856,6 +856,19 @@
      */
     public int getGwpAsanMode();
 
+    /**
+     * @see ApplicationInfo#memtagMode
+     * @see R.styleable#AndroidManifest_memtagMode
+     */
+    int getMemtagMode();
+
+      /**
+     * @see ApplicationInfo#nativeHeapZeroInit
+     * @see R.styleable#AndroidManifest_nativeHeapZeroInit
+     */
+    @Nullable
+    Boolean isNativeHeapZeroInit();
+
     // TODO(b/135203078): Hide and enforce going through PackageInfoUtils
     ApplicationInfo toAppInfoWithoutState();
 
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index ab0ed51..890ba8a 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -1799,6 +1799,11 @@
             }
 
             pkg.setGwpAsanMode(sa.getInt(R.styleable.AndroidManifestApplication_gwpAsanMode, -1));
+            pkg.setMemtagMode(sa.getInt(R.styleable.AndroidManifestApplication_memtagMode, -1));
+            if (sa.hasValue(R.styleable.AndroidManifestApplication_nativeHeapZeroInit)) {
+                pkg.setNativeHeapZeroInit(sa.getBoolean(
+                        R.styleable.AndroidManifestApplication_nativeHeapZeroInit, false));
+            }
         } finally {
             sa.recycle();
         }
diff --git a/core/java/android/content/pm/parsing/component/ParsedProcess.java b/core/java/android/content/pm/parsing/component/ParsedProcess.java
index e0ae81b..89fef9d 100644
--- a/core/java/android/content/pm/parsing/component/ParsedProcess.java
+++ b/core/java/android/content/pm/parsing/component/ParsedProcess.java
@@ -20,6 +20,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.content.pm.ApplicationInfo;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArraySet;
@@ -41,7 +42,10 @@
     @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedStringSet.class)
     protected Set<String> deniedPermissions = emptySet();
 
-    protected int gwpAsanMode = -1;
+    protected int gwpAsanMode = ApplicationInfo.GWP_ASAN_DEFAULT;
+    protected int memtagMode = ApplicationInfo.MEMTAG_DEFAULT;
+    @Nullable
+    protected Boolean nativeHeapZeroInit = null;
 
     public ParsedProcess() {
     }
@@ -57,7 +61,7 @@
 
 
 
-    // Code below generated by codegen v1.0.15.
+    // Code below generated by codegen v1.0.22.
     //
     // DO NOT MODIFY!
     // CHECKSTYLE:OFF Generated code
@@ -74,7 +78,9 @@
     public ParsedProcess(
             @NonNull String name,
             @NonNull Set<String> deniedPermissions,
-            int gwpAsanMode) {
+            int gwpAsanMode,
+            int memtagMode,
+            @Nullable Boolean nativeHeapZeroInit) {
         this.name = name;
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, name);
@@ -82,6 +88,8 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, deniedPermissions);
         this.gwpAsanMode = gwpAsanMode;
+        this.memtagMode = memtagMode;
+        this.nativeHeapZeroInit = nativeHeapZeroInit;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -102,6 +110,16 @@
     }
 
     @DataClass.Generated.Member
+    public int getMemtagMode() {
+        return memtagMode;
+    }
+
+    @DataClass.Generated.Member
+    public @Nullable Boolean getNativeHeapZeroInit() {
+        return nativeHeapZeroInit;
+    }
+
+    @DataClass.Generated.Member
     static Parcelling<Set<String>> sParcellingForDeniedPermissions =
             Parcelling.Cache.get(
                     Parcelling.BuiltIn.ForInternedStringSet.class);
@@ -118,9 +136,14 @@
         // You can override field parcelling by defining methods like:
         // void parcelFieldName(Parcel dest, int flags) { ... }
 
+        byte flg = 0;
+        if (nativeHeapZeroInit != null) flg |= 0x10;
+        dest.writeByte(flg);
         dest.writeString(name);
         sParcellingForDeniedPermissions.parcel(deniedPermissions, dest, flags);
         dest.writeInt(gwpAsanMode);
+        dest.writeInt(memtagMode);
+        if (nativeHeapZeroInit != null) dest.writeBoolean(nativeHeapZeroInit);
     }
 
     @Override
@@ -134,9 +157,12 @@
         // You can override field unparcelling by defining methods like:
         // static FieldType unparcelFieldName(Parcel in) { ... }
 
+        byte flg = in.readByte();
         String _name = in.readString();
         Set<String> _deniedPermissions = sParcellingForDeniedPermissions.unparcel(in);
         int _gwpAsanMode = in.readInt();
+        int _memtagMode = in.readInt();
+        Boolean _nativeHeapZeroInit = (flg & 0x10) == 0 ? null : (Boolean) in.readBoolean();
 
         this.name = _name;
         com.android.internal.util.AnnotationValidations.validate(
@@ -145,6 +171,8 @@
         com.android.internal.util.AnnotationValidations.validate(
                 NonNull.class, null, deniedPermissions);
         this.gwpAsanMode = _gwpAsanMode;
+        this.memtagMode = _memtagMode;
+        this.nativeHeapZeroInit = _nativeHeapZeroInit;
 
         // onConstructed(); // You can define this method to get a callback
     }
@@ -164,10 +192,10 @@
     };
 
     @DataClass.Generated(
-            time = 1584557524776L,
-            codegenVersion = "1.0.15",
+            time = 1611615591258L,
+            codegenVersion = "1.0.22",
             sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedProcess.java",
-            inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprotected  int gwpAsanMode\npublic  void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
+            inputSignatures = "protected @android.annotation.NonNull java.lang.String name\nprotected @android.annotation.NonNull @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedStringSet.class) java.util.Set<java.lang.String> deniedPermissions\nprotected  int gwpAsanMode\nprotected  int memtagMode\nprotected @android.annotation.Nullable java.lang.Boolean nativeHeapZeroInit\npublic  void addStateFrom(android.content.pm.parsing.component.ParsedProcess)\nclass ParsedProcess extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genGetters=true, genSetters=false, genParcelable=true, genAidl=false, genBuilder=false)")
     @Deprecated
     private void __metadata() {}
 
diff --git a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
index 8372707..082593e 100644
--- a/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
+++ b/core/java/android/content/pm/parsing/component/ParsedProcessUtils.java
@@ -105,6 +105,11 @@
             }
 
             proc.gwpAsanMode = sa.getInt(R.styleable.AndroidManifestProcess_gwpAsanMode, -1);
+            proc.memtagMode = sa.getInt(R.styleable.AndroidManifestProcess_memtagMode, -1);
+            if (sa.hasValue(R.styleable.AndroidManifestProcess_nativeHeapZeroInit)) {
+                proc.nativeHeapZeroInit =
+                        sa.getBoolean(R.styleable.AndroidManifestProcess_nativeHeapZeroInit, false);
+            }
         } finally {
             sa.recycle();
         }
diff --git a/core/java/android/content/pm/verify/domain/OWNERS b/core/java/android/content/pm/verify/domain/OWNERS
new file mode 100644
index 0000000..c669112
--- /dev/null
+++ b/core/java/android/content/pm/verify/domain/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 36137
+
+chiuwinson@google.com
+patb@google.com
+toddke@google.com
\ No newline at end of file
diff --git a/core/java/android/hardware/OWNERS b/core/java/android/hardware/OWNERS
index 3295042..2b4e4a1 100644
--- a/core/java/android/hardware/OWNERS
+++ b/core/java/android/hardware/OWNERS
@@ -3,3 +3,6 @@
 
 # Sensor Privacy
 per-file *SensorPrivacy* = file:platform/frameworks/native:/libs/sensorprivacy/OWNERS
+
+# Sensors framework
+per-file *Sensor*,*Trigger* = file:platform/frameworks/native:/services/sensorservice/OWNERS
diff --git a/core/java/android/hardware/input/OWNERS b/core/java/android/hardware/input/OWNERS
index 25e02e1..c390b33 100644
--- a/core/java/android/hardware/input/OWNERS
+++ b/core/java/android/hardware/input/OWNERS
@@ -1,6 +1,3 @@
 # Bug component: 136048
 
 include /services/core/java/com/android/server/input/OWNERS
-
-michaelwr@google.com
-svv@google.com
diff --git a/core/java/android/hardware/soundtrigger/OWNERS b/core/java/android/hardware/soundtrigger/OWNERS
index 816bc6b..e5d0370 100644
--- a/core/java/android/hardware/soundtrigger/OWNERS
+++ b/core/java/android/hardware/soundtrigger/OWNERS
@@ -1 +1,2 @@
-include /core/java/android/media/soundtrigger/OWNERS
+ytai@google.com
+elaurent@google.com
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityMetricsEvent.aidl b/core/java/android/net/ConnectivityMetricsEvent.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/ConnectivityMetricsEvent.aidl
rename to core/java/android/net/ConnectivityMetricsEvent.aidl
diff --git a/packages/Connectivity/framework/src/android/net/InterfaceConfiguration.aidl b/core/java/android/net/InterfaceConfiguration.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/InterfaceConfiguration.aidl
rename to core/java/android/net/InterfaceConfiguration.aidl
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 32b19a4..303a407 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -18,6 +18,7 @@
 
 import static android.net.ConnectivityManager.TYPE_WIFI;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
 import android.net.wifi.WifiInfo;
@@ -41,6 +42,22 @@
 
     public static final int SUBTYPE_COMBINED = -1;
 
+    /**
+     * Network has no {@code NetworkCapabilities#NET_CAPABILITY_OEM_*}.
+     * @hide
+     */
+    public static final int OEM_NONE = 0x0;
+    /**
+     * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PAID}.
+     * @hide
+     */
+    public static final int OEM_PAID = 0x1;
+    /**
+     * Network has {@link NetworkCapabilities#NET_CAPABILITY_OEM_PRIVATE}.
+     * @hide
+     */
+    public static final int OEM_PRIVATE = 0x2;
+
     final int mType;
     final int mSubType;
     final String mSubscriberId;
@@ -48,10 +65,11 @@
     final boolean mRoaming;
     final boolean mMetered;
     final boolean mDefaultNetwork;
+    final int mOemManaged;
 
     public NetworkIdentity(
             int type, int subType, String subscriberId, String networkId, boolean roaming,
-            boolean metered, boolean defaultNetwork) {
+            boolean metered, boolean defaultNetwork, int oemManaged) {
         mType = type;
         mSubType = subType;
         mSubscriberId = subscriberId;
@@ -59,12 +77,13 @@
         mRoaming = roaming;
         mMetered = metered;
         mDefaultNetwork = defaultNetwork;
+        mOemManaged = oemManaged;
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mType, mSubType, mSubscriberId, mNetworkId, mRoaming, mMetered,
-                mDefaultNetwork);
+                mDefaultNetwork, mOemManaged);
     }
 
     @Override
@@ -75,7 +94,8 @@
                     && Objects.equals(mSubscriberId, ident.mSubscriberId)
                     && Objects.equals(mNetworkId, ident.mNetworkId)
                     && mMetered == ident.mMetered
-                    && mDefaultNetwork == ident.mDefaultNetwork;
+                    && mDefaultNetwork == ident.mDefaultNetwork
+                    && mOemManaged == ident.mOemManaged;
         }
         return false;
     }
@@ -102,6 +122,8 @@
         }
         builder.append(", metered=").append(mMetered);
         builder.append(", defaultNetwork=").append(mDefaultNetwork);
+        // TODO(180557699): Print a human readable string for OEM managed state.
+        builder.append(", oemManaged=").append(mOemManaged);
         return builder.append("}").toString();
     }
 
@@ -120,6 +142,7 @@
         proto.write(NetworkIdentityProto.ROAMING, mRoaming);
         proto.write(NetworkIdentityProto.METERED, mMetered);
         proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork);
+        proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged);
 
         proto.end(start);
     }
@@ -152,6 +175,10 @@
         return mDefaultNetwork;
     }
 
+    public int getOemManaged() {
+        return mOemManaged;
+    }
+
     /**
      * Build a {@link NetworkIdentity} from the given {@link NetworkState} and {@code subType},
      * assuming that any mobile networks are using the current IMSI. The subType if applicable,
@@ -171,6 +198,8 @@
 
         subscriberId = state.subscriberId;
 
+        final int oemManaged = getOemBitfield(state.networkCapabilities);
+
         if (legacyType == TYPE_WIFI) {
             if (state.networkCapabilities.getSsid() != null) {
                 networkId = state.networkCapabilities.getSsid();
@@ -185,7 +214,24 @@
         }
 
         return new NetworkIdentity(legacyType, subType, subscriberId, networkId, roaming, metered,
-                defaultNetwork);
+                defaultNetwork, oemManaged);
+    }
+
+    /**
+     * Builds a bitfield of {@code NetworkIdentity.OEM_*} based on {@link NetworkCapabilities}.
+     * @hide
+     */
+    public static int getOemBitfield(NetworkCapabilities nc) {
+        int oemManaged = OEM_NONE;
+
+        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID)) {
+            oemManaged |= OEM_PAID;
+        }
+        if (nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE)) {
+            oemManaged |= OEM_PRIVATE;
+        }
+
+        return oemManaged;
     }
 
     @Override
@@ -209,6 +255,9 @@
         if (res == 0) {
             res = Boolean.compare(mDefaultNetwork, another.mDefaultNetwork);
         }
+        if (res == 0) {
+            res = Integer.compare(mOemManaged, another.mOemManaged);
+        }
         return res;
     }
 }
diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java
index 79f9e6e..dbb3127 100644
--- a/core/java/android/net/NetworkStack.java
+++ b/core/java/android/net/NetworkStack.java
@@ -15,9 +15,6 @@
  */
 package android.net;
 
-import static android.Manifest.permission.NETWORK_STACK;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -26,8 +23,7 @@
 import android.os.IBinder;
 import android.os.ServiceManager;
 
-import java.util.ArrayList;
-import java.util.Arrays;
+import com.android.net.module.util.PermissionUtils;
 /**
  * Constants and utilities for client code communicating with the network stack service.
  * @hide
@@ -79,9 +75,14 @@
      * @param context {@link android.content.Context} for the process.
      *
      * @hide
+     *
+     * @deprecated Use {@link PermissionUtils#enforceNetworkStackPermission} instead.
+     *
+     * TODO: remove this method and let the users call to PermissionUtils directly.
      */
+    @Deprecated
     public static void checkNetworkStackPermission(final @NonNull Context context) {
-        checkNetworkStackPermissionOr(context);
+        PermissionUtils.enforceNetworkStackPermission(context);
     }
 
     /**
@@ -92,31 +93,14 @@
      * @param otherPermissions The set of permissions that could be the candidate permissions , or
      *                         empty string if none of other permissions needed.
      * @hide
+     *
+     * @deprecated Use {@link PermissionUtils#enforceNetworkStackPermissionOr} instead.
+     *
+     * TODO: remove this method and let the users call to PermissionUtils directly.
      */
+    @Deprecated
     public static void checkNetworkStackPermissionOr(final @NonNull Context context,
             final @NonNull String... otherPermissions) {
-        ArrayList<String> permissions = new ArrayList<String>(Arrays.asList(otherPermissions));
-        permissions.add(NETWORK_STACK);
-        permissions.add(PERMISSION_MAINLINE_NETWORK_STACK);
-        enforceAnyPermissionOf(context, permissions.toArray(new String[0]));
+        PermissionUtils.enforceNetworkStackPermissionOr(context, otherPermissions);
     }
-
-    private static void enforceAnyPermissionOf(final @NonNull Context context,
-            final @NonNull String... permissions) {
-        if (!checkAnyPermissionOf(context, permissions)) {
-            throw new SecurityException("Requires one of the following permissions: "
-                + String.join(", ", permissions) + ".");
-        }
-    }
-
-    private static boolean checkAnyPermissionOf(final @NonNull Context context,
-            final @NonNull String... permissions) {
-        for (String permission : permissions) {
-            if (context.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
-                return true;
-            }
-        }
-        return false;
-    }
-
 }
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index e466d2e..813fde1 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -41,7 +41,6 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public final Network network;
     public final String subscriberId;
-    public final String networkId;
     public final int legacyNetworkType;
 
     private NetworkState() {
@@ -50,35 +49,33 @@
         networkCapabilities = null;
         network = null;
         subscriberId = null;
-        networkId = null;
         legacyNetworkType = 0;
     }
 
     public NetworkState(int legacyNetworkType, @NonNull LinkProperties linkProperties,
             @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
-            @Nullable String subscriberId, @Nullable String networkId) {
+            @Nullable String subscriberId) {
         this(legacyNetworkType, new NetworkInfo(legacyNetworkType, 0, null, null), linkProperties,
-                networkCapabilities, network, subscriberId, networkId);
+                networkCapabilities, network, subscriberId);
     }
 
     // Constructor that used internally in ConnectivityService mainline module.
     public NetworkState(@NonNull NetworkInfo networkInfo, @NonNull LinkProperties linkProperties,
             @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
-            String subscriberId, String networkId) {
+            @Nullable String subscriberId) {
         this(networkInfo.getType(), networkInfo, linkProperties,
-                networkCapabilities, network, subscriberId, networkId);
+                networkCapabilities, network, subscriberId);
     }
 
     public NetworkState(int legacyNetworkType, @NonNull NetworkInfo networkInfo,
             @NonNull LinkProperties linkProperties,
             @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
-            String subscriberId, String networkId) {
+            @Nullable String subscriberId) {
         this.networkInfo = networkInfo;
         this.linkProperties = linkProperties;
         this.networkCapabilities = networkCapabilities;
         this.network = network;
         this.subscriberId = subscriberId;
-        this.networkId = networkId;
         this.legacyNetworkType = legacyNetworkType;
 
         // This object is an atomic view of a network, so the various components
@@ -99,7 +96,6 @@
         networkCapabilities = in.readParcelable(null);
         network = in.readParcelable(null);
         subscriberId = in.readString();
-        networkId = in.readString();
         legacyNetworkType = in.readInt();
     }
 
@@ -115,7 +111,6 @@
         out.writeParcelable(networkCapabilities, flags);
         out.writeParcelable(network, flags);
         out.writeString(subscriberId);
-        out.writeString(networkId);
         out.writeInt(legacyNetworkType);
     }
 
diff --git a/core/java/android/net/NetworkStateSnapshot.aidl b/core/java/android/net/NetworkStateSnapshot.aidl
new file mode 100644
index 0000000..cb602d79
--- /dev/null
+++ b/core/java/android/net/NetworkStateSnapshot.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2021, 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.net;
+
+parcelable NetworkStateSnapshot;
diff --git a/core/java/android/net/NetworkStateSnapshot.java b/core/java/android/net/NetworkStateSnapshot.java
new file mode 100644
index 0000000..881b373
--- /dev/null
+++ b/core/java/android/net/NetworkStateSnapshot.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2021 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.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Snapshot of network state.
+ *
+ * @hide
+ */
+public final class NetworkStateSnapshot implements Parcelable {
+    @NonNull
+    public final LinkProperties linkProperties;
+    @NonNull
+    public final NetworkCapabilities networkCapabilities;
+    @NonNull
+    public final Network network;
+    @Nullable
+    public final String subscriberId;
+    public final int legacyType;
+
+    public NetworkStateSnapshot(@NonNull LinkProperties linkProperties,
+            @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
+            @Nullable String subscriberId, int legacyType) {
+        this.linkProperties = Objects.requireNonNull(linkProperties);
+        this.networkCapabilities = Objects.requireNonNull(networkCapabilities);
+        this.network = Objects.requireNonNull(network);
+        this.subscriberId = subscriberId;
+        this.legacyType = legacyType;
+    }
+
+    public NetworkStateSnapshot(@NonNull Parcel in) {
+        linkProperties = in.readParcelable(null);
+        networkCapabilities = in.readParcelable(null);
+        network = in.readParcelable(null);
+        subscriberId = in.readString();
+        legacyType = in.readInt();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel out, int flags) {
+        out.writeParcelable(linkProperties, flags);
+        out.writeParcelable(networkCapabilities, flags);
+        out.writeParcelable(network, flags);
+        out.writeString(subscriberId);
+        out.writeInt(legacyType);
+    }
+
+    @NonNull
+    public static final Creator<NetworkStateSnapshot> CREATOR =
+            new Creator<NetworkStateSnapshot>() {
+        @NonNull
+        @Override
+        public NetworkStateSnapshot createFromParcel(@NonNull Parcel in) {
+            return new NetworkStateSnapshot(in);
+        }
+
+        @NonNull
+        @Override
+        public NetworkStateSnapshot[] newArray(int size) {
+            return new NetworkStateSnapshot[size];
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof NetworkStateSnapshot)) return false;
+        NetworkStateSnapshot that = (NetworkStateSnapshot) o;
+        return legacyType == that.legacyType
+                && Objects.equals(linkProperties, that.linkProperties)
+                && Objects.equals(networkCapabilities, that.networkCapabilities)
+                && Objects.equals(network, that.network)
+                && Objects.equals(subscriberId, that.subscriberId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(linkProperties, networkCapabilities, network, subscriberId, legacyType);
+    }
+}
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index aa61e03..c83dd99 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -23,6 +23,7 @@
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
+import static android.net.NetworkIdentity.OEM_NONE;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
 import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
 import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
@@ -99,6 +100,22 @@
      */
     public static final int NETWORK_TYPE_5G_NSA = -2;
 
+    /**
+     * Value to match both OEM managed and unmanaged networks (all networks).
+     * @hide
+     */
+    public static final int OEM_MANAGED_ALL = -1;
+    /**
+     * Value to match networks which are not OEM managed.
+     * @hide
+     */
+    public static final int OEM_MANAGED_NO = OEM_NONE;
+    /**
+     * Value to match any OEM managed network.
+     * @hide
+     */
+    public static final int OEM_MANAGED_YES = -2;
+
     private static boolean isKnownMatchRule(final int rule) {
         switch (rule) {
             case MATCH_MOBILE:
@@ -151,10 +168,10 @@
             @NetworkType int ratType) {
         if (TextUtils.isEmpty(subscriberId)) {
             return new NetworkTemplate(MATCH_MOBILE_WILDCARD, null, null, null,
-                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType);
+                    METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL);
         }
         return new NetworkTemplate(MATCH_MOBILE, subscriberId, new String[]{subscriberId}, null,
-                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType);
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, ratType, OEM_MANAGED_ALL);
     }
 
     /**
@@ -235,6 +252,9 @@
     private final int mDefaultNetwork;
     private final int mSubType;
 
+    // Bitfield containing OEM network properties{@code NetworkIdentity#OEM_*}.
+    private final int mOemManaged;
+
     @UnsupportedAppUsage
     public NetworkTemplate(int matchRule, String subscriberId, String networkId) {
         this(matchRule, subscriberId, new String[] { subscriberId }, networkId);
@@ -243,11 +263,12 @@
     public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
             String networkId) {
         this(matchRule, subscriberId, matchSubscriberIds, networkId, METERED_ALL, ROAMING_ALL,
-                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL);
+                DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_ALL);
     }
 
     public NetworkTemplate(int matchRule, String subscriberId, String[] matchSubscriberIds,
-            String networkId, int metered, int roaming, int defaultNetwork, int subType) {
+            String networkId, int metered, int roaming, int defaultNetwork, int subType,
+            int oemManaged) {
         mMatchRule = matchRule;
         mSubscriberId = subscriberId;
         mMatchSubscriberIds = matchSubscriberIds;
@@ -256,6 +277,7 @@
         mRoaming = roaming;
         mDefaultNetwork = defaultNetwork;
         mSubType = subType;
+        mOemManaged = oemManaged;
 
         if (!isKnownMatchRule(matchRule)) {
             Log.e(TAG, "Unknown network template rule " + matchRule
@@ -272,6 +294,7 @@
         mRoaming = in.readInt();
         mDefaultNetwork = in.readInt();
         mSubType = in.readInt();
+        mOemManaged = in.readInt();
     }
 
     @Override
@@ -284,6 +307,7 @@
         dest.writeInt(mRoaming);
         dest.writeInt(mDefaultNetwork);
         dest.writeInt(mSubType);
+        dest.writeInt(mOemManaged);
     }
 
     @Override
@@ -319,13 +343,16 @@
         if (mSubType != NETWORK_TYPE_ALL) {
             builder.append(", subType=").append(mSubType);
         }
+        if (mOemManaged != OEM_MANAGED_ALL) {
+            builder.append(", oemManaged=").append(mOemManaged);
+        }
         return builder.toString();
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mMatchRule, mSubscriberId, mNetworkId, mMetered, mRoaming,
-                mDefaultNetwork, mSubType);
+                mDefaultNetwork, mSubType, mOemManaged);
     }
 
     @Override
@@ -338,7 +365,8 @@
                     && mMetered == other.mMetered
                     && mRoaming == other.mRoaming
                     && mDefaultNetwork == other.mDefaultNetwork
-                    && mSubType == other.mSubType;
+                    && mSubType == other.mSubType
+                    && mOemManaged == other.mOemManaged;
         }
         return false;
     }
@@ -384,6 +412,7 @@
         if (!matchesMetered(ident)) return false;
         if (!matchesRoaming(ident)) return false;
         if (!matchesDefaultNetwork(ident)) return false;
+        if (!matchesOemNetwork(ident)) return false;
 
         switch (mMatchRule) {
             case MATCH_MOBILE:
@@ -425,6 +454,13 @@
             || (mDefaultNetwork == DEFAULT_NETWORK_NO && !ident.mDefaultNetwork);
     }
 
+    private boolean matchesOemNetwork(NetworkIdentity ident) {
+        return (mOemManaged == OEM_MANAGED_ALL)
+            || (mOemManaged == OEM_MANAGED_YES
+                    && ident.mOemManaged != OEM_NONE)
+            || (mOemManaged == ident.mOemManaged);
+    }
+
     private boolean matchesCollapsedRatType(NetworkIdentity ident) {
         return mSubType == NETWORK_TYPE_ALL
                 || getCollapsedRatType(mSubType) == getCollapsedRatType(ident.mSubType);
diff --git a/core/java/android/net/NetworkWatchlistManager.java b/core/java/android/net/NetworkWatchlistManager.java
index 49047d3..8f6510e 100644
--- a/core/java/android/net/NetworkWatchlistManager.java
+++ b/core/java/android/net/NetworkWatchlistManager.java
@@ -16,6 +16,8 @@
 
 package android.net;
 
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
 import android.os.RemoteException;
@@ -29,6 +31,7 @@
  * Class that manage network watchlist in system.
  * @hide
  */
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
 @SystemService(Context.NETWORK_WATCHLIST_SERVICE)
 public class NetworkWatchlistManager {
 
@@ -90,6 +93,7 @@
     /**
      * Get Network Watchlist config file hash.
      */
+    @Nullable
     public byte[] getWatchlistConfigHash() {
         try {
             return mNetworkWatchlistManager.getWatchlistConfigHash();
diff --git a/packages/Connectivity/framework/src/android/net/UidRange.aidl b/core/java/android/net/UidRange.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/UidRange.aidl
rename to core/java/android/net/UidRange.aidl
diff --git a/core/java/android/net/UidRange.java b/core/java/android/net/UidRange.java
index b172ccc..f0e7da7 100644
--- a/core/java/android/net/UidRange.java
+++ b/core/java/android/net/UidRange.java
@@ -42,10 +42,6 @@
         stop  = stopUid;
     }
 
-    public static UidRange createForUser(int userId) {
-        return new UidRange(userId * PER_USER_RANGE, (userId + 1) * PER_USER_RANGE - 1);
-    }
-
     /** Creates a UidRange for the specified user. */
     public static UidRange createForUser(UserHandle user) {
         final UserHandle nextUser = UserHandle.of(user.getIdentifier() + 1);
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index e43b0b6..f90fbaf 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -596,7 +596,8 @@
                     }
                 }
             }
-            mRoutes.add(new RouteInfo(new IpPrefix(address, prefixLength), null));
+            mRoutes.add(new RouteInfo(new IpPrefix(address, prefixLength), null, null,
+                RouteInfo.RTN_UNICAST));
             mConfig.updateAllowedFamilies(address);
             return this;
         }
diff --git a/core/java/android/net/vcn/IVcnStatusCallback.aidl b/core/java/android/net/vcn/IVcnStatusCallback.aidl
index 555e9b5..d91cef5 100644
--- a/core/java/android/net/vcn/IVcnStatusCallback.aidl
+++ b/core/java/android/net/vcn/IVcnStatusCallback.aidl
@@ -17,8 +17,9 @@
 package android.net.vcn;
 
 /** @hide */
-interface IVcnStatusCallback {
+oneway interface IVcnStatusCallback {
     void onEnteredSafeMode();
+    void onVcnStatusChanged(int statusCode);
     void onGatewayConnectionError(
             in int[] gatewayNetworkCapabilities,
             int errorCode,
diff --git a/core/java/android/net/vcn/VcnManager.java b/core/java/android/net/vcn/VcnManager.java
index aea0ea9..eb8c251 100644
--- a/core/java/android/net/vcn/VcnManager.java
+++ b/core/java/android/net/vcn/VcnManager.java
@@ -21,6 +21,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.content.Context;
 import android.net.LinkProperties;
@@ -72,8 +73,7 @@
 public class VcnManager {
     @NonNull private static final String TAG = VcnManager.class.getSimpleName();
 
-    private static final Map<
-                    VcnUnderlyingNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
+    private static final Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
             REGISTERED_POLICY_LISTENERS = new ConcurrentHashMap<>();
 
     @NonNull private final Context mContext;
@@ -93,13 +93,13 @@
     }
 
     /**
-     * Get all currently registered VcnUnderlyingNetworkPolicyListeners for testing purposes.
+     * Get all currently registered VcnNetworkPolicyListeners for testing purposes.
      *
      * @hide
      */
     @VisibleForTesting(visibility = Visibility.PRIVATE)
     @NonNull
-    public static Map<VcnUnderlyingNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
+    public static Map<VcnNetworkPolicyListener, VcnUnderlyingNetworkPolicyListenerBinder>
             getAllPolicyListeners() {
         return Collections.unmodifiableMap(REGISTERED_POLICY_LISTENERS);
     }
@@ -161,22 +161,15 @@
         }
     }
 
-    // TODO: make VcnUnderlyingNetworkPolicyListener @SystemApi
+    // TODO(b/180537630): remove all VcnUnderlyingNetworkPolicyListener refs once Telephony is using
+    // the new VcnNetworkPolicyListener API
     /**
      * VcnUnderlyingNetworkPolicyListener is the interface through which internal system components
      * can register to receive updates for VCN-underlying Network policies from the System Server.
      *
      * @hide
      */
-    public interface VcnUnderlyingNetworkPolicyListener {
-        /**
-         * Notifies the implementation that the VCN's underlying Network policy has changed.
-         *
-         * <p>After receiving this callback, implementations MUST poll VcnManager for the updated
-         * VcnUnderlyingNetworkPolicy via VcnManager#getUnderlyingNetworkPolicy.
-         */
-        void onPolicyChanged();
-    }
+    public interface VcnUnderlyingNetworkPolicyListener extends VcnNetworkPolicyListener {}
 
     /**
      * Add a listener for VCN-underlying network policy updates.
@@ -185,29 +178,14 @@
      *     Listener
      * @param listener the VcnUnderlyingNetworkPolicyListener to be added
      * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
-     * @throws IllegalArgumentException if the specified VcnUnderlyingNetworkPolicyListener is
-     *     already registered
+     * @throws IllegalStateException if the specified VcnUnderlyingNetworkPolicyListener is already
+     *     registered
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
     public void addVcnUnderlyingNetworkPolicyListener(
             @NonNull Executor executor, @NonNull VcnUnderlyingNetworkPolicyListener listener) {
-        requireNonNull(executor, "executor must not be null");
-        requireNonNull(listener, "listener must not be null");
-
-        VcnUnderlyingNetworkPolicyListenerBinder binder =
-                new VcnUnderlyingNetworkPolicyListenerBinder(executor, listener);
-        if (REGISTERED_POLICY_LISTENERS.putIfAbsent(listener, binder) != null) {
-            throw new IllegalArgumentException(
-                    "Attempting to add a listener that is already in use");
-        }
-
-        try {
-            mService.addVcnUnderlyingNetworkPolicyListener(binder);
-        } catch (RemoteException e) {
-            REGISTERED_POLICY_LISTENERS.remove(listener);
-            throw e.rethrowFromSystemServer();
-        }
+        addVcnNetworkPolicyListener(executor, listener);
     }
 
     /**
@@ -220,19 +198,7 @@
      */
     public void removeVcnUnderlyingNetworkPolicyListener(
             @NonNull VcnUnderlyingNetworkPolicyListener listener) {
-        requireNonNull(listener, "listener must not be null");
-
-        VcnUnderlyingNetworkPolicyListenerBinder binder =
-                REGISTERED_POLICY_LISTENERS.remove(listener);
-        if (binder == null) {
-            return;
-        }
-
-        try {
-            mService.removeVcnUnderlyingNetworkPolicyListener(binder);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
+        removeVcnNetworkPolicyListener(listener);
     }
 
     /**
@@ -266,6 +232,170 @@
         }
     }
 
+    /**
+     * VcnNetworkPolicyListener is the interface through which internal system components (e.g.
+     * Network Factories) can register to receive updates for VCN-underlying Network policies from
+     * the System Server.
+     *
+     * <p>Any Network Factory that brings up Networks capable of being VCN-underlying Networks
+     * should register a VcnNetworkPolicyListener. VcnManager will then use this listener to notify
+     * the registrant when VCN Network policies change. Upon receiving this signal, the listener
+     * must check {@link VcnManager} for the current Network policy result for each of its Networks
+     * via {@link #applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}.
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface VcnNetworkPolicyListener {
+        /**
+         * Notifies the implementation that the VCN's underlying Network policy has changed.
+         *
+         * <p>After receiving this callback, implementations should get the current {@link
+         * VcnNetworkPolicyResult} via {@link #applyVcnNetworkPolicy(NetworkCapabilities,
+         * LinkProperties)}.
+         */
+        void onPolicyChanged();
+    }
+
+    /**
+     * Add a listener for VCN-underlying Network policy updates.
+     *
+     * <p>A {@link VcnNetworkPolicyListener} is eligible to begin receiving callbacks once it is
+     * registered. No callbacks are guaranteed upon registration.
+     *
+     * @param executor the Executor that will be used for invoking all calls to the specified
+     *     Listener
+     * @param listener the VcnNetworkPolicyListener to be added
+     * @throws SecurityException if the caller does not have permission NETWORK_FACTORY
+     * @throws IllegalStateException if the specified VcnNetworkPolicyListener is already registered
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+    public void addVcnNetworkPolicyListener(
+            @NonNull Executor executor, @NonNull VcnNetworkPolicyListener listener) {
+        requireNonNull(executor, "executor must not be null");
+        requireNonNull(listener, "listener must not be null");
+
+        VcnUnderlyingNetworkPolicyListenerBinder binder =
+                new VcnUnderlyingNetworkPolicyListenerBinder(executor, listener);
+        if (REGISTERED_POLICY_LISTENERS.putIfAbsent(listener, binder) != null) {
+            throw new IllegalStateException("listener is already registered with VcnManager");
+        }
+
+        try {
+            mService.addVcnUnderlyingNetworkPolicyListener(binder);
+        } catch (RemoteException e) {
+            REGISTERED_POLICY_LISTENERS.remove(listener);
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Remove the specified VcnNetworkPolicyListener from VcnManager.
+     *
+     * <p>If the specified listener is not currently registered, this is a no-op.
+     *
+     * @param listener the VcnNetworkPolicyListener that will be removed
+     * @hide
+     */
+    @SystemApi
+    public void removeVcnNetworkPolicyListener(@NonNull VcnNetworkPolicyListener listener) {
+        requireNonNull(listener, "listener must not be null");
+
+        VcnUnderlyingNetworkPolicyListenerBinder binder =
+                REGISTERED_POLICY_LISTENERS.remove(listener);
+        if (binder == null) {
+            return;
+        }
+
+        try {
+            mService.removeVcnUnderlyingNetworkPolicyListener(binder);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Applies the network policy for a {@link android.net.Network} with the given parameters.
+     *
+     * <p>Prior to a new NetworkAgent being registered, or upon notification that Carrier VCN policy
+     * may have changed via {@link VcnNetworkPolicyListener#onPolicyChanged()}, a Network Provider
+     * MUST poll for the updated Network policy based on that Network's capabilities and properties.
+     *
+     * @param networkCapabilities the NetworkCapabilities to be used in determining the Network
+     *     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
+     * @return the {@link VcnNetworkPolicyResult} to be used for this Network.
+     * @hide
+     */
+    @NonNull
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY)
+    public VcnNetworkPolicyResult applyVcnNetworkPolicy(
+            @NonNull NetworkCapabilities networkCapabilities,
+            @NonNull LinkProperties linkProperties) {
+        requireNonNull(networkCapabilities, "networkCapabilities must not be null");
+        requireNonNull(linkProperties, "linkProperties must not be null");
+
+        final VcnUnderlyingNetworkPolicy policy =
+                getUnderlyingNetworkPolicy(networkCapabilities, linkProperties);
+        return new VcnNetworkPolicyResult(
+                policy.isTeardownRequested(), policy.getMergedNetworkCapabilities());
+    }
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        VCN_STATUS_CODE_NOT_CONFIGURED,
+        VCN_STATUS_CODE_INACTIVE,
+        VCN_STATUS_CODE_ACTIVE,
+        VCN_STATUS_CODE_SAFE_MODE
+    })
+    public @interface VcnStatusCode {}
+
+    /**
+     * Value indicating that the VCN for the subscription group is not configured, or that the
+     * callback is not privileged for the subscription group.
+     *
+     * @hide
+     */
+    public static final int VCN_STATUS_CODE_NOT_CONFIGURED = 0;
+
+    /**
+     * Value indicating that the VCN for the subscription group is inactive.
+     *
+     * <p>A VCN is inactive if a {@link VcnConfig} is present for the subscription group, but the
+     * provisioning package is not privileged.
+     *
+     * @hide
+     */
+    public static final int VCN_STATUS_CODE_INACTIVE = 1;
+
+    /**
+     * Value indicating that the VCN for the subscription group is active.
+     *
+     * <p>A VCN is active if a {@link VcnConfig} is present for the subscription, the provisioning
+     * package is privileged, and the VCN is not in Safe Mode. In other words, a VCN is considered
+     * active while it is connecting, fully connected, and disconnecting.
+     *
+     * @hide
+     */
+    public static final int VCN_STATUS_CODE_ACTIVE = 2;
+
+    /**
+     * Value indicating that the VCN for the subscription group is in Safe Mode.
+     *
+     * <p>A VCN will be put into Safe Mode if any of the gateway connections were unable to
+     * establish a connection within a system-determined timeout (while underlying networks were
+     * available).
+     *
+     * @hide
+     */
+    public static final int VCN_STATUS_CODE_SAFE_MODE = 3;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({
@@ -323,8 +453,18 @@
          *
          * <p>A VCN-configuring app may opt to exit safe mode by (re)setting the VCN configuration
          * via {@link #setVcnConfig(ParcelUuid, VcnConfig)}.
+         *
+         * @hide
          */
-        public abstract void onEnteredSafeMode();
+        public void onEnteredSafeMode() {}
+
+        /**
+         * Invoked when status of the VCN for this callback's subscription group changes.
+         *
+         * @param statusCode the code for the status change encountered by this {@link
+         *     VcnStatusCallback}'s subscription group.
+         */
+        public abstract void onVcnStatusChanged(@VcnStatusCode int statusCode);
 
         /**
          * Invoked when a VCN Gateway Connection corresponding to this callback's subscription
@@ -356,6 +496,11 @@
      * <p>A {@link VcnStatusCallback} will only be invoked if the registering package has carrier
      * privileges for the specified subscription at the time of invocation.
      *
+     * <p>{@link VcnStatusCallback#onVcnStatusChanged(int)} will be invoked on registration with the
+     * current status for the specified subscription group's VCN. If the registrant is not
+     * privileged for this subscription group, {@link #VCN_STATUS_CODE_NOT_CONFIGURED} will be
+     * returned.
+     *
      * @param subscriptionGroup The subscription group to match for callbacks
      * @param executor The {@link Executor} to be used for invoking callbacks
      * @param callback The VcnStatusCallback to be registered
@@ -415,18 +560,17 @@
     }
 
     /**
-     * Binder wrapper for added VcnUnderlyingNetworkPolicyListeners to receive signals from System
-     * Server.
+     * Binder wrapper for added VcnNetworkPolicyListeners to receive signals from System Server.
      *
      * @hide
      */
     private static class VcnUnderlyingNetworkPolicyListenerBinder
             extends IVcnUnderlyingNetworkPolicyListener.Stub {
         @NonNull private final Executor mExecutor;
-        @NonNull private final VcnUnderlyingNetworkPolicyListener mListener;
+        @NonNull private final VcnNetworkPolicyListener mListener;
 
         private VcnUnderlyingNetworkPolicyListenerBinder(
-                Executor executor, VcnUnderlyingNetworkPolicyListener listener) {
+                Executor executor, VcnNetworkPolicyListener listener) {
             mExecutor = executor;
             mListener = listener;
         }
@@ -460,6 +604,12 @@
                     () -> mExecutor.execute(() -> mCallback.onEnteredSafeMode()));
         }
 
+        @Override
+        public void onVcnStatusChanged(@VcnStatusCode int statusCode) {
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> mCallback.onVcnStatusChanged(statusCode)));
+        }
+
         // TODO(b/180521637): use ServiceSpecificException for safer Exception 'parceling'
         @Override
         public void onGatewayConnectionError(
diff --git a/core/java/android/net/vcn/VcnNetworkPolicyResult.aidl b/core/java/android/net/vcn/VcnNetworkPolicyResult.aidl
new file mode 100644
index 0000000..3f13abe
--- /dev/null
+++ b/core/java/android/net/vcn/VcnNetworkPolicyResult.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2021 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.net.vcn;
+
+/** @hide */
+parcelable VcnNetworkPolicyResult;
diff --git a/core/java/android/net/vcn/VcnNetworkPolicyResult.java b/core/java/android/net/vcn/VcnNetworkPolicyResult.java
new file mode 100644
index 0000000..5e93820
--- /dev/null
+++ b/core/java/android/net/vcn/VcnNetworkPolicyResult.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2021 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.net.vcn;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.net.NetworkCapabilities;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * VcnNetworkPolicyResult represents the Network policy result for a Network transport applying its
+ * VCN policy via {@link VcnManager#applyVcnNetworkPolicy(NetworkCapabilities, LinkProperties)}.
+ *
+ * <p>Bearers that are bringing up networks capable of acting as a VCN's underlying network should
+ * query for Network policy results upon any capability changes (e.g. changing of TRUSTED bit), and
+ * when prompted by VcnManagementService via {@link VcnManager.VcnNetworkPolicyListener}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class VcnNetworkPolicyResult implements Parcelable {
+    private final boolean mIsTearDownRequested;
+    private final NetworkCapabilities mNetworkCapabilities;
+
+    /**
+     * Constructs a VcnNetworkPolicyResult with the specified parameters.
+     *
+     * @hide
+     */
+    public VcnNetworkPolicyResult(
+            boolean isTearDownRequested, @NonNull NetworkCapabilities networkCapabilities) {
+        Objects.requireNonNull(networkCapabilities, "networkCapabilities must be non-null");
+
+        mIsTearDownRequested = isTearDownRequested;
+        mNetworkCapabilities = networkCapabilities;
+    }
+
+    /**
+     * Returns whether this VCN policy result requires that the underlying Network should be torn
+     * down.
+     *
+     * <p>Upon querying for the current Network policy result, the bearer must check this method,
+     * and MUST tear down the corresponding Network if it returns true.
+     */
+    public boolean isTeardownRequested() {
+        return mIsTearDownRequested;
+    }
+
+    /**
+     * Returns the NetworkCapabilities that the bearer should be using for the corresponding
+     * Network.
+     */
+    @NonNull
+    public NetworkCapabilities getNetworkCapabilities() {
+        return mNetworkCapabilities;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mIsTearDownRequested, mNetworkCapabilities);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof VcnNetworkPolicyResult)) return false;
+        final VcnNetworkPolicyResult that = (VcnNetworkPolicyResult) o;
+
+        return mIsTearDownRequested == that.mIsTearDownRequested
+                && mNetworkCapabilities.equals(that.mNetworkCapabilities);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeBoolean(mIsTearDownRequested);
+        dest.writeParcelable(mNetworkCapabilities, flags);
+    }
+
+    /** Implement the Parcelable interface */
+    public static final @NonNull Creator<VcnNetworkPolicyResult> CREATOR =
+            new Creator<VcnNetworkPolicyResult>() {
+                public VcnNetworkPolicyResult createFromParcel(Parcel in) {
+                    return new VcnNetworkPolicyResult(in.readBoolean(), in.readParcelable(null));
+                }
+
+                public VcnNetworkPolicyResult[] newArray(int size) {
+                    return new VcnNetworkPolicyResult[size];
+                }
+            };
+}
diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java b/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
index dd7c86d8..b47d564 100644
--- a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
+++ b/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java
@@ -33,8 +33,7 @@
  * @hide
  */
 public final class VcnUnderlyingNetworkPolicy implements Parcelable {
-    private final boolean mIsTearDownRequested;
-    private final NetworkCapabilities mMergedNetworkCapabilities;
+    private final VcnNetworkPolicyResult mVcnNetworkPolicyResult;
 
     /**
      * Constructs a VcnUnderlyingNetworkPolicy with the specified parameters.
@@ -46,8 +45,13 @@
         Objects.requireNonNull(
                 mergedNetworkCapabilities, "mergedNetworkCapabilities must be nonnull");
 
-        mIsTearDownRequested = isTearDownRequested;
-        mMergedNetworkCapabilities = mergedNetworkCapabilities;
+        mVcnNetworkPolicyResult =
+                new VcnNetworkPolicyResult(isTearDownRequested, mergedNetworkCapabilities);
+    }
+
+    private VcnUnderlyingNetworkPolicy(@NonNull VcnNetworkPolicyResult vcnNetworkPolicyResult) {
+        this.mVcnNetworkPolicyResult =
+                Objects.requireNonNull(vcnNetworkPolicyResult, "vcnNetworkPolicyResult");
     }
 
     /**
@@ -55,7 +59,7 @@
      * be torn down.
      */
     public boolean isTeardownRequested() {
-        return mIsTearDownRequested;
+        return mVcnNetworkPolicyResult.isTeardownRequested();
     }
 
     /**
@@ -64,12 +68,12 @@
      */
     @NonNull
     public NetworkCapabilities getMergedNetworkCapabilities() {
-        return mMergedNetworkCapabilities;
+        return mVcnNetworkPolicyResult.getNetworkCapabilities();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mIsTearDownRequested, mMergedNetworkCapabilities);
+        return Objects.hash(mVcnNetworkPolicyResult);
     }
 
     @Override
@@ -78,8 +82,7 @@
         if (!(o instanceof VcnUnderlyingNetworkPolicy)) return false;
         final VcnUnderlyingNetworkPolicy that = (VcnUnderlyingNetworkPolicy) o;
 
-        return mIsTearDownRequested == that.mIsTearDownRequested
-                && mMergedNetworkCapabilities.equals(that.mMergedNetworkCapabilities);
+        return mVcnNetworkPolicyResult.equals(that.mVcnNetworkPolicyResult);
     }
 
     /** {@inheritDoc} */
@@ -91,16 +94,14 @@
     /** {@inheritDoc} */
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeBoolean(mIsTearDownRequested);
-        dest.writeParcelable(mMergedNetworkCapabilities, flags);
+        dest.writeParcelable(mVcnNetworkPolicyResult, flags);
     }
 
     /** Implement the Parcelable interface */
     public static final @NonNull Creator<VcnUnderlyingNetworkPolicy> CREATOR =
             new Creator<VcnUnderlyingNetworkPolicy>() {
                 public VcnUnderlyingNetworkPolicy createFromParcel(Parcel in) {
-                    return new VcnUnderlyingNetworkPolicy(
-                            in.readBoolean(), in.readParcelable(null));
+                    return new VcnUnderlyingNetworkPolicy(in.readParcelable(null));
                 }
 
                 public VcnUnderlyingNetworkPolicy[] newArray(int size) {
diff --git a/core/java/android/os/BugreportManager.java b/core/java/android/os/BugreportManager.java
index 305c686..73bb8d5 100644
--- a/core/java/android/os/BugreportManager.java
+++ b/core/java/android/os/BugreportManager.java
@@ -25,6 +25,7 @@
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.annotation.WorkerThread;
 import android.app.ActivityManager;
 import android.content.Context;
 import android.util.Log;
@@ -41,7 +42,15 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.concurrent.Executor;
 
-/** Class that provides a privileged API to capture and consume bugreports. */
+/**
+ * Class that provides a privileged API to capture and consume bugreports.
+ *
+ * <p>This class may only be used by apps that currently have carrier privileges (see {@link
+ * android.telephony.TelephonyManager#hasCarrierPrivileges}) on an active SIM or priv-apps
+ * explicitly allowed by the device manufacturer.
+ *
+ * <p>Only one bugreport can be generated by the system at a time.
+ */
 @SystemService(Context.BUGREPORT_SERVICE)
 public final class BugreportManager {
 
@@ -56,7 +65,15 @@
         mBinder = binder;
     }
 
-    /** An interface describing the callback for bugreport progress and status. */
+    /**
+     * An interface describing the callback for bugreport progress and status.
+     *
+     * <p>Callers will receive {@link #onProgress} calls as the bugreport progresses, followed by a
+     * terminal call to either {@link #onFinished} or {@link #onError}.
+     *
+     * <p>If an issue is encountered while starting the bugreport asynchronously, callers will
+     * receive an {@link #onError} call without any {@link #onProgress} callbacks.
+     */
     public abstract static class BugreportCallback {
         /**
          * Possible error codes taking a bugreport can encounter.
@@ -75,15 +92,18 @@
                 })
         public @interface BugreportErrorCode {}
 
-        /** The input options were invalid */
+        /**
+         * The input options were invalid. For example, the destination file the app provided could
+         * not be written by the system.
+         */
         public static final int BUGREPORT_ERROR_INVALID_INPUT =
                 IDumpstateListener.BUGREPORT_ERROR_INVALID_INPUT;
 
-        /** A runtime error occurred */
+        /** A runtime error occurred. */
         public static final int BUGREPORT_ERROR_RUNTIME =
                 IDumpstateListener.BUGREPORT_ERROR_RUNTIME_ERROR;
 
-        /** User denied consent to share the bugreport */
+        /** User denied consent to share the bugreport. */
         public static final int BUGREPORT_ERROR_USER_DENIED_CONSENT =
                 IDumpstateListener.BUGREPORT_ERROR_USER_DENIED_CONSENT;
 
@@ -149,6 +169,7 @@
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.DUMP)
+    @WorkerThread
     public void startBugreport(
             @NonNull ParcelFileDescriptor bugreportFd,
             @Nullable ParcelFileDescriptor screenshotFd,
@@ -222,6 +243,7 @@
      * @param callback callback for progress and status updates.
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    @WorkerThread
     public void startConnectivityBugreport(
             @NonNull ParcelFileDescriptor bugreportFd,
             @NonNull @CallbackExecutor Executor executor,
@@ -247,6 +269,7 @@
      * @throws SecurityException if trying to cancel another app's bugreport in progress
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    @WorkerThread
     public void cancelBugreport() {
         try {
             mBinder.cancelBugreport(-1 /* callingUid */, mContext.getOpPackageName());
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 33dedda..874add5 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -24,7 +24,6 @@
 import android.net.NetworkStats;
 import android.net.RouteInfo;
 import android.net.UidRange;
-import android.os.INetworkActivityListener;
 
 /**
  * @hide
@@ -294,25 +293,6 @@
     @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     boolean isBandwidthControlEnabled();
 
-    /**
-     * Sets idletimer for an interface.
-     *
-     * This either initializes a new idletimer or increases its
-     * reference-counting if an idletimer already exists for given
-     * {@code iface}.
-     *
-     * {@code type} is the type of the interface, such as TYPE_MOBILE.
-     *
-     * Every {@code addIdleTimer} should be paired with a
-     * {@link removeIdleTimer} to cleanup when the network disconnects.
-     */
-    void addIdleTimer(String iface, int timeout, int type);
-
-    /**
-     * Removes idletimer for an interface.
-     */
-    void removeIdleTimer(String iface);
-
     void setFirewallEnabled(boolean enabled);
     boolean isFirewallEnabled();
     void setFirewallInterfaceRule(String iface, boolean allow);
@@ -320,21 +300,6 @@
     void setFirewallUidRules(int chain, in int[] uids, in int[] rules);
     void setFirewallChainEnabled(int chain, boolean enable);
 
-    /**
-     * Start listening for mobile activity state changes.
-     */
-    void registerNetworkActivityListener(INetworkActivityListener listener);
-
-    /**
-     * Stop listening for mobile activity state changes.
-     */
-    void unregisterNetworkActivityListener(INetworkActivityListener listener);
-
-    /**
-     * Check whether the mobile radio is currently active.
-     */
-    boolean isNetworkActive();
-
     void addLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid);
 
     /**
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 93c1690..43184ea 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -26,6 +26,7 @@
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
+import android.app.KeyguardManager;
 import android.app.PendingIntent;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
@@ -631,10 +632,15 @@
     /**
      * Prepare to apply an unattended update by asking the user for their Lock Screen Knowledge
      * Factor (LSKF). If supplied, the {@code intentSender} will be called when the system is setup
-     * and ready to apply the OTA. This API is expected to handle requests from multiple clients
-     * simultaneously, e.g. from ota and mainline.
+     * and ready to apply the OTA. <p>
      *
-     * <p> The behavior of multi-client Resume on Reboot works as follows
+     * <p> If the device doesn't setup a lock screen, i.e. by checking
+     * {@link KeyguardManager#isKeyguardSecure()}, this API call will fail and throw an exception.
+     * Callers are expected to use {@link PowerManager#reboot(String)} directly without going
+     * through the RoR flow. <p>
+     *
+     * <p>  This API is expected to handle requests from multiple clients simultaneously, e.g.
+     * from ota and mainline. The behavior of multi-client Resume on Reboot works as follows
      * <li> Each client should call this function to prepare for Resume on Reboot before calling
      *      {@link #rebootAndApply(Context, String, boolean)} </li>
      * <li> One client cannot clear the Resume on Reboot preparation of another client. </li>
@@ -658,6 +664,13 @@
         if (updateToken == null) {
             throw new NullPointerException("updateToken == null");
         }
+
+        KeyguardManager keyguardManager = context.getSystemService(KeyguardManager.class);
+        if (keyguardManager == null || !keyguardManager.isDeviceSecure()) {
+            throw new IOException("Failed to request LSKF because the device doesn't have a"
+                    + " lock screen. ");
+        }
+
         RecoverySystem rs = (RecoverySystem) context.getSystemService(Context.RECOVERY_SERVICE);
         if (!rs.requestLskf(context.getPackageName(), intentSender)) {
             throw new IOException("preparation for update failed");
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index b1014af..3360459 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -329,8 +329,7 @@
                 try {
                     time = mMgr.getGnssTimeMillis();
                 } catch (RemoteException e) {
-                    e.rethrowFromSystemServer();
-                    return 0;
+                    throw e.rethrowFromSystemServer();
                 }
                 if (time == null) {
                     throw new DateTimeException("Gnss based time is not available.");
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 9e332e9..c9da641 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -426,7 +426,7 @@
         // avoid writing a partial response to the zygote.
         for (String arg : args) {
             // Making two indexOf calls here is faster than running a manually fused loop due
-            // to the fact that indexOf is a optimized intrinsic.
+            // to the fact that indexOf is an optimized intrinsic.
             if (arg.indexOf('\n') >= 0) {
                 throw new ZygoteStartFailedEx("Embedded newlines not allowed");
             } else if (arg.indexOf('\r') >= 0) {
diff --git a/core/java/android/provider/SimPhonebookContract.java b/core/java/android/provider/SimPhonebookContract.java
index 074d5f1..030b863 100644
--- a/core/java/android/provider/SimPhonebookContract.java
+++ b/core/java/android/provider/SimPhonebookContract.java
@@ -44,8 +44,11 @@
  * The contract between the provider of contact records on the device's SIM cards and applications.
  * Contains definitions of the supported URIs and columns.
  *
- * <p>This content provider does not support any of the QUERY_ARG_SQL* bundle arguments. An
- * IllegalArgumentException will be thrown if these are included.
+ * <h3>Permissions</h3>
+ * <p>
+ * Querying this provider requires {@link android.Manifest.permission#READ_CONTACTS} and writing
+ * to this provider requires {@link android.Manifest.permission#WRITE_CONTACTS}
+ * </p>
  */
 public final class SimPhonebookContract {
 
@@ -85,7 +88,73 @@
         }
     }
 
-    /** Constants for the contact records on a SIM card. */
+    /**
+     * Constants for the contact records on a SIM card.
+     *
+     * <h3 id="simrecords-data">Data</h3>
+     * <p>
+     * Data is stored in a specific elementary file on a specific SIM card and these are isolated
+     * from each other. SIM cards are identified by their subscription ID. SIM cards may not support
+     * all or even any of the elementary file types. A SIM will have constraints on
+     * the values of the data that can be stored in each elementary file. The available SIMs,
+     * their supported elementary file types and the constraints on the data can be discovered by
+     * querying {@link ElementaryFiles#CONTENT_URI}. Each elementary file has a fixed capacity
+     * for the number of records that may be stored. This can be determined from the value
+     * of the {@link ElementaryFiles#MAX_RECORDS} column.
+     * </p>
+     * <p>
+     * The {@link SimRecords#PHONE_NUMBER} column can only contain dialable characters and this
+     * applies regardless of the SIM that is being used. See
+     * {@link android.telephony.PhoneNumberUtils#isDialable(char)} for more details. Additionally
+     * the phone number can contain at most {@link ElementaryFiles#PHONE_NUMBER_MAX_LENGTH}
+     * characters. The {@link SimRecords#NAME} column can contain at most
+     * {@link ElementaryFiles#NAME_MAX_LENGTH} bytes when it is encoded for storage on the SIM.
+     * Encoding is done internally and so the name should be provided unencoded but the number of
+     * bytes required to encode it will vary depending on the characters it contains. This length
+     * can be determined by calling
+     * {@link SimRecords#getEncodedNameLength(ContentResolver, String)}.
+     * </p>
+     * <h3>Operations </h3>
+     * <dl>
+     * <dd><b>Insert</b></dd>
+     * <p>
+     * Only {@link ElementaryFiles#EF_ADN} supports inserts. {@link SimRecords#PHONE_NUMBER}
+     * is a required column. If the value provided for this column is missing, null, empty
+     * or violates the requirements discussed in the <a href="#simrecords-data">Data</a>
+     * section above an {@link IllegalArgumentException} will be thrown. The
+     * {@link SimRecords#NAME} column may be omitted but if provided and it violates any of
+     * the requirements discussed in the <a href="#simrecords-data">Data</a> section above
+     * an {@link IllegalArgumentException} will be thrown.
+     * </p>
+     * <p>
+     * If an insert is not possible because the elementary file is full then an
+     * {@link IllegalStateException} will be thrown.
+     * </p>
+     * <dd><b>Update</b></dd>
+     * <p>
+     * Updates can only be performed for individual records on {@link ElementaryFiles#EF_ADN}.
+     * A specific record is referenced via the Uri returned by
+     * {@link SimRecords#getItemUri(int, int, int)}. Updates have the same constraints and
+     * behavior for the {@link SimRecords#PHONE_NUMBER} and {@link SimRecords#NAME} as insert.
+     * However, in the case of update the {@link SimRecords#PHONE_NUMBER} may be omitted as
+     * the existing record will already have a valid value.
+     * </p>
+     * <dd><b>Delete</b></dd>
+     * <p>
+     * Delete may only be performed for individual records on {@link ElementaryFiles#EF_ADN}.
+     * Deleting records will free up space for use by future inserts.
+     * </p>
+     * <dd><b>Query</b></dd>
+     * <p>
+     * All the records stored on a specific elementary file can be read via a Uri returned by
+     * {@link SimRecords#getContentUri(int, int)}. This query always returns all records; there
+     * is no support for filtering via a selection. An individual record can be queried via a Uri
+     * returned by {@link SimRecords#getItemUri(int, int, int)}. Queries will throw an
+     * {@link IllegalArgumentException} when the SIM with the subscription ID or the elementary file
+     * type are invalid or unavailable.
+     * </p>
+     * </dl>
+     */
     public static final class SimRecords {
 
         /**
@@ -197,8 +266,8 @@
          * be discovered by querying {@link ElementaryFiles#CONTENT_URI}.
          *
          * <p>If a SIM with the provided subscription ID does not exist or the SIM with the provided
-         * subscription ID doesn't support the specified entity file then queries will return
-         * and empty cursor and inserts will throw an {@link IllegalArgumentException}
+         * subscription ID doesn't support the specified entity file then all operations will
+         * throw an {@link IllegalArgumentException}.
          *
          * @param subscriptionId the subscriptionId of the SIM card that this Uri will reference
          * @param efType         the elementary file on the SIM that this Uri will reference
@@ -233,6 +302,9 @@
          *                       must be greater than 0. If there is no record with this record
          *                       number in the specified entity file then it will be treated as a
          *                       non-existent record.
+         * @see ElementaryFiles#SUBSCRIPTION_ID
+         * @see ElementaryFiles#EF_TYPE
+         * @see #RECORD_NUMBER
          */
         @NonNull
         public static Uri getItemUri(
@@ -287,7 +359,28 @@
 
     }
 
-    /** Constants for metadata about the elementary files of the SIM cards in the phone. */
+    /**
+     * Constants for metadata about the elementary files of the SIM cards in the phone.
+     *
+     * <h3>Operations </h3>
+     * <dl>
+     * <dd><b>Insert</b></dd>
+     * <p>Insert is not supported for the Uris defined in this class.</p>
+     * <dd><b>Update</b></dd>
+     * <p>Update is not supported for the Uris defined in this class.</p>
+     * <dd><b>Delete</b></dd>
+     * <p>Delete is not supported for the Uris defined in this class.</p>
+     * <dd><b>Query</b></dd>
+     * <p>
+     * The elementary files for all the inserted SIMs can be read via
+     * {@link ElementaryFiles#CONTENT_URI}. Unsupported elementary files are omitted from the
+     * results. This Uri always returns all supported elementary files for all available SIMs; it
+     * does not support filtering via a selection. A specific elementary file can be queried
+     * via a Uri returned by {@link ElementaryFiles#getItemUri(int, int)}. If the elementary file
+     * referenced by this Uri is unsupported by the SIM then the query will return an empty cursor.
+     * </p>
+     * </dl>
+     */
     public static final class ElementaryFiles {
 
         /** {@link SubscriptionInfo#getSimSlotIndex()} of the SIM for this row. */
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java
index cc3e578..1dc7f71 100644
--- a/core/java/android/security/keystore/recovery/RecoveryController.java
+++ b/core/java/android/security/keystore/recovery/RecoveryController.java
@@ -27,8 +27,11 @@
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.security.KeyStore;
-import android.security.keystore.AndroidKeyStoreProvider;
+import android.security.KeyStore2;
 import android.security.keystore.KeyPermanentlyInvalidatedException;
+import android.security.keystore2.AndroidKeyStoreProvider;
+import android.system.keystore2.Domain;
+import android.system.keystore2.KeyDescriptor;
 
 import com.android.internal.widget.ILockSettings;
 
@@ -709,10 +712,34 @@
      */
     @NonNull Key getKeyFromGrant(@NonNull String grantAlias)
             throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
-        return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
-                mKeyStore,
-                grantAlias,
-                KeyStore.UID_SELF);
+        if (grantAlias.startsWith(APPLICATION_KEY_GRANT_PREFIX)) {
+            return AndroidKeyStoreProvider
+                    .loadAndroidKeyStoreSecretKeyFromKeystore(
+                            KeyStore2.getInstance(),
+                            getGrantDescriptor(grantAlias));
+        }
+        // TODO(b/171305545): remove KeyStore1 logic.
+        return android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyFromKeystore(
+            mKeyStore,
+            grantAlias,
+            KeyStore.UID_SELF);
+
+    }
+
+    private static final String APPLICATION_KEY_GRANT_PREFIX = "recoverable_key:";
+
+    private static @Nullable KeyDescriptor getGrantDescriptor(String grantAlias) {
+        KeyDescriptor result = new KeyDescriptor();
+        result.domain = Domain.GRANT;
+        result.blob = null;
+        result.alias = null;
+        try {
+            result.nspace = Long.parseUnsignedLong(
+                    grantAlias.substring(APPLICATION_KEY_GRANT_PREFIX.length()), 16);
+        } catch (NumberFormatException e) {
+            return null;
+        }
+        return result;
     }
 
     /**
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index a9548b0..299a292 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -332,12 +332,12 @@
     /**
      * Notify {@link ServiceState} update on certain subscription.
      *
-     * @param subId for which the service state changed.
      * @param slotIndex for which the service state changed. Can be derived from subId except
      * subId is invalid.
+     * @param subId for which the service state changed.
      * @param state service state e.g, in service, out of service or roaming status.
      */
-    public void notifyServiceStateChanged(int subId, int slotIndex, @NonNull ServiceState state) {
+    public void notifyServiceStateChanged(int slotIndex, int subId, @NonNull ServiceState state) {
         try {
             sRegistry.notifyServiceStateForPhoneId(slotIndex, subId, state);
         } catch (RemoteException ex) {
@@ -348,12 +348,12 @@
     /**
      * Notify {@link SignalStrength} update on certain subscription.
      *
-     * @param subId for which the signalstrength changed.
      * @param slotIndex for which the signalstrength changed. Can be derived from subId except when
      * subId is invalid.
+     * @param subId for which the signalstrength changed.
      * @param signalStrength e.g, signalstrength level {@see SignalStrength#getLevel()}
      */
-    public void notifySignalStrengthChanged(int subId, int slotIndex,
+    public void notifySignalStrengthChanged(int slotIndex, int subId,
             @NonNull SignalStrength signalStrength) {
         try {
             sRegistry.notifySignalStrengthForPhoneId(slotIndex, subId, signalStrength);
@@ -366,13 +366,13 @@
      * Notify changes to the message-waiting indicator on certain subscription. e.g, The status bar
      * uses message waiting indicator to determine when to display the voicemail icon.
      *
-     * @param subId for which message waiting indicator changed.
      * @param slotIndex for which message waiting indicator changed. Can be derived from subId
      * except when subId is invalid.
+     * @param subId for which message waiting indicator changed.
      * @param msgWaitingInd {@code true} indicates there is message-waiting indicator, {@code false}
      * otherwise.
      */
-    public void notifyMessageWaitingChanged(int subId, int slotIndex, boolean msgWaitingInd) {
+    public void notifyMessageWaitingChanged(int slotIndex, int subId, boolean msgWaitingInd) {
         try {
             sRegistry.notifyMessageWaitingChangedForPhoneId(slotIndex, subId, msgWaitingInd);
         } catch (RemoteException ex) {
@@ -413,9 +413,9 @@
     /**
      * Notify changes to default (Internet) data connection state on certain subscription.
      *
-     * @param subId for which data connection state changed.
      * @param slotIndex for which data connections state changed. Can be derived from subId except
      * when subId is invalid.
+     * @param subId for which data connection state changed.
      * @param preciseState the PreciseDataConnectionState
      *
      * @see PreciseDataConnectionState
@@ -434,13 +434,13 @@
     /**
      * Notify {@link CallQuality} change on certain subscription.
      *
-     * @param subId for which call quality state changed.
      * @param slotIndex for which call quality state changed. Can be derived from subId except when
      * subId is invalid.
+     * @param subId for which call quality state changed.
      * @param callQuality Information about call quality e.g, call quality level
      * @param networkType associated with this data connection. e.g, LTE
      */
-    public void notifyCallQualityChanged(int subId, int slotIndex, @NonNull CallQuality callQuality,
+    public void notifyCallQualityChanged(int slotIndex, int subId, @NonNull CallQuality callQuality,
         @NetworkType int networkType) {
         try {
             sRegistry.notifyCallQualityChanged(callQuality, slotIndex, subId, networkType);
@@ -452,11 +452,11 @@
     /**
      * Notify emergency number list changed on certain subscription.
      *
-     * @param subId for which emergency number list changed.
      * @param slotIndex for which emergency number list changed. Can be derived from subId except
      * when subId is invalid.
+     * @param subId for which emergency number list changed.
      */
-    public void notifyEmergencyNumberList(int subId, int slotIndex) {
+    public void notifyEmergencyNumberList( int slotIndex, int subId) {
         try {
             sRegistry.notifyEmergencyNumberList(slotIndex, subId);
         } catch (RemoteException ex) {
@@ -497,13 +497,13 @@
     /**
      * Notify radio power state changed on certain subscription.
      *
-     * @param subId for which radio power state changed.
      * @param slotIndex for which radio power state changed. Can be derived from subId except when
      * subId is invalid.
+     * @param subId for which radio power state changed.
      * @param radioPowerState the current modem radio state.
      */
-    public void notifyRadioPowerStateChanged(int subId, int slotIndex,
-        @RadioPowerState int radioPowerState) {
+    public void notifyRadioPowerStateChanged(int slotIndex, int subId,
+            @RadioPowerState int radioPowerState) {
         try {
             sRegistry.notifyRadioPowerStateChanged(slotIndex, subId, radioPowerState);
         } catch (RemoteException ex) {
@@ -541,13 +541,13 @@
      * Notify data activation state changed on certain subscription.
      * @see TelephonyManager#getDataActivationState()
      *
-     * @param subId for which data activation state changed.
      * @param slotIndex for which data activation state changed. Can be derived from subId except
      * when subId is invalid.
+     * @param subId for which data activation state changed.
      * @param activationState sim activation state e.g, activated.
      */
-    public void notifyDataActivationStateChanged(int subId, int slotIndex,
-        @SimActivationState int activationState) {
+    public void notifyDataActivationStateChanged(int slotIndex, int subId,
+            @SimActivationState int activationState) {
         try {
             sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId,
                     SIM_ACTIVATION_TYPE_DATA, activationState);
@@ -560,13 +560,13 @@
      * Notify voice activation state changed on certain subscription.
      * @see TelephonyManager#getVoiceActivationState()
      *
-     * @param subId for which voice activation state changed.
      * @param slotIndex for which voice activation state changed. Can be derived from subId except
      * subId is invalid.
+     * @param subId for which voice activation state changed.
      * @param activationState sim activation state e.g, activated.
      */
-    public void notifyVoiceActivationStateChanged(int subId, int slotIndex,
-        @SimActivationState int activationState) {
+    public void notifyVoiceActivationStateChanged(int slotIndex, int subId,
+            @SimActivationState int activationState) {
         try {
             sRegistry.notifySimActivationStateChangedForPhoneId(slotIndex, subId,
                     SIM_ACTIVATION_TYPE_VOICE, activationState);
@@ -579,9 +579,9 @@
      * Notify User mobile data state changed on certain subscription. e.g, mobile data is enabled
      * or disabled.
      *
-     * @param subId for which mobile data state has changed.
      * @param slotIndex for which mobile data state has changed. Can be derived from subId except
      * when subId is invalid.
+     * @param subId for which mobile data state has changed.
      * @param state {@code true} indicates mobile data is enabled/on. {@code false} otherwise.
      */
     public void notifyUserMobileDataStateChanged(int slotIndex, int subId, boolean state) {
@@ -602,7 +602,7 @@
      * @param telephonyDisplayInfo The display info.
      */
     public void notifyDisplayInfoChanged(int slotIndex, int subscriptionId,
-                                         @NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
+            @NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
         try {
             sRegistry.notifyDisplayInfoChanged(slotIndex, subscriptionId, telephonyDisplayInfo);
         } catch (RemoteException ex) {
@@ -643,14 +643,14 @@
      * Notify precise call state changed on certain subscription, including foreground, background
      * and ringcall states.
      *
-     * @param subId for which precise call state changed.
      * @param slotIndex for which precise call state changed. Can be derived from subId except when
      * subId is invalid.
+     * @param subId for which precise call state changed.
      * @param ringCallPreciseState ringCall state.
      * @param foregroundCallPreciseState foreground call state.
      * @param backgroundCallPreciseState background call state.
      */
-    public void notifyPreciseCallState(int subId, int slotIndex,
+    public void notifyPreciseCallState(int slotIndex, int subId,
             @PreciseCallStates int ringCallPreciseState,
             @PreciseCallStates int foregroundCallPreciseState,
             @PreciseCallStates int backgroundCallPreciseState) {
@@ -793,9 +793,10 @@
      * @param reason Reason for data enabled/disabled. See {@code REASON_*} in
      * {@link TelephonyManager}.
      */
-    public void notifyDataEnabled(boolean enabled, @TelephonyManager.DataEnabledReason int reason) {
+    public void notifyDataEnabled(int slotIndex, int subId, boolean enabled,
+            @TelephonyManager.DataEnabledReason int reason) {
         try {
-            sRegistry.notifyDataEnabled(enabled, reason);
+            sRegistry.notifyDataEnabled(slotIndex, subId, enabled, reason);
         } catch (RemoteException ex) {
             // system server crash
         }
diff --git a/core/java/android/uwb/AngleOfArrivalSupport.aidl b/core/java/android/uwb/AngleOfArrivalSupport.aidl
deleted file mode 100644
index 57666ff..0000000
--- a/core/java/android/uwb/AngleOfArrivalSupport.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2020 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.uwb;
-
-/**
- * @hide
- */
-@Backing(type="int")
-enum AngleOfArrivalSupport {
-  /**
-   * The device does not support angle of arrival
-   */
-  NONE,
-
-  /**
-   * The device supports planar angle of arrival
-   */
-  TWO_DIMENSIONAL,
-
-  /**
-   * The device does supports three dimensional angle of arrival with hemispherical azimuth angles
-   */
-  THREE_DIMENSIONAL_HEMISPHERICAL,
-
-  /**
-   * The device does supports three dimensional angle of arrival with full azimuth angles
-   */
-  THREE_DIMENSIONAL_SPHERICAL,
-}
-
diff --git a/core/java/android/uwb/IUwbAdapter.aidl b/core/java/android/uwb/IUwbAdapter.aidl
index b9c5508..468a69c 100644
--- a/core/java/android/uwb/IUwbAdapter.aidl
+++ b/core/java/android/uwb/IUwbAdapter.aidl
@@ -17,7 +17,6 @@
 package android.uwb;
 
 import android.os.PersistableBundle;
-import android.uwb.AngleOfArrivalSupport;
 import android.uwb.IUwbAdapterStateCallbacks;
 import android.uwb.IUwbRangingCallbacks;
 import android.uwb.SessionHandle;
@@ -47,43 +46,6 @@
   void unregisterAdapterStateCallbacks(in IUwbAdapterStateCallbacks callbacks);
 
   /**
-   * Returns true if ranging is supported, false otherwise
-   */
-  boolean isRangingSupported();
-
-  /**
-   * Get the angle of arrival supported by this device
-   *
-   * @return the angle of arrival type supported
-   */
-  AngleOfArrivalSupport getAngleOfArrivalSupport();
-
-  /**
-   * Generates a list of the supported 802.15.4z channels
-   *
-   * The list must be prioritized in the order of preferred channel usage.
-   *
-   * The list must only contain channels that are permitted to be used in the
-   * device's current location.
-   *
-   * @return an array of support channels on the device for the current location.
-   */
-  int[] getSupportedChannels();
-
-  /**
-   * Generates a list of the supported 802.15.4z preamble codes
-   *
-   * The list must be prioritized in the order of preferred preamble usage.
-   *
-   * The list must only contain preambles that are permitted to be used in the
-   * device's current location.
-   *
-   * @return an array of supported preambles on the device for the current
-   *         location.
-   */
-  int[] getSupportedPreambleCodes();
-
-  /**
    * Get the accuracy of the ranging timestamps
    *
    * @return accuracy of the ranging timestamps in nanoseconds
@@ -91,27 +53,6 @@
   long getTimestampResolutionNanos();
 
   /**
-   * Get the supported number of simultaneous ranging sessions
-   *
-   * @return the supported number of simultaneous ranging sessions
-   */
-  int getMaxSimultaneousSessions();
-
-  /**
-   * Get the maximum number of remote devices per session when local device is initiator
-   *
-   * @return the maximum number of remote devices supported in a single session
-   */
-  int getMaxRemoteDevicesPerInitiatorSession();
-
-  /**
-   * Get the maximum number of remote devices per session when local device is responder
-   *
-   * @return the maximum number of remote devices supported in a single session
-   */
-  int getMaxRemoteDevicesPerResponderSession();
-
-  /**
    * Provides the capabilities and features of the device
    *
    * @return specification specific capabilities and features of the device
diff --git a/core/java/android/uwb/UwbManager.java b/core/java/android/uwb/UwbManager.java
index 2dc0ba0..63a6d05 100644
--- a/core/java/android/uwb/UwbManager.java
+++ b/core/java/android/uwb/UwbManager.java
@@ -32,10 +32,6 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
 import java.util.concurrent.Executor;
 
 /**
@@ -195,133 +191,6 @@
     }
 
     /**
-     * Check if ranging is supported, regardless of ranging method
-     *
-     * @return true if ranging is supported
-     */
-    @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
-    public boolean isRangingSupported() {
-        try {
-            return mUwbAdapter.isRangingSupported();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * @hide
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = {
-            ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE,
-            ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D,
-            ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL,
-            ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL})
-    public @interface AngleOfArrivalSupportType {}
-
-    /**
-     * Indicate absence of support for angle of arrival measurement
-     */
-    public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE = 1;
-
-    /**
-     * Indicate support for planar angle of arrival measurement, due to antenna
-     * limitation. Typically requires at least two antennas.
-     */
-    public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D = 2;
-
-    /**
-     * Indicate support for three dimensional angle of arrival measurement.
-     * Typically requires at least three antennas. However, due to antenna
-     * arrangement, a platform may only support hemi-spherical azimuth angles
-     * ranging from -pi/2 to pi/2
-     */
-    public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL = 3;
-
-    /**
-     * Indicate support for three dimensional angle of arrival measurement.
-     * Typically requires at least three antennas. This mode supports full
-     * azimuth angles ranging from -pi to pi.
-     */
-    public static final int ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL = 4;
-
-    /**
-     * Gets the {@link AngleOfArrivalSupportType} supported on this platform
-     * <p>Possible return values are
-     * {@link #ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE},
-     * {@link #ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D},
-     * {@link #ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL},
-     * {@link #ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL}.
-     *
-     * @return angle of arrival type supported
-     */
-    @AngleOfArrivalSupportType
-    @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
-    public int getAngleOfArrivalSupport() {
-        try {
-            switch (mUwbAdapter.getAngleOfArrivalSupport()) {
-                case AngleOfArrivalSupport.TWO_DIMENSIONAL:
-                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_2D;
-
-                case AngleOfArrivalSupport.THREE_DIMENSIONAL_HEMISPHERICAL:
-                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_HEMISPHERICAL;
-
-                case AngleOfArrivalSupport.THREE_DIMENSIONAL_SPHERICAL:
-                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_3D_SPHERICAL;
-
-                case AngleOfArrivalSupport.NONE:
-                default:
-                    return ANGLE_OF_ARRIVAL_SUPPORT_TYPE_NONE;
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get a {@link List} of supported channel numbers based on the device's current location
-     * <p>The returned values are ordered by the system's desired ordered of use, with the first
-     * entry being the most preferred.
-     *
-     * <p>Channel numbers are defined based on the IEEE 802.15.4z standard for UWB.
-     *
-     * @return {@link List} of supported channel numbers ordered by preference
-     */
-    @NonNull
-    @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
-    public List<Integer> getSupportedChannelNumbers() {
-        List<Integer> channels = new ArrayList<>();
-        try {
-            for (int channel : mUwbAdapter.getSupportedChannels()) {
-                channels.add(channel);
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-        return channels;
-    }
-
-    /**
-     * Get a {@link List} of supported preamble code indices
-     * <p> Preamble code indices are defined based on the IEEE 802.15.4z standard for UWB.
-     *
-     * @return {@link List} of supported preamble code indices
-     */
-    @NonNull
-    @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
-    public Set<Integer> getSupportedPreambleCodeIndices() {
-        Set<Integer> preambles = new HashSet<>();
-        try {
-            for (int preamble : mUwbAdapter.getSupportedPreambleCodes()) {
-                preambles.add(preamble);
-            }
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-        return preambles;
-    }
-
-    /**
      * Get the timestamp resolution for events in nanoseconds
      * <p>This value defines the maximum error of all timestamps for events reported to
      * {@link RangingSession.Callback}.
@@ -339,50 +208,6 @@
     }
 
     /**
-     * Get the number of simultaneous sessions allowed in the system
-     *
-     * @return the maximum allowed number of simultaneously open {@link RangingSession} instances.
-     */
-    @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
-    public int getMaxSimultaneousSessions() {
-        try {
-            return mUwbAdapter.getMaxSimultaneousSessions();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the maximum number of remote devices in a {@link RangingSession} when the local device
-     * is the initiator.
-     *
-     * @return the maximum number of remote devices per {@link RangingSession}
-     */
-    @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
-    public int getMaxRemoteDevicesPerInitiatorSession() {
-        try {
-            return mUwbAdapter.getMaxRemoteDevicesPerInitiatorSession();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
-     * Get the maximum number of remote devices in a {@link RangingSession} when the local device
-     * is a responder.
-     *
-     * @return the maximum number of remote devices per {@link RangingSession}
-     */
-    @RequiresPermission(Manifest.permission.UWB_PRIVILEGED)
-    public int getMaxRemoteDevicesPerResponderSession() {
-        try {
-            return mUwbAdapter.getMaxRemoteDevicesPerResponderSession();
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Open a {@link RangingSession} with the given parameters
      * <p>The {@link RangingSession.Callback#onOpened(RangingSession)} function is called with a
      * {@link RangingSession} object used to control ranging when the session is successfully
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index e66b17a..c43c410 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -77,3 +77,7 @@
 per-file ViewRootInsetsControllerHost.java = file:/services/core/java/com/android/server/wm/OWNERS
 per-file Window*.java = file:/services/core/java/com/android/server/wm/OWNERS
 per-file Window*.aidl = file:/services/core/java/com/android/server/wm/OWNERS
+
+# Scroll Capture
+per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
+per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index c5ca886..8810814 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1911,7 +1911,10 @@
         if (client == null) {
             return;
         }
-
+        if (mService == null) {
+            Log.w(TAG, "Autofill service is null!");
+            return;
+        }
         if (mServiceClient == null) {
             mServiceClient = new AutofillManagerClient(this);
             try {
diff --git a/core/java/com/android/internal/graphics/palette/OWNERS b/core/java/com/android/internal/graphics/palette/OWNERS
new file mode 100644
index 0000000..731dca9
--- /dev/null
+++ b/core/java/com/android/internal/graphics/palette/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 484670

+dupin@google.com

+jamesoleary@google.com
\ No newline at end of file
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 2d75b70..c34b9f0 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -11879,16 +11879,17 @@
         final int numClusters = mPowerProfile.getNumCpuClusters();
         mWakeLockAllocationsUs = null;
         final long startTimeMs = mClocks.uptimeMillis();
+        final List<Integer> uidsToRemove = new ArrayList<>();
         mCpuUidFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> {
             uid = mapUid(uid);
             if (Process.isIsolated(uid)) {
-                mCpuUidFreqTimeReader.removeUid(uid);
+                uidsToRemove.add(uid);
                 Slog.d(TAG, "Got freq readings for an isolated uid with no mapping: " + uid);
                 return;
             }
             if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
                 Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid);
-                mCpuUidFreqTimeReader.removeUid(uid);
+                uidsToRemove.add(uid);
                 return;
             }
             final Uid u = getUidStatsLocked(uid);
@@ -11947,6 +11948,9 @@
                 }
             }
         });
+        for (int uid : uidsToRemove) {
+            mCpuUidFreqTimeReader.removeUid(uid);
+        }
 
         final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
         if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
@@ -11992,21 +11996,25 @@
     @VisibleForTesting
     public void readKernelUidCpuActiveTimesLocked(boolean onBattery) {
         final long startTimeMs = mClocks.uptimeMillis();
+        final List<Integer> uidsToRemove = new ArrayList<>();
         mCpuUidActiveTimeReader.readDelta((uid, cpuActiveTimesMs) -> {
             uid = mapUid(uid);
             if (Process.isIsolated(uid)) {
-                mCpuUidActiveTimeReader.removeUid(uid);
+                uidsToRemove.add(uid);
                 Slog.w(TAG, "Got active times for an isolated uid with no mapping: " + uid);
                 return;
             }
             if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
                 Slog.w(TAG, "Got active times for an invalid user's uid " + uid);
-                mCpuUidActiveTimeReader.removeUid(uid);
+                uidsToRemove.add(uid);
                 return;
             }
             final Uid u = getUidStatsLocked(uid);
             u.mCpuActiveTimeMs.addCountLocked(cpuActiveTimesMs, onBattery);
         });
+        for (int uid : uidsToRemove) {
+            mCpuUidActiveTimeReader.removeUid(uid);
+        }
 
         final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
         if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
@@ -12021,21 +12029,25 @@
     @VisibleForTesting
     public void readKernelUidCpuClusterTimesLocked(boolean onBattery) {
         final long startTimeMs = mClocks.uptimeMillis();
+        final List<Integer> uidsToRemove = new ArrayList<>();
         mCpuUidClusterTimeReader.readDelta((uid, cpuClusterTimesMs) -> {
             uid = mapUid(uid);
             if (Process.isIsolated(uid)) {
-                mCpuUidClusterTimeReader.removeUid(uid);
+                uidsToRemove.add(uid);
                 Slog.w(TAG, "Got cluster times for an isolated uid with no mapping: " + uid);
                 return;
             }
             if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
                 Slog.w(TAG, "Got cluster times for an invalid user's uid " + uid);
-                mCpuUidClusterTimeReader.removeUid(uid);
+                uidsToRemove.add(uid);
                 return;
             }
             final Uid u = getUidStatsLocked(uid);
             u.mCpuClusterTimesMs.addCountLocked(cpuClusterTimesMs, onBattery);
         });
+        for (int uid : uidsToRemove) {
+            mCpuUidClusterTimeReader.removeUid(uid);
+        }
 
         final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
         if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
diff --git a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
index f7fad2c..2dd51b4 100644
--- a/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
+++ b/core/java/com/android/internal/os/KernelCpuUidTimeReader.java
@@ -143,6 +143,10 @@
      */
     public void removeUid(int uid) {
         mLastTimes.delete(uid);
+
+        if (mBpfTimesAvailable) {
+            mBpfReader.removeUidsInRange(uid, uid);
+        }
     }
 
     /**
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 65beb93..d99f305 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -18,8 +18,8 @@
 
 import static android.system.OsConstants.O_CLOEXEC;
 
-import static com.android.internal.os.ZygoteConnectionConstants.MAX_ZYGOTE_ARGC;
-
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.pm.ApplicationInfo;
 import android.net.Credentials;
 import android.net.LocalServerSocket;
@@ -36,17 +36,16 @@
 
 import com.android.internal.net.NetworkUtilsInternal;
 
+import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
 import dalvik.system.ZygoteHooks;
 
 import libcore.io.IoUtils;
 
-import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.io.InputStreamReader;
 
 /** @hide */
 public final class Zygote {
@@ -103,7 +102,7 @@
      */
     public static final int PROFILE_FROM_SHELL = 1 << 15;
 
-    /**
+    /*
      * Enable using the ART app image startup cache
      */
     public static final int USE_APP_IMAGE_STARTUP_CACHE = 1 << 16;
@@ -116,7 +115,16 @@
      */
     public static final int DEBUG_IGNORE_APP_SIGNAL_HANDLER = 1 << 17;
 
+    /**
+     * Disable runtime access to {@link android.annotation.TestApi} annotated members.
+     *
+     * <p>This only takes effect if Hidden API access restrictions are enabled as well.
+     */
+    public static final int DISABLE_TEST_API_ENFORCEMENT_POLICY = 1 << 18;
+
     public static final int MEMORY_TAG_LEVEL_MASK = (1 << 19) | (1 << 20);
+
+    public static final int MEMORY_TAG_LEVEL_NONE = 0;
     /**
      * Enable pointer tagging in this process.
      * Tags are checked during memory deallocation, but not on access.
@@ -162,6 +170,11 @@
      */
     public static final int GWP_ASAN_LEVEL_ALWAYS = 2 << 21;
 
+    /**
+     * Enable automatic zero-initialization of native heap memory allocations.
+     */
+    public static final int NATIVE_HEAP_ZERO_INIT = 1 << 23;
+
     /** No external storage should be mounted. */
     public static final int MOUNT_EXTERNAL_NONE = IVold.REMOUNT_MODE_NONE;
     /** Default external storage should be mounted. */
@@ -236,6 +249,8 @@
      */
     public static final String CHILD_ZYGOTE_UID_RANGE_END = "--uid-range-end=";
 
+    private static final String TAG = "Zygote";
+
     /** Prefix prepended to socket names created by init */
     private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";
 
@@ -406,6 +421,10 @@
         // Note that this event ends at the end of handleChildProc.
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "PostFork");
 
+        if (gids != null && gids.length > 0) {
+            NetworkUtilsInternal.setAllowNetworkingForProcess(containsInetGid(gids));
+        }
+
         // Set the Java Language thread priority to the default value for new apps.
         Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
 
@@ -578,114 +597,163 @@
     private static native int nativeGetUsapPoolEventFD();
 
     /**
-     * Fork a new unspecialized app process from the zygote
+     * Fork a new unspecialized app process from the zygote. Adds the Usap to the native
+     * Usap table.
      *
      * @param usapPoolSocket  The server socket the USAP will call accept on
-     * @param sessionSocketRawFDs  Anonymous session sockets that are currently open
-     * @param isPriorityFork  Value controlling the process priority level until accept is called
-     * @return In the Zygote process this function will always return null; in unspecialized app
-     *         processes this function will return a Runnable object representing the new
-     *         application that is passed up from usapMain.
+     * @param sessionSocketRawFDs  Anonymous session sockets that are currently open.
+     *         These are closed in the child.
+     * @param isPriorityFork Raise the initial process priority level because this is on the
+     *         critical path for application startup.
+     * @return In the child process, this returns a Runnable that waits for specialization
+     *         info to start an app process. In the sygote/parent process this returns null.
      */
-    static Runnable forkUsap(LocalServerSocket usapPoolSocket,
-                             int[] sessionSocketRawFDs,
-                             boolean isPriorityFork) {
-        FileDescriptor[] pipeFDs;
+    static @Nullable Runnable forkUsap(LocalServerSocket usapPoolSocket,
+                                       int[] sessionSocketRawFDs,
+                                       boolean isPriorityFork) {
+        FileDescriptor readFD;
+        FileDescriptor writeFD;
 
         try {
-            pipeFDs = Os.pipe2(O_CLOEXEC);
+            FileDescriptor[] pipeFDs = Os.pipe2(O_CLOEXEC);
+            readFD = pipeFDs[0];
+            writeFD = pipeFDs[1];
         } catch (ErrnoException errnoEx) {
             throw new IllegalStateException("Unable to create USAP pipe.", errnoEx);
         }
 
-        int pid =
-                nativeForkUsap(pipeFDs[0].getInt$(), pipeFDs[1].getInt$(),
-                               sessionSocketRawFDs, isPriorityFork);
-
+        int pid = nativeForkApp(readFD.getInt$(), writeFD.getInt$(),
+                                sessionSocketRawFDs, /*argsKnown=*/ false, isPriorityFork);
         if (pid == 0) {
-            IoUtils.closeQuietly(pipeFDs[0]);
-            return usapMain(usapPoolSocket, pipeFDs[1]);
+            IoUtils.closeQuietly(readFD);
+            return childMain(null, usapPoolSocket, writeFD);
+        } else if (pid == -1) {
+            // Fork failed.
+            return null;
         } else {
-            // The read-end of the pipe will be closed by the native code.
-            // See removeUsapTableEntry();
-            IoUtils.closeQuietly(pipeFDs[1]);
+            // readFD will be closed by the native code. See removeUsapTableEntry();
+            IoUtils.closeQuietly(writeFD);
+            nativeAddUsapTableEntry(pid, readFD.getInt$());
             return null;
         }
     }
 
-    private static native int nativeForkUsap(int readPipeFD,
-                                             int writePipeFD,
-                                             int[] sessionSocketRawFDs,
-                                             boolean isPriorityFork);
+    private static native int nativeForkApp(int readPipeFD,
+                                            int writePipeFD,
+                                            int[] sessionSocketRawFDs,
+                                            boolean argsKnown,
+                                            boolean isPriorityFork);
 
     /**
-     * This function is used by unspecialized app processes to wait for specialization requests from
-     * the system server.
+     * Add an entry for a new Usap to the table maintained in native code.
+     */
+    @CriticalNative
+    private static native void nativeAddUsapTableEntry(int pid, int readPipeFD);
+
+    /**
+     * Fork a new app process from the zygote. argBuffer contains a fork command that
+     * request neither a child zygote, nor a wrapped process. Continue to accept connections
+     * on the specified socket, use those to refill argBuffer, and continue to process
+     * sufficiently simple fork requests. We presume that the only open file descriptors
+     * requiring special treatment are the session socket embedded in argBuffer, and
+     * zygoteSocket.
+     * @param argBuffer containing initial command and the connected socket from which to
+     *         read more
+     * @param zygoteSocket socket from which to obtain new connections when current argBuffer
+     *         one is disconnected
+     * @param expectedUId Uid of peer for initial requests. Subsequent requests from a different
+     *               peer will cause us to return rather than perform the requested fork.
+     * @param minUid Minimum Uid enforced for all but first fork request. The caller checks
+     *               the Uid policy for the initial request.
+     * @param firstNiceName name of first created process. Used for error reporting only.
+     * @return A Runnable in each child process, null in the parent.
+     * If this returns in then argBuffer still contains a command needing to be executed.
+     */
+    static @Nullable Runnable forkSimpleApps(@NonNull ZygoteCommandBuffer argBuffer,
+                                             @NonNull FileDescriptor zygoteSocket,
+                                             int expectedUid,
+                                             int minUid,
+                                             @Nullable String firstNiceName) {
+        boolean in_child =
+                argBuffer.forkRepeatedly(zygoteSocket, expectedUid, minUid, firstNiceName);
+        if (in_child) {
+            return childMain(argBuffer, /*usapPoolSocket=*/null, /*writePipe=*/null);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Specialize the current process into one described by argBuffer or the command read from
+     * usapPoolSocket. Exactly one of those must be null. If we are given an argBuffer, we close
+     * it. Used both for a specializing a USAP process, and for process creation without USAPs.
+     * In both cases, we specialize the process after first returning to Java code.
      *
      * @param writePipe  The write end of the reporting pipe used to communicate with the poll loop
      *                   of the ZygoteServer.
      * @return A runnable oject representing the new application.
      */
-    private static Runnable usapMain(LocalServerSocket usapPoolSocket,
-                                     FileDescriptor writePipe) {
+    private static Runnable childMain(@Nullable ZygoteCommandBuffer argBuffer,
+                                      @Nullable LocalServerSocket usapPoolSocket,
+                                      FileDescriptor writePipe) {
         final int pid = Process.myPid();
-        Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32");
 
-        LocalSocket sessionSocket = null;
         DataOutputStream usapOutputStream = null;
-        Credentials peerCredentials = null;
         ZygoteArguments args = null;
 
-        // Change the priority to max before calling accept so we can respond to new specialization
-        // requests as quickly as possible.  This will be reverted to the default priority in the
-        // native specialization code.
-        boostUsapPriority();
+        // Block SIGTERM so we won't be killed if the Zygote flushes the USAP pool.
+        blockSigTerm();
 
-        while (true) {
-            try {
-                sessionSocket = usapPoolSocket.accept();
+        LocalSocket sessionSocket = null;
+        if (argBuffer == null) {
+            // Read arguments from usapPoolSocket instead.
 
-                // Block SIGTERM so we won't be killed if the Zygote flushes the USAP pool.
-                blockSigTerm();
+            Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32");
 
-                BufferedReader usapReader =
-                        new BufferedReader(new InputStreamReader(sessionSocket.getInputStream()));
-                usapOutputStream =
-                        new DataOutputStream(sessionSocket.getOutputStream());
+            // Change the priority to max before calling accept so we can respond to new
+            // specialization requests as quickly as possible.  This will be reverted to the
+            // default priority in the native specialization code.
+            boostUsapPriority();
 
-                peerCredentials = sessionSocket.getPeerCredentials();
+            while (true) {
+                ZygoteCommandBuffer tmpArgBuffer = null;
+                try {
+                    sessionSocket = usapPoolSocket.accept();
 
-                String[] argStrings = readArgumentList(usapReader);
-
-                if (argStrings != null) {
-                    args = new ZygoteArguments(argStrings);
-
+                    usapOutputStream =
+                            new DataOutputStream(sessionSocket.getOutputStream());
+                    Credentials peerCredentials = sessionSocket.getPeerCredentials();
+                    tmpArgBuffer = new ZygoteCommandBuffer(sessionSocket);
+                    args = ZygoteArguments.getInstance(argBuffer);
+                    applyUidSecurityPolicy(args, peerCredentials);
                     // TODO (chriswailes): Should this only be run for debug builds?
                     validateUsapCommand(args);
                     break;
-                } else {
-                    Log.e("USAP", "Truncated command received.");
-                    IoUtils.closeQuietly(sessionSocket);
-
-                    // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary.
-                    unblockSigTerm();
+                } catch (Exception ex) {
+                    Log.e("USAP", ex.getMessage());
                 }
-            } catch (Exception ex) {
-                Log.e("USAP", ex.getMessage());
-                IoUtils.closeQuietly(sessionSocket);
-
                 // Re-enable SIGTERM so the USAP can be flushed from the pool if necessary.
                 unblockSigTerm();
+                IoUtils.closeQuietly(sessionSocket);
+                IoUtils.closeQuietly(tmpArgBuffer);
+                blockSigTerm();
             }
+        } else {
+            try {
+                args = ZygoteArguments.getInstance(argBuffer);
+            } catch (Exception ex) {
+                Log.e("AppStartup", ex.getMessage());
+                throw new AssertionError("Failed to parse application start command", ex);
+            }
+            // peerCredentials were checked in parent.
         }
-
+        if (args == null) {
+            throw new AssertionError("Empty command line");
+        }
         try {
-            // SIGTERM is blocked on loop exit.  This prevents a USAP that is specializing from
-            // being killed during a pool flush.
+            // SIGTERM is blocked here.  This prevents a USAP that is specializing from being
+            // killed during a pool flush.
 
-            setAppProcessName(args, "USAP");
-
-            applyUidSecurityPolicy(args, peerCredentials);
             applyDebuggerSystemProperty(args);
 
             int[][] rlimits = null;
@@ -694,53 +762,57 @@
                 rlimits = args.mRLimits.toArray(INT_ARRAY_2D);
             }
 
-            // This must happen before the SELinux policy for this process is
-            // changed when specializing.
-            try {
-                // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
-                // Process.ProcessStartResult object.
-                usapOutputStream.writeInt(pid);
-            } catch (IOException ioEx) {
-                Log.e("USAP", "Failed to write response to session socket: "
-                        + ioEx.getMessage());
-                throw new RuntimeException(ioEx);
-            } finally {
-                IoUtils.closeQuietly(sessionSocket);
-
+            if (argBuffer == null) {
+                // This must happen before the SELinux policy for this process is
+                // changed when specializing.
                 try {
-                    // This socket is closed using Os.close due to an issue with the implementation
-                    // of LocalSocketImp.close().  Because the raw FD is created by init and then
-                    // loaded from an environment variable (as opposed to being created by the
-                    // LocalSocketImpl itself) the current implementation will not actually close
-                    // the underlying FD.
-                    //
-                    // See b/130309968 for discussion of this issue.
-                    Os.close(usapPoolSocket.getFileDescriptor());
-                } catch (ErrnoException ex) {
-                    Log.e("USAP", "Failed to close USAP pool socket");
-                    throw new RuntimeException(ex);
+                    // Used by ZygoteProcess.zygoteSendArgsAndGetResult to fill in a
+                    // Process.ProcessStartResult object.
+                    usapOutputStream.writeInt(pid);
+                } catch (IOException ioEx) {
+                    Log.e("USAP", "Failed to write response to session socket: "
+                            + ioEx.getMessage());
+                    throw new RuntimeException(ioEx);
+                } finally {
+                    try {
+                        // Since the raw FD is created by init and then loaded from an environment
+                        // variable (as opposed to being created by the LocalSocketImpl itself),
+                        // the LocalSocket/LocalSocketImpl does not own the Os-level socket. See
+                        // the spec for LocalSocket.createConnectedLocalSocket(FileDescriptor fd).
+                        // Thus closing the LocalSocket does not suffice. See b/130309968 for more
+                        // discussion.
+                        FileDescriptor fd = usapPoolSocket.getFileDescriptor();
+                        usapPoolSocket.close();
+                        Os.close(fd);
+                    } catch (ErrnoException | IOException ex) {
+                        Log.e("USAP", "Failed to close USAP pool socket");
+                        throw new RuntimeException(ex);
+                    }
                 }
             }
 
-            try {
-                ByteArrayOutputStream buffer =
-                        new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES);
-                DataOutputStream outputStream = new DataOutputStream(buffer);
+            if (writePipe != null) {
+                try {
+                    ByteArrayOutputStream buffer =
+                            new ByteArrayOutputStream(Zygote.USAP_MANAGEMENT_MESSAGE_BYTES);
+                    DataOutputStream outputStream = new DataOutputStream(buffer);
 
-                // This is written as a long so that the USAP reporting pipe and USAP pool event FD
-                // handlers in ZygoteServer.runSelectLoop can be unified.  These two cases should
-                // both send/receive 8 bytes.
-                outputStream.writeLong(pid);
-                outputStream.flush();
-
-                Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
-            } catch (Exception ex) {
-                Log.e("USAP",
-                        String.format("Failed to write PID (%d) to pipe (%d): %s",
-                                pid, writePipe.getInt$(), ex.getMessage()));
-                throw new RuntimeException(ex);
-            } finally {
-                IoUtils.closeQuietly(writePipe);
+                    // This is written as a long so that the USAP reporting pipe and USAP pool
+                    // event FD handlers in ZygoteServer.runSelectLoop can be unified.  These two
+                    // cases should both send/receive 8 bytes.
+                    // TODO: Needs tweaking to handle the non-Usap invoke-with case, which expects
+                    // a different format.
+                    outputStream.writeLong(pid);
+                    outputStream.flush();
+                    Os.write(writePipe, buffer.toByteArray(), 0, buffer.size());
+                } catch (Exception ex) {
+                    Log.e("USAP",
+                            String.format("Failed to write PID (%d) to pipe (%d): %s",
+                                    pid, writePipe.getInt$(), ex.getMessage()));
+                    throw new RuntimeException(ex);
+                } finally {
+                    IoUtils.closeQuietly(writePipe);
+                }
             }
 
             specializeAppProcess(args.mUid, args.mGid, args.mGids,
@@ -847,13 +919,29 @@
         return nativeRemoveUsapTableEntry(usapPID);
     }
 
+    @CriticalNative
     private static native boolean nativeRemoveUsapTableEntry(int usapPID);
 
     /**
-     * uid 1000 (Process.SYSTEM_UID) may specify any uid &gt; 1000 in normal
+     * Return the minimum child uid that the given peer is allowed to create.
+     * uid 1000 (Process.SYSTEM_UID) may specify any uid &ge; 1000 in normal
      * operation. It may also specify any gid and setgroups() list it chooses.
      * In factory test mode, it may specify any UID.
-     *
+     */
+    static int minChildUid(Credentials peer) {
+        if (peer.getUid() == Process.SYSTEM_UID
+                && FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF) {
+            /* In normal operation, SYSTEM_UID can only specify a restricted
+             * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
+             */
+            return Process.SYSTEM_UID;
+        } else {
+            return 0;
+        }
+    }
+
+    /*
+     * Adjust uid and gid arguments, ensuring that the security policy is satisfied.
      * @param args non-null; zygote spawner arguments
      * @param peer non-null; peer credentials
      * @throws ZygoteSecurityException Indicates a security issue when applying the UID based
@@ -862,17 +950,10 @@
     static void applyUidSecurityPolicy(ZygoteArguments args, Credentials peer)
             throws ZygoteSecurityException {
 
-        if (peer.getUid() == Process.SYSTEM_UID) {
-            /* In normal operation, SYSTEM_UID can only specify a restricted
-             * set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
-             */
-            boolean uidRestricted = FactoryTest.getMode() == FactoryTest.FACTORY_TEST_OFF;
-
-            if (uidRestricted && args.mUidSpecified && (args.mUid < Process.SYSTEM_UID)) {
-                throw new ZygoteSecurityException(
-                        "System UID may not launch process with UID < "
-                        + Process.SYSTEM_UID);
-            }
+        if (args.mUidSpecified && (args.mUid < minChildUid(peer))) {
+            throw new ZygoteSecurityException(
+                    "System UID may not launch process with UID < "
+                    + Process.SYSTEM_UID);
         }
 
         // If not otherwise specified, uid and gid are inherited from peer
@@ -958,45 +1039,6 @@
     }
 
     /**
-     * Reads an argument list from the provided socket
-     * @return Argument list or null if EOF is reached
-     * @throws IOException passed straight through
-     */
-    static String[] readArgumentList(BufferedReader socketReader) throws IOException {
-        int argc;
-
-        try {
-            String argc_string = socketReader.readLine();
-
-            if (argc_string == null) {
-                // EOF reached.
-                return null;
-            }
-            argc = Integer.parseInt(argc_string);
-
-        } catch (NumberFormatException ex) {
-            Log.e("Zygote", "Invalid Zygote wire format: non-int at argc");
-            throw new IOException("Invalid wire format");
-        }
-
-        // See bug 1092107: large argc can be used for a DOS attack
-        if (argc > MAX_ZYGOTE_ARGC) {
-            throw new IOException("Max arg count exceeded");
-        }
-
-        String[] args = new String[argc];
-        for (int arg_index = 0; arg_index < argc; arg_index++) {
-            args[arg_index] = socketReader.readLine();
-            if (args[arg_index] == null) {
-                // We got an unexpected EOF.
-                throw new IOException("Truncated request");
-            }
-        }
-
-        return args;
-    }
-
-    /**
      * Creates a managed LocalServerSocket object using a file descriptor
      * created by an init.rc script.  The init scripts that specify the
      * sockets name can be found in system/core/rootdir.  The socket is bound
diff --git a/core/java/com/android/internal/os/ZygoteArguments.java b/core/java/com/android/internal/os/ZygoteArguments.java
index ed07432..5a1c171 100644
--- a/core/java/com/android/internal/os/ZygoteArguments.java
+++ b/core/java/com/android/internal/os/ZygoteArguments.java
@@ -16,8 +16,8 @@
 
 package com.android.internal.os;
 
+import java.io.EOFException;
 import java.util.ArrayList;
-import java.util.Arrays;
 
 /**
  * Handles argument parsing for args related to the zygote spawner.
@@ -245,20 +245,34 @@
     /**
      * Constructs instance and parses args
      *
-     * @param args zygote command-line args
+     * @param args zygote command-line args as ZygoteCommandBuffer, positioned after argument count.
      */
-    ZygoteArguments(String[] args) throws IllegalArgumentException {
-        parseArgs(args);
+    private ZygoteArguments(ZygoteCommandBuffer args, int argCount)
+            throws IllegalArgumentException, EOFException {
+        parseArgs(args, argCount);
+    }
+
+    /**
+     * Return a new ZygoteArguments reflecting the contents of the given ZygoteCommandBuffer. Return
+     * null if the ZygoteCommandBuffer was positioned at EOF. Assumes the buffer is initially
+     * positioned at the beginning of the command.
+     */
+    public static ZygoteArguments getInstance(ZygoteCommandBuffer args)
+            throws IllegalArgumentException, EOFException {
+        int argCount = args.getCount();
+        return argCount == 0 ? null : new ZygoteArguments(args, argCount);
     }
 
     /**
      * Parses the commandline arguments intended for the Zygote spawner (such as "--setuid=" and
-     * "--setgid=") and creates an array containing the remaining args.
+     * "--setgid=") and creates an array containing the remaining args. Return false if we were
+     * at EOF.
      *
      * Per security review bug #1112214, duplicate args are disallowed in critical cases to make
      * injection harder.
      */
-    private void parseArgs(String[] args) throws IllegalArgumentException {
+    private void parseArgs(ZygoteCommandBuffer args, int argCount)
+            throws IllegalArgumentException, EOFException {
         /*
          * See android.os.ZygoteProcess.zygoteSendArgsAndGetResult()
          * Presently the wire format to the zygote process is:
@@ -269,13 +283,13 @@
          * the child or -1 on failure.
          */
 
-        int curArg = 0;
-
+        String unprocessedArg = null;
+        int curArg = 0;  // Index of arg
         boolean seenRuntimeArgs = false;
-
         boolean expectRuntimeArgs = true;
-        for ( /* curArg */ ; curArg < args.length; curArg++) {
-            String arg = args[curArg];
+
+        for ( /* curArg */ ; curArg < argCount; ++curArg) {
+            String arg = args.nextArg();
 
             if (arg.equals("--")) {
                 curArg++;
@@ -367,7 +381,8 @@
                         "Duplicate arg specified");
                 }
                 try {
-                    mInvokeWith = args[++curArg];
+                    ++curArg;
+                    mInvokeWith = args.nextArg();
                 } catch (IndexOutOfBoundsException ex) {
                     throw new IllegalArgumentException(
                         "--invoke-with requires argument");
@@ -405,12 +420,14 @@
             } else if (arg.startsWith("--app-data-dir=")) {
                 mAppDataDir = getAssignmentValue(arg);
             } else if (arg.equals("--preload-app")) {
-                mPreloadApp = args[++curArg];
+                ++curArg;
+                mPreloadApp = args.nextArg();
             } else if (arg.equals("--preload-package")) {
-                mPreloadPackage = args[++curArg];
-                mPreloadPackageLibs = args[++curArg];
-                mPreloadPackageLibFileName = args[++curArg];
-                mPreloadPackageCacheKey = args[++curArg];
+                curArg += 4;
+                mPreloadPackage = args.nextArg();
+                mPreloadPackageLibs = args.nextArg();
+                mPreloadPackageLibFileName = args.nextArg();
+                mPreloadPackageCacheKey = args.nextArg();
             } else if (arg.equals("--preload-default")) {
                 mPreloadDefault = true;
                 expectRuntimeArgs = false;
@@ -419,8 +436,11 @@
             } else if (arg.equals("--set-api-denylist-exemptions")) {
                 // consume all remaining args; this is a stand-alone command, never included
                 // with the regular fork command.
-                mApiDenylistExemptions = Arrays.copyOfRange(args, curArg + 1, args.length);
-                curArg = args.length;
+                mApiDenylistExemptions = new String[argCount - curArg - 1];
+                ++curArg;
+                for (int i = 0; curArg < argCount; ++curArg, ++i) {
+                    mApiDenylistExemptions[i] = args.nextArg();
+                }
                 expectRuntimeArgs = false;
             } else if (arg.startsWith("--hidden-api-log-sampling-rate=")) {
                 String rateStr = getAssignmentValue(arg);
@@ -470,35 +490,46 @@
             } else if (arg.equals(Zygote.BIND_MOUNT_APP_DATA_DIRS)) {
                 mBindMountAppDataDirs = true;
             } else {
+                unprocessedArg = arg;
                 break;
             }
         }
+        // curArg is the index of the first unprocessed argument. That argument is either referenced
+        // by unprocessedArg or not read yet.
 
         if (mBootCompleted) {
-            if (args.length - curArg > 0) {
+            if (argCount > curArg) {
                 throw new IllegalArgumentException("Unexpected arguments after --boot-completed");
             }
         } else if (mAbiListQuery || mPidQuery) {
-            if (args.length - curArg > 0) {
+            if (argCount > curArg) {
                 throw new IllegalArgumentException("Unexpected arguments after --query-abi-list.");
             }
         } else if (mPreloadPackage != null) {
-            if (args.length - curArg > 0) {
+            if (argCount > curArg) {
                 throw new IllegalArgumentException(
                     "Unexpected arguments after --preload-package.");
             }
         } else if (mPreloadApp != null) {
-            if (args.length - curArg > 0) {
+            if (argCount > curArg) {
                 throw new IllegalArgumentException(
                     "Unexpected arguments after --preload-app.");
             }
         } else if (expectRuntimeArgs) {
             if (!seenRuntimeArgs) {
-                throw new IllegalArgumentException("Unexpected argument : " + args[curArg]);
+                throw new IllegalArgumentException("Unexpected argument : "
+                    + (unprocessedArg == null ? args.nextArg() : unprocessedArg));
             }
 
-            mRemainingArgs = new String[args.length - curArg];
-            System.arraycopy(args, curArg, mRemainingArgs, 0, mRemainingArgs.length);
+            mRemainingArgs = new String[argCount - curArg];
+            int i = 0;
+            if (unprocessedArg != null) {
+                mRemainingArgs[0] = unprocessedArg;
+                ++i;
+            }
+            for (; i < argCount - curArg; ++i) {
+                mRemainingArgs[i] = args.nextArg();
+            }
         }
 
         if (mStartChildZygote) {
diff --git a/core/java/com/android/internal/os/ZygoteCommandBuffer.java b/core/java/com/android/internal/os/ZygoteCommandBuffer.java
new file mode 100644
index 0000000..b61ae7a
--- /dev/null
+++ b/core/java/com/android/internal/os/ZygoteCommandBuffer.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.LocalSocket;
+
+import java.io.FileDescriptor;
+import java.lang.ref.Reference;  // For reachabilityFence.
+
+/**
+ * A native-accessible buffer for Zygote commands. Designed to support repeated forking
+ * of applications without intervening memory allocation, thus keeping zygote memory
+ * as stable as possible.
+ * A ZygoteCommandBuffer may have an associated socket from which it can be refilled.
+ * Otherwise the contents are explicitly set by getInstance().
+ *
+ * NOT THREAD-SAFE. No methods may be called concurrently from multiple threads.
+ *
+ * Only one ZygoteCommandBuffer can exist at a time.
+ * Must be explicitly closed before being dropped.
+ * @hide
+ */
+class ZygoteCommandBuffer implements AutoCloseable {
+    private long mNativeBuffer;  // Not final so that we can clear it in close().
+
+    /**
+     * The command socket.
+     *
+     * mSocket is retained in the child process in "peer wait" mode, so
+     * that it closes when the child process terminates. In other cases,
+     * it is closed in the peer.
+     */
+    private final LocalSocket mSocket;
+    private final int mNativeSocket;
+
+    /**
+     * Constructs instance from file descriptor from which the command will be read.
+     * Only a single instance may be live in a given process. The native code checks.
+     *
+     * @param fd file descriptor to read from. The setCommand() method may be used if and only if
+     * fd is null.
+     */
+    ZygoteCommandBuffer(@Nullable LocalSocket socket) {
+        mSocket = socket;
+        if (socket == null) {
+            mNativeSocket = -1;
+        } else {
+            mNativeSocket = mSocket.getFileDescriptor().getInt$();
+        }
+        mNativeBuffer = getNativeBuffer(mNativeSocket);
+    }
+
+    /**
+     * Constructs an instance with explicitly supplied arguments and an invalid
+     * file descriptor. Can only be used for a single command.
+     */
+    ZygoteCommandBuffer(@NonNull String[] args) {
+        this((LocalSocket) null);
+        setCommand(args);
+    }
+
+
+    private static native long getNativeBuffer(int fd);
+
+    /**
+     * Deallocate native resources associated with the one and only command buffer, and prevent
+     * reuse. Subsequent calls to getInstance() will yield a new buffer.
+     * We do not close the associated socket, if any.
+     */
+    @Override
+    public void close() {
+        freeNativeBuffer(mNativeBuffer);
+        mNativeBuffer = 0;
+    }
+
+    private static native void freeNativeBuffer(long /* NativeCommandBuffer* */ nbuffer);
+
+    /**
+     * Read at least the first line of the next command into the buffer, return the argument count
+     * from that line. Assumes we are initially positioned at the beginning of the first line of
+     * the command. Leave the buffer positioned at the beginning of the second command line, i.e.
+     * the first argument. If the buffer has no associated file descriptor, we just reposition to
+     * the beginning of the buffer, and reread existing contents.  Returns zero if we started out
+     * at EOF.
+     */
+    int getCount() {
+        try {
+            return nativeGetCount(mNativeBuffer);
+        } finally {
+            // Make sure the mNativeSocket doesn't get closed due to early finalization.
+            Reference.reachabilityFence(mSocket);
+        }
+    }
+
+    private static native int nativeGetCount(long /* NativeCommandBuffer* */ nbuffer);
+
+
+    /*
+     * Set the buffer to contain the supplied sequence of arguments.
+     */
+    private void setCommand(String[] command) {
+        int nArgs = command.length;
+        insert(mNativeBuffer, Integer.toString(nArgs));
+        for (String s: command) {
+            insert(mNativeBuffer, s);
+        }
+        // Native code checks there is no socket; hence no reachabilityFence.
+    }
+
+    private static native void insert(long /* NativeCommandBuffer* */ nbuffer, String s);
+
+    /**
+     * Retrieve the next argument/line from the buffer, filling the buffer as necessary.
+     */
+    String nextArg() {
+        try {
+            return nativeNextArg(mNativeBuffer);
+        } finally {
+            Reference.reachabilityFence(mSocket);
+        }
+    }
+
+    private static native String nativeNextArg(long /* NativeCommandBuffer* */ nbuffer);
+
+    void readFullyAndReset() {
+        try {
+            nativeReadFullyAndReset(mNativeBuffer);
+        } finally {
+            Reference.reachabilityFence(mSocket);
+        }
+    }
+
+    private static native void nativeReadFullyAndReset(long /* NativeCommandBuffer* */ nbuffer);
+
+    /**
+     * Fork a child as specified by the current command in the buffer, and repeat this process
+     * after refilling the buffer, so long as the buffer clearly contains another fork command.
+     *
+     * @param zygoteSocket socket from which to obtain new connections when current one is
+     *         disconnected
+     * @param expectedUid Peer UID for current connection. We refuse to deal with requests from
+     *         a different UID.
+     * @param minUid the smallest uid that may be request for the child process.
+     * @param firstNiceName The name for the initial process to be forked. Used only for error
+     *         reporting.
+     *
+     * @return true in the child, false in the parent. In the parent case, the buffer is positioned
+     * at the beginning of a command that still needs to be processed.
+     */
+    boolean forkRepeatedly(FileDescriptor zygoteSocket, int expectedUid, int minUid,
+                       String firstNiceName) {
+        try {
+            return nativeForkRepeatedly(mNativeBuffer, zygoteSocket.getInt$(),
+                    expectedUid, minUid, firstNiceName);
+        } finally {
+            Reference.reachabilityFence(mSocket);
+            Reference.reachabilityFence(zygoteSocket);
+        }
+    }
+
+    /*
+     * Repeatedly fork children as above. It commonly does not return in the parent, but it may.
+     * @return true in the chaild, false in the parent if we encounter a command we couldn't handle.
+     */
+    private static native boolean nativeForkRepeatedly(long /* NativeCommandBuffer* */ nbuffer,
+                                                   int zygoteSocketRawFd,
+                                                   int expectedUid,
+                                                   int minUid,
+                                                   String firstNiceName);
+
+}
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 5a576ebb..37c7590 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -36,16 +36,15 @@
 import android.util.Log;
 
 import dalvik.system.VMRuntime;
+import dalvik.system.ZygoteHooks;
 
 import libcore.io.IoUtils;
 
-import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.FileDescriptor;
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.nio.charset.StandardCharsets;
 import java.util.Base64;
 import java.util.concurrent.TimeUnit;
@@ -67,7 +66,6 @@
     private final LocalSocket mSocket;
     @UnsupportedAppUsage
     private final DataOutputStream mSocketOutStream;
-    private final BufferedReader mSocketReader;
     @UnsupportedAppUsage
     private final Credentials peer;
     private final String abiList;
@@ -85,9 +83,6 @@
         this.abiList = abiList;
 
         mSocketOutStream = new DataOutputStream(socket.getOutputStream());
-        mSocketReader =
-                new BufferedReader(
-                        new InputStreamReader(socket.getInputStream()), Zygote.SOCKET_BUFFER_SIZE);
 
         mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS);
 
@@ -111,178 +106,216 @@
     }
 
     /**
-     * Reads one start command from the command socket. If successful, a child is forked and a
+     * Reads a command from the command socket. If a child is successfully forked, a
      * {@code Runnable} that calls the childs main method (or equivalent) is returned in the child
      * process. {@code null} is always returned in the parent process (the zygote).
+     * If multipleOK is set, we may keep processing additional fork commands before returning.
      *
      * If the client closes the socket, an {@code EOF} condition is set, which callers can test
      * for by calling {@code ZygoteConnection.isClosedByPeer}.
      */
-    Runnable processOneCommand(ZygoteServer zygoteServer) {
-        String[] args;
+    Runnable processCommand(ZygoteServer zygoteServer, boolean multipleOK) {
+        ZygoteArguments parsedArgs;
 
-        try {
-            args = Zygote.readArgumentList(mSocketReader);
-        } catch (IOException ex) {
-            throw new IllegalStateException("IOException on command socket", ex);
+        try (ZygoteCommandBuffer argBuffer = new ZygoteCommandBuffer(mSocket)) {
+            while (true) {
+                try {
+                    parsedArgs = ZygoteArguments.getInstance(argBuffer);
+                    // Keep argBuffer around, since we need it to fork.
+                } catch (IOException ex) {
+                    throw new IllegalStateException("IOException on command socket", ex);
+                }
+                if (parsedArgs == null) {
+                    isEof = true;
+                    return null;
+                }
+
+                int pid;
+                FileDescriptor childPipeFd = null;
+                FileDescriptor serverPipeFd = null;
+
+                if (parsedArgs.mBootCompleted) {
+                    handleBootCompleted();
+                    return null;
+                }
+
+                if (parsedArgs.mAbiListQuery) {
+                    handleAbiListQuery();
+                    return null;
+                }
+
+                if (parsedArgs.mPidQuery) {
+                    handlePidQuery();
+                    return null;
+                }
+
+                if (parsedArgs.mUsapPoolStatusSpecified) {
+                    // Handle this once we've released the argBuffer, to avoid opening a second one.
+                    break;
+                }
+
+                if (parsedArgs.mPreloadDefault) {
+                    handlePreload();
+                    return null;
+                }
+
+                if (parsedArgs.mPreloadPackage != null) {
+                    handlePreloadPackage(parsedArgs.mPreloadPackage,
+                            parsedArgs.mPreloadPackageLibs,
+                            parsedArgs.mPreloadPackageLibFileName,
+                            parsedArgs.mPreloadPackageCacheKey);
+                    return null;
+                }
+
+                if (canPreloadApp() && parsedArgs.mPreloadApp != null) {
+                    byte[] rawParcelData = Base64.getDecoder().decode(parsedArgs.mPreloadApp);
+                    Parcel appInfoParcel = Parcel.obtain();
+                    appInfoParcel.unmarshall(rawParcelData, 0, rawParcelData.length);
+                    appInfoParcel.setDataPosition(0);
+                    ApplicationInfo appInfo =
+                            ApplicationInfo.CREATOR.createFromParcel(appInfoParcel);
+                    appInfoParcel.recycle();
+                    if (appInfo != null) {
+                        handlePreloadApp(appInfo);
+                    } else {
+                        throw new IllegalArgumentException("Failed to deserialize --preload-app");
+                    }
+                    return null;
+                }
+
+                if (parsedArgs.mApiDenylistExemptions != null) {
+                    return handleApiDenylistExemptions(zygoteServer,
+                            parsedArgs.mApiDenylistExemptions);
+                }
+
+                if (parsedArgs.mHiddenApiAccessLogSampleRate != -1
+                        || parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) {
+                    return handleHiddenApiAccessLogSampleRate(zygoteServer,
+                            parsedArgs.mHiddenApiAccessLogSampleRate,
+                            parsedArgs.mHiddenApiAccessStatslogSampleRate);
+                }
+
+                if (parsedArgs.mPermittedCapabilities != 0
+                        || parsedArgs.mEffectiveCapabilities != 0) {
+                    throw new ZygoteSecurityException("Client may not specify capabilities: "
+                            + "permitted=0x" + Long.toHexString(parsedArgs.mPermittedCapabilities)
+                            + ", effective=0x"
+                            + Long.toHexString(parsedArgs.mEffectiveCapabilities));
+                }
+
+                Zygote.applyUidSecurityPolicy(parsedArgs, peer);
+                Zygote.applyInvokeWithSecurityPolicy(parsedArgs, peer);
+
+                Zygote.applyDebuggerSystemProperty(parsedArgs);
+                Zygote.applyInvokeWithSystemProperty(parsedArgs);
+
+                int[][] rlimits = null;
+
+                if (parsedArgs.mRLimits != null) {
+                    rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D);
+                }
+
+                int[] fdsToIgnore = null;
+
+                if (parsedArgs.mInvokeWith != null) {
+                    try {
+                        FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
+                        childPipeFd = pipeFds[1];
+                        serverPipeFd = pipeFds[0];
+                        Os.fcntlInt(childPipeFd, F_SETFD, 0);
+                        fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
+                    } catch (ErrnoException errnoEx) {
+                        throw new IllegalStateException("Unable to set up pipe for invoke-with",
+                                errnoEx);
+                    }
+                }
+
+                /*
+                 * In order to avoid leaking descriptors to the Zygote child,
+                 * the native code must close the two Zygote socket descriptors
+                 * in the child process before it switches from Zygote-root to
+                 * the UID and privileges of the application being launched.
+                 *
+                 * In order to avoid "bad file descriptor" errors when the
+                 * two LocalSocket objects are closed, the Posix file
+                 * descriptors are released via a dup2() call which closes
+                 * the socket and substitutes an open descriptor to /dev/null.
+                 */
+
+                int [] fdsToClose = { -1, -1 };
+
+                FileDescriptor fd = mSocket.getFileDescriptor();
+
+                if (fd != null) {
+                    fdsToClose[0] = fd.getInt$();
+                }
+
+                FileDescriptor zygoteFd = zygoteServer.getZygoteSocketFileDescriptor();
+
+                if (zygoteFd != null) {
+                    fdsToClose[1] = zygoteFd.getInt$();
+                }
+
+                if (parsedArgs.mInvokeWith != null || parsedArgs.mStartChildZygote
+                        || !multipleOK || peer.getUid() != Process.SYSTEM_UID) {
+                    // Continue using old code for now. TODO: Handle these cases in the other path.
+                    pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid,
+                            parsedArgs.mGids, parsedArgs.mRuntimeFlags, rlimits,
+                            parsedArgs.mMountExternal, parsedArgs.mSeInfo, parsedArgs.mNiceName,
+                            fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
+                            parsedArgs.mInstructionSet, parsedArgs.mAppDataDir,
+                            parsedArgs.mIsTopApp, parsedArgs.mPkgDataInfoList,
+                            parsedArgs.mWhitelistedDataInfoList, parsedArgs.mBindMountAppDataDirs,
+                            parsedArgs.mBindMountAppStorageDirs);
+
+                    try {
+                        if (pid == 0) {
+                            // in child
+                            zygoteServer.setForkChild();
+
+                            zygoteServer.closeServerSocket();
+                            IoUtils.closeQuietly(serverPipeFd);
+                            serverPipeFd = null;
+
+                            return handleChildProc(parsedArgs, childPipeFd,
+                                    parsedArgs.mStartChildZygote);
+                        } else {
+                            // In the parent. A pid < 0 indicates a failure and will be handled in
+                            // handleParentProc.
+                            IoUtils.closeQuietly(childPipeFd);
+                            childPipeFd = null;
+                            handleParentProc(pid, serverPipeFd);
+                            return null;
+                        }
+                    } finally {
+                        IoUtils.closeQuietly(childPipeFd);
+                        IoUtils.closeQuietly(serverPipeFd);
+                    }
+                } else {
+                    ZygoteHooks.preFork();
+                    Runnable result = Zygote.forkSimpleApps(argBuffer,
+                            zygoteServer.getZygoteSocketFileDescriptor(),
+                            peer.getUid(), Zygote.minChildUid(peer), parsedArgs.mNiceName);
+                    if (result == null) {
+                        // parent; we finished some number of forks. Result is Boolean.
+                        // We already did the equivalent of handleParentProc().
+                        ZygoteHooks.postForkCommon();
+                        // argBuffer contains a command not understood by forksimpleApps.
+                        continue;
+                    } else {
+                        // child; result is a Runnable.
+                        zygoteServer.setForkChild();
+                        Zygote.setAppProcessName(parsedArgs, TAG);  // ??? Necessary?
+                        return result;
+                    }
+                }
+            }
         }
-
-        // readArgumentList returns null only when it has reached EOF with no available
-        // data to read. This will only happen when the remote socket has disconnected.
-        if (args == null) {
-            isEof = true;
-            return null;
-        }
-
-        int pid;
-        FileDescriptor childPipeFd = null;
-        FileDescriptor serverPipeFd = null;
-
-        ZygoteArguments parsedArgs = new ZygoteArguments(args);
-
-        if (parsedArgs.mBootCompleted) {
-            handleBootCompleted();
-            return null;
-        }
-
-        if (parsedArgs.mAbiListQuery) {
-            handleAbiListQuery();
-            return null;
-        }
-
-        if (parsedArgs.mPidQuery) {
-            handlePidQuery();
-            return null;
-        }
-
         if (parsedArgs.mUsapPoolStatusSpecified) {
+            // Now that we've released argBuffer:
             return handleUsapPoolStatusChange(zygoteServer, parsedArgs.mUsapPoolEnabled);
         }
-
-        if (parsedArgs.mPreloadDefault) {
-            handlePreload();
-            return null;
-        }
-
-        if (parsedArgs.mPreloadPackage != null) {
-            handlePreloadPackage(parsedArgs.mPreloadPackage, parsedArgs.mPreloadPackageLibs,
-                    parsedArgs.mPreloadPackageLibFileName, parsedArgs.mPreloadPackageCacheKey);
-            return null;
-        }
-
-        if (canPreloadApp() && parsedArgs.mPreloadApp != null) {
-            byte[] rawParcelData = Base64.getDecoder().decode(parsedArgs.mPreloadApp);
-            Parcel appInfoParcel = Parcel.obtain();
-            appInfoParcel.unmarshall(rawParcelData, 0, rawParcelData.length);
-            appInfoParcel.setDataPosition(0);
-            ApplicationInfo appInfo = ApplicationInfo.CREATOR.createFromParcel(appInfoParcel);
-            appInfoParcel.recycle();
-            if (appInfo != null) {
-                handlePreloadApp(appInfo);
-            } else {
-                throw new IllegalArgumentException("Failed to deserialize --preload-app");
-            }
-            return null;
-        }
-
-        if (parsedArgs.mApiDenylistExemptions != null) {
-            return handleApiDenylistExemptions(zygoteServer, parsedArgs.mApiDenylistExemptions);
-        }
-
-        if (parsedArgs.mHiddenApiAccessLogSampleRate != -1
-                || parsedArgs.mHiddenApiAccessStatslogSampleRate != -1) {
-            return handleHiddenApiAccessLogSampleRate(zygoteServer,
-                    parsedArgs.mHiddenApiAccessLogSampleRate,
-                    parsedArgs.mHiddenApiAccessStatslogSampleRate);
-        }
-
-        if (parsedArgs.mPermittedCapabilities != 0 || parsedArgs.mEffectiveCapabilities != 0) {
-            throw new ZygoteSecurityException("Client may not specify capabilities: "
-                    + "permitted=0x" + Long.toHexString(parsedArgs.mPermittedCapabilities)
-                    + ", effective=0x" + Long.toHexString(parsedArgs.mEffectiveCapabilities));
-        }
-
-        Zygote.applyUidSecurityPolicy(parsedArgs, peer);
-        Zygote.applyInvokeWithSecurityPolicy(parsedArgs, peer);
-
-        Zygote.applyDebuggerSystemProperty(parsedArgs);
-        Zygote.applyInvokeWithSystemProperty(parsedArgs);
-
-        int[][] rlimits = null;
-
-        if (parsedArgs.mRLimits != null) {
-            rlimits = parsedArgs.mRLimits.toArray(Zygote.INT_ARRAY_2D);
-        }
-
-        int[] fdsToIgnore = null;
-
-        if (parsedArgs.mInvokeWith != null) {
-            try {
-                FileDescriptor[] pipeFds = Os.pipe2(O_CLOEXEC);
-                childPipeFd = pipeFds[1];
-                serverPipeFd = pipeFds[0];
-                Os.fcntlInt(childPipeFd, F_SETFD, 0);
-                fdsToIgnore = new int[]{childPipeFd.getInt$(), serverPipeFd.getInt$()};
-            } catch (ErrnoException errnoEx) {
-                throw new IllegalStateException("Unable to set up pipe for invoke-with", errnoEx);
-            }
-        }
-
-        /*
-         * In order to avoid leaking descriptors to the Zygote child,
-         * the native code must close the two Zygote socket descriptors
-         * in the child process before it switches from Zygote-root to
-         * the UID and privileges of the application being launched.
-         *
-         * In order to avoid "bad file descriptor" errors when the
-         * two LocalSocket objects are closed, the Posix file
-         * descriptors are released via a dup2() call which closes
-         * the socket and substitutes an open descriptor to /dev/null.
-         */
-
-        int [] fdsToClose = { -1, -1 };
-
-        FileDescriptor fd = mSocket.getFileDescriptor();
-
-        if (fd != null) {
-            fdsToClose[0] = fd.getInt$();
-        }
-
-        fd = zygoteServer.getZygoteSocketFileDescriptor();
-
-        if (fd != null) {
-            fdsToClose[1] = fd.getInt$();
-        }
-
-        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
-                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
-                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
-                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
-                parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
-                parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
-
-        try {
-            if (pid == 0) {
-                // in child
-                zygoteServer.setForkChild();
-
-                zygoteServer.closeServerSocket();
-                IoUtils.closeQuietly(serverPipeFd);
-                serverPipeFd = null;
-
-                return handleChildProc(parsedArgs, childPipeFd, parsedArgs.mStartChildZygote);
-            } else {
-                // In the parent. A pid < 0 indicates a failure and will be handled in
-                // handleParentProc.
-                IoUtils.closeQuietly(childPipeFd);
-                childPipeFd = null;
-                handleParentProc(pid, serverPipeFd);
-                return null;
-            }
-        } finally {
-            IoUtils.closeQuietly(childPipeFd);
-            IoUtils.closeQuietly(serverPipeFd);
-        }
+        throw new AssertionError("Shouldn't get here");
     }
 
     private void handleAbiListQuery() {
@@ -557,7 +590,7 @@
 
                     if (res > 0) {
                         if ((fds[0].revents & POLLIN) != 0) {
-                            // Only read one byte, so as not to block.
+                            // Only read one byte, so as not to block. Really needed?
                             int readBytes = android.system.Os.read(pipeFd, data, dataIndex, 1);
                             if (readBytes < 0) {
                                 throw new RuntimeException("Some error");
diff --git a/core/java/com/android/internal/os/ZygoteConnectionConstants.java b/core/java/com/android/internal/os/ZygoteConnectionConstants.java
index 506e39f..0c1cd6d 100644
--- a/core/java/com/android/internal/os/ZygoteConnectionConstants.java
+++ b/core/java/com/android/internal/os/ZygoteConnectionConstants.java
@@ -31,9 +31,6 @@
      */
     public static final int CONNECTION_TIMEOUT_MILLIS = 1000;
 
-    /** max number of arguments that a connection can specify */
-    public static final int MAX_ZYGOTE_ARGC = 1024;
-
     /**
      * Wait time for a wrapped app to report back its pid.
      *
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index ef1c50f..fe87b64 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -65,6 +65,7 @@
 import libcore.io.IoUtils;
 
 import java.io.BufferedReader;
+import java.io.EOFException;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -779,7 +780,13 @@
         int pid;
 
         try {
-            parsedArgs = new ZygoteArguments(args);
+            ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
+            try {
+                parsedArgs = ZygoteArguments.getInstance(commandBuffer);
+            } catch (EOFException e) {
+                throw new AssertionError("Unexpected argument error for forking system server", e);
+            }
+            commandBuffer.close();
             Zygote.applyDebuggerSystemProperty(parsedArgs);
             Zygote.applyInvokeWithSystemProperty(parsedArgs);
 
@@ -858,7 +865,7 @@
      * into new processes are required to either set the priority to the default value or terminate
      * before executing any non-system code.  The native side of this occurs in SpecializeCommon,
      * while the Java Language priority is changed in ZygoteInit.handleSystemServerProcess,
-     * ZygoteConnection.handleChildProc, and Zygote.usapMain.
+     * ZygoteConnection.handleChildProc, and Zygote.childMain.
      *
      * @param argv  Command line arguments used to specify the Zygote's configuration.
      */
diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java
index 585ddf6..f71b314 100644
--- a/core/java/com/android/internal/os/ZygoteServer.java
+++ b/core/java/com/android/internal/os/ZygoteServer.java
@@ -337,7 +337,7 @@
      * @param sessionSocketRawFDs  Anonymous session sockets that are currently open
      * @return In the Zygote process this function will always return null; in unspecialized app
      *         processes this function will return a Runnable object representing the new
-     *         application that is passed up from usapMain.
+     *         application that is passed up from childMain (the usap's main wait loop).
      */
 
     Runnable fillUsapPool(int[] sessionSocketRawFDs, boolean isPriorityRefill) {
@@ -420,6 +420,7 @@
      * Runs the zygote process's select loop. Accepts new connections as
      * they happen, and reads commands from connections one spawn-request's
      * worth at a time.
+     * @param abiList list of ABIs supported by this zygote.
      */
     Runnable runSelectLoop(String abiList) {
         ArrayList<FileDescriptor> socketFDs = new ArrayList<>();
@@ -537,22 +538,23 @@
 
                     if (pollIndex == 0) {
                         // Zygote server socket
-
                         ZygoteConnection newPeer = acceptCommandPeer(abiList);
                         peers.add(newPeer);
                         socketFDs.add(newPeer.getFileDescriptor());
-
                     } else if (pollIndex < usapPoolEventFDIndex) {
                         // Session socket accepted from the Zygote server socket
 
                         try {
                             ZygoteConnection connection = peers.get(pollIndex);
-                            final Runnable command = connection.processOneCommand(this);
+                            boolean multipleForksOK = !isUsapPoolEnabled()
+                                    && ZygoteHooks.indefiniteThreadSuspensionOK();
+                            final Runnable command =
+                                    connection.processCommand(this, multipleForksOK);
 
                             // TODO (chriswailes): Is this extra check necessary?
                             if (mIsForkChild) {
                                 // We're in the child. We should always have a command to run at
-                                // this stage if processOneCommand hasn't called "exec".
+                                // this stage if processCommand hasn't called "exec".
                                 if (command == null) {
                                     throw new IllegalStateException("command == null");
                                 }
@@ -565,7 +567,7 @@
                                 }
 
                                 // We don't know whether the remote side of the socket was closed or
-                                // not until we attempt to read from it from processOneCommand. This
+                                // not until we attempt to read from it from processCommand. This
                                 // shows up as a regular POLLIN event in our regular processing
                                 // loop.
                                 if (connection.isClosedByPeer()) {
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index 2a73dac..47e696a 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -93,5 +93,5 @@
     void notifyBarringInfoChanged(int slotIndex, int subId, in BarringInfo barringInfo);
     void notifyPhysicalChannelConfigForSubscriber(in int subId,
             in List<PhysicalChannelConfig> configs);
-    void notifyDataEnabled(boolean enabled, int reason);
+    void notifyDataEnabled(in int phoneId, int subId, boolean enabled, int reason);
 }
diff --git a/core/java/com/android/internal/view/OWNERS b/core/java/com/android/internal/view/OWNERS
index 851d1f3..eb2478f 100644
--- a/core/java/com/android/internal/view/OWNERS
+++ b/core/java/com/android/internal/view/OWNERS
@@ -18,3 +18,7 @@
 per-file BaseIWIndow.java = file:/services/core/java/com/android/server/wm/OWNERS
 per-file RotationPolicy.java = file:/services/core/java/com/android/server/wm/OWNERS
 per-file WindowManagerPolicyThread.java = file:/services/core/java/com/android/server/wm/OWNERS
+
+# Scroll Capture
+per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
+per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/java/com/android/server/OWNERS b/core/java/com/android/server/OWNERS
new file mode 100644
index 0000000..12629254
--- /dev/null
+++ b/core/java/com/android/server/OWNERS
@@ -0,0 +1 @@
+per-file SystemConfig.java = toddke@google.com
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 7f9544c..e58ad79 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -67,11 +67,12 @@
         "libhwui",
         "liblog",
         "libminikin",
-        "libnativehelper",
         "libz",
         "libziparchive",
     ],
 
+    static_libs: ["libnativehelper_lazy"],
+
     export_include_dirs: [
         ".",
         "include",
@@ -205,6 +206,7 @@
                 "com_android_internal_os_KernelCpuUidBpfMapReader.cpp",
                 "com_android_internal_os_KernelSingleUidTimeReader.cpp",
                 "com_android_internal_os_Zygote.cpp",
+                "com_android_internal_os_ZygoteCommandBuffer.cpp",
                 "com_android_internal_os_ZygoteInit.cpp",
                 "hwbinder/EphemeralStorage.cpp",
                 "fd_utils.cpp",
@@ -284,12 +286,13 @@
                 "libstatspull",
             ],
             export_shared_lib_headers: [
-                // AndroidRuntime.h depends on nativehelper/jni.h
-                "libnativehelper",
-
                 // our headers include libnativewindow's public headers
                 "libnativewindow",
             ],
+            export_static_lib_headers: [
+                // AndroidRuntime.h depends on nativehelper/jni.h
+                "libnativehelper_lazy",
+            ],
             header_libs: [
                 "bionic_libc_platform_headers",
                 "dnsproxyd_protocol_headers",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 3198cb1..c01f741 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -193,6 +193,7 @@
 extern int register_com_android_internal_os_KernelCpuUidBpfMapReader(JNIEnv *env);
 extern int register_com_android_internal_os_KernelSingleUidTimeReader(JNIEnv *env);
 extern int register_com_android_internal_os_Zygote(JNIEnv *env);
+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_util_VirtualRefBasePtr(JNIEnv *env);
 
@@ -1524,6 +1525,7 @@
         REG_JNI(register_com_android_internal_net_NetworkUtilsInternal),
         REG_JNI(register_com_android_internal_os_ClassLoaderFactory),
         REG_JNI(register_com_android_internal_os_Zygote),
+        REG_JNI(register_com_android_internal_os_ZygoteCommandBuffer),
         REG_JNI(register_com_android_internal_os_ZygoteInit),
         REG_JNI(register_com_android_internal_util_VirtualRefBasePtr),
         REG_JNI(register_android_hardware_Camera),
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 35d1d7b..19c6a62 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -42,6 +42,9 @@
 per-file android_os_HwRemoteBinder* = file:platform/system/libhwbinder:/OWNERS
 per-file EphemeralStorage* = file:platform/system/libhwbinder:/OWNERS
 
+# Sensor
+per-file android_hardware_SensorManager* = arthuri@google.com, bduddie@google.com, stange@google.com
+
 per-file *Zygote* = file:/ZYGOTE_OWNERS
 per-file Android.bp = file:platform/build/soong:/OWNERS
 per-file android_animation_* = file:/core/java/android/animation/OWNERS
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 903ecae..bcd203b 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -17,6 +17,8 @@
 #define LOG_TAG "Zygote"
 #define ATRACE_TAG ATRACE_TAG_DALVIK
 
+#include "com_android_internal_os_Zygote.h"
+
 #include <async_safe/log.h>
 
 // sys/mount.h has to come before linux/fs.h due to redefinition of MS_RDONLY, MS_BIND, etc
@@ -91,19 +93,6 @@
 
 #include "nativebridge/native_bridge.h"
 
-/* Functions in the callchain during the fork shall not be protected with
-   Armv8.3-A Pointer Authentication, otherwise child will not be able to return. */
-#ifdef __ARM_FEATURE_PAC_DEFAULT
-#ifdef __ARM_FEATURE_BTI_DEFAULT
-#define NO_PAC_FUNC __attribute__((target("branch-protection=bti")))
-#else
-#define NO_PAC_FUNC __attribute__((target("branch-protection=none")))
-#endif /* __ARM_FEATURE_BTI_DEFAULT */
-#else /* !__ARM_FEATURE_PAC_DEFAULT */
-#define NO_PAC_FUNC
-#endif /* __ARM_FEATURE_PAC_DEFAULT */
-
-
 namespace {
 
 // TODO (chriswailes): Add a function to initialize native Zygote data.
@@ -118,8 +107,7 @@
 using android::base::WriteStringToFile;
 using android::base::GetBoolProperty;
 
-#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \
-                              append(StringPrintf(__VA_ARGS__))
+using android::zygote::ZygoteFailure;
 
 // This type is duplicated in fd_utils.h
 typedef const std::function<void(std::string)>& fail_fn_t;
@@ -215,7 +203,7 @@
   static constexpr EntryStorage INVALID_ENTRY_VALUE = {-1, -1};
 
   std::atomic<EntryStorage> mStorage;
-  static_assert(decltype(mStorage)::is_always_lock_free);
+  static_assert(decltype(mStorage)::is_always_lock_free);  // Accessed from signal handler.
 
  public:
   constexpr UsapTableEntry() : mStorage(INVALID_ENTRY_VALUE) {}
@@ -356,6 +344,7 @@
     GWP_ASAN_LEVEL_NEVER = 0 << 21,
     GWP_ASAN_LEVEL_LOTTERY = 1 << 21,
     GWP_ASAN_LEVEL_ALWAYS = 2 << 21,
+    NATIVE_HEAP_ZERO_INIT = 1 << 23,
 };
 
 enum UnsolicitedZygoteMessageTypes : uint32_t {
@@ -942,36 +931,6 @@
 }
 
 /**
- * A failure function used to report fatal errors to the managed runtime.  This
- * function is often curried with the process name information and then passed
- * to called functions.
- *
- * @param env  Managed runtime environment
- * @param process_name  A native representation of the process name
- * @param managed_process_name  A managed representation of the process name
- * @param msg  The error message to be reported
- */
-[[noreturn]]
-static void ZygoteFailure(JNIEnv* env,
-                          const char* process_name,
-                          jstring managed_process_name,
-                          const std::string& msg) {
-  std::unique_ptr<ScopedUtfChars> scoped_managed_process_name_ptr = nullptr;
-  if (managed_process_name != nullptr) {
-    scoped_managed_process_name_ptr.reset(new ScopedUtfChars(env, managed_process_name));
-    if (scoped_managed_process_name_ptr->c_str() != nullptr) {
-      process_name = scoped_managed_process_name_ptr->c_str();
-    }
-  }
-
-  const std::string& error_msg =
-      (process_name == nullptr) ? msg : StringPrintf("(%s) %s", process_name, msg.c_str());
-
-  env->FatalError(error_msg.c_str());
-  __builtin_unreachable();
-}
-
-/**
  * A helper method for converting managed strings to native strings.  A fatal
  * error is generated if a problem is encountered in extracting a non-null
  * string.
@@ -1098,86 +1057,6 @@
 #endif
 }
 
-// Utility routine to fork a process from the zygote.
-NO_PAC_FUNC
-static pid_t ForkCommon(JNIEnv* env, bool is_system_server,
-                        const std::vector<int>& fds_to_close,
-                        const std::vector<int>& fds_to_ignore,
-                        bool is_priority_fork) {
-  SetSignalHandlers();
-
-  // Curry a failure function.
-  auto fail_fn = std::bind(ZygoteFailure, env, is_system_server ? "system_server" : "zygote",
-                           nullptr, _1);
-
-  // Temporarily block SIGCHLD during forks. The SIGCHLD handler might
-  // log, which would result in the logging FDs we close being reopened.
-  // This would cause failures because the FDs are not allowlisted.
-  //
-  // Note that the zygote process is single threaded at this point.
-  BlockSignal(SIGCHLD, fail_fn);
-
-  // Close any logging related FDs before we start evaluating the list of
-  // file descriptors.
-  __android_log_close();
-  AStatsSocket_close();
-
-  // If this is the first fork for this zygote, create the open FD table.  If
-  // it isn't, we just need to check whether the list of open files has changed
-  // (and it shouldn't in the normal case).
-  if (gOpenFdTable == nullptr) {
-    gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn);
-  } else {
-    gOpenFdTable->Restat(fds_to_ignore, fail_fn);
-  }
-
-  android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level();
-
-  // Purge unused native memory in an attempt to reduce the amount of false
-  // sharing with the child process.  By reducing the size of the libc_malloc
-  // region shared with the child process we reduce the number of pages that
-  // transition to the private-dirty state when malloc adjusts the meta-data
-  // on each of the pages it is managing after the fork.
-  mallopt(M_PURGE, 0);
-
-  pid_t pid = fork();
-
-  if (pid == 0) {
-    if (is_priority_fork) {
-      setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
-    } else {
-      setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);
-    }
-
-    // The child process.
-    PAuthKeyChange(env);
-    PreApplicationInit();
-
-    // Clean up any descriptors which must be closed immediately
-    DetachDescriptors(env, fds_to_close, fail_fn);
-
-    // Invalidate the entries in the USAP table.
-    ClearUsapTable();
-
-    // Re-open all remaining open file descriptors so that they aren't shared
-    // with the zygote across a fork.
-    gOpenFdTable->ReopenOrDetach(fail_fn);
-
-    // Turn fdsan back on.
-    android_fdsan_set_error_level(fdsan_error_level);
-
-    // Reset the fd to the unsolicited zygote socket
-    gSystemServerSocketFd = -1;
-  } else {
-    ALOGD("Forked child process %d", pid);
-  }
-
-  // We blocked SIGCHLD prior to a fork, we unblock it here.
-  UnblockSignal(SIGCHLD, fail_fn);
-
-  return pid;
-}
-
 // Create an app data directory over tmpfs overlayed CE / DE storage, and bind mount it
 // from the actual app data directory in data mirror.
 static bool createAndMountAppData(std::string_view package_name,
@@ -1804,15 +1683,20 @@
   }
   mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, heap_tagging_level);
 
+  // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART runtime.
+  runtime_flags &= ~RuntimeFlags::MEMORY_TAG_LEVEL_MASK;
+
   // Avoid heap zero initialization for applications without MTE. Zero init may
   // cause app compat problems, use more memory, or reduce performance. While it
   // would be nice to have them for apps, we will have to wait until they are
   // proven out, have more efficient hardware, and/or apply them only to new
   // applications.
-  mallopt(M_BIONIC_ZERO_INIT, 0);
+  if (!(runtime_flags & RuntimeFlags::NATIVE_HEAP_ZERO_INIT)) {
+    mallopt(M_BIONIC_ZERO_INIT, 0);
+  }
 
   // Now that we've used the flag, clear it so that we don't pass unknown flags to the ART runtime.
-  runtime_flags &= ~RuntimeFlags::MEMORY_TAG_LEVEL_MASK;
+  runtime_flags &= ~RuntimeFlags::NATIVE_HEAP_ZERO_INIT;
 
   bool forceEnableGwpAsan = false;
   switch (runtime_flags & RuntimeFlags::GWP_ASAN_LEVEL_MASK) {
@@ -1993,9 +1877,10 @@
   static int sUsapTableInsertIndex = 0;
 
   int search_index = sUsapTableInsertIndex;
-
   do {
     if (gUsapTable[search_index].SetIfInvalid(usap_pid, read_pipe_fd)) {
+      ++gUsapPoolCount;
+
       // Start our next search right after where we finished this one.
       sUsapTableInsertIndex = (search_index + 1) % gUsapTable.size();
 
@@ -2013,7 +1898,7 @@
 /**
  * Invalidates the entry in the USAPTable corresponding to the provided
  * process ID if it is present.  If an entry was removed the USAP pool
- * count is decremented.
+ * count is decremented. May be called from signal handler.
  *
  * @param usap_pid  Process ID of the USAP entry to invalidate
  * @return True if an entry was invalidated; false otherwise
@@ -2089,6 +1974,121 @@
 
 namespace android {
 
+/**
+ * A failure function used to report fatal errors to the managed runtime.  This
+ * function is often curried with the process name information and then passed
+ * to called functions.
+ *
+ * @param env  Managed runtime environment
+ * @param process_name  A native representation of the process name
+ * @param managed_process_name  A managed representation of the process name
+ * @param msg  The error message to be reported
+ */
+[[noreturn]]
+void zygote::ZygoteFailure(JNIEnv* env,
+                           const char* process_name,
+                           jstring managed_process_name,
+                           const std::string& msg) {
+  std::unique_ptr<ScopedUtfChars> scoped_managed_process_name_ptr = nullptr;
+  if (managed_process_name != nullptr) {
+    scoped_managed_process_name_ptr.reset(new ScopedUtfChars(env, managed_process_name));
+    if (scoped_managed_process_name_ptr->c_str() != nullptr) {
+      process_name = scoped_managed_process_name_ptr->c_str();
+    }
+  }
+
+  const std::string& error_msg =
+      (process_name == nullptr || process_name[0] == '\0') ?
+      msg : StringPrintf("(%s) %s", process_name, msg.c_str());
+
+  env->FatalError(error_msg.c_str());
+  __builtin_unreachable();
+}
+
+// Utility routine to fork a process from the zygote.
+NO_PAC_FUNC
+pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
+                         const std::vector<int>& fds_to_close,
+                         const std::vector<int>& fds_to_ignore,
+                         bool is_priority_fork,
+                         bool purge) {
+  SetSignalHandlers();
+
+  // Curry a failure function.
+  auto fail_fn = std::bind(zygote::ZygoteFailure, env,
+                           is_system_server ? "system_server" : "zygote",
+                           nullptr, _1);
+
+  // Temporarily block SIGCHLD during forks. The SIGCHLD handler might
+  // log, which would result in the logging FDs we close being reopened.
+  // This would cause failures because the FDs are not allowlisted.
+  //
+  // Note that the zygote process is single threaded at this point.
+  BlockSignal(SIGCHLD, fail_fn);
+
+  // Close any logging related FDs before we start evaluating the list of
+  // file descriptors.
+  __android_log_close();
+  AStatsSocket_close();
+
+  // If this is the first fork for this zygote, create the open FD table.  If
+  // it isn't, we just need to check whether the list of open files has changed
+  // (and it shouldn't in the normal case).
+  if (gOpenFdTable == nullptr) {
+    gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore, fail_fn);
+  } else {
+    gOpenFdTable->Restat(fds_to_ignore, fail_fn);
+  }
+
+  android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level();
+
+  if (purge) {
+    // Purge unused native memory in an attempt to reduce the amount of false
+    // sharing with the child process.  By reducing the size of the libc_malloc
+    // region shared with the child process we reduce the number of pages that
+    // transition to the private-dirty state when malloc adjusts the meta-data
+    // on each of the pages it is managing after the fork.
+    mallopt(M_PURGE, 0);
+  }
+
+  pid_t pid = fork();
+
+  if (pid == 0) {
+    if (is_priority_fork) {
+      setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MAX);
+    } else {
+      setpriority(PRIO_PROCESS, 0, PROCESS_PRIORITY_MIN);
+    }
+
+    // The child process.
+    PAuthKeyChange(env);
+    PreApplicationInit();
+
+    // Clean up any descriptors which must be closed immediately
+    DetachDescriptors(env, fds_to_close, fail_fn);
+
+    // Invalidate the entries in the USAP table.
+    ClearUsapTable();
+
+    // Re-open all remaining open file descriptors so that they aren't shared
+    // with the zygote across a fork.
+    gOpenFdTable->ReopenOrDetach(fail_fn);
+
+    // Turn fdsan back on.
+    android_fdsan_set_error_level(fdsan_error_level);
+
+    // Reset the fd to the unsolicited zygote socket
+    gSystemServerSocketFd = -1;
+  } else {
+    ALOGD("Forked child process %d", pid);
+  }
+
+  // We blocked SIGCHLD prior to a fork, we unblock it here.
+  UnblockSignal(SIGCHLD, fail_fn);
+
+  return pid;
+}
+
 static void com_android_internal_os_Zygote_nativePreApplicationInit(JNIEnv*, jclass) {
   PreApplicationInit();
 }
@@ -2105,7 +2105,8 @@
     jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);
 
     if (UNLIKELY(managed_fds_to_close == nullptr)) {
-      ZygoteFailure(env, "zygote", nice_name, "Zygote received a null fds_to_close vector.");
+      zygote::ZygoteFailure(env, "zygote", nice_name,
+                            "Zygote received a null fds_to_close vector.");
     }
 
     std::vector<int> fds_to_close =
@@ -2131,7 +2132,7 @@
         fds_to_ignore.push_back(gSystemServerSocketFd);
     }
 
-    pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
+    pid_t pid = zygote::ForkCommon(env, false, fds_to_close, fds_to_ignore, true);
 
     if (pid == 0) {
       SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
@@ -2166,10 +2167,10 @@
       fds_to_ignore.push_back(gSystemServerSocketFd);
   }
 
-  pid_t pid = ForkCommon(env, true,
-                         fds_to_close,
-                         fds_to_ignore,
-                         true);
+  pid_t pid = zygote::ForkCommon(env, true,
+                                 fds_to_close,
+                                 fds_to_ignore,
+                                 true);
   if (pid == 0) {
       // System server prcoess does not need data isolation so no need to
       // know pkg_data_info_list.
@@ -2209,58 +2210,74 @@
  * ensuring proper file descriptor hygiene.
  *
  * @param env  Managed runtime environment
- * @param read_pipe_fd  The read FD for the USAP reporting pipe.  Manually closed by blastlas
- * in managed code.
+ * @param read_pipe_fd  The read FD for the USAP reporting pipe.  Manually closed by the child
+ * in managed code. -1 indicates none.
  * @param write_pipe_fd  The write FD for the USAP reporting pipe.  Manually closed by the
- * zygote in managed code.
+ * zygote in managed code. -1 indicates none.
  * @param managed_session_socket_fds  A list of anonymous session sockets that must be ignored by
  * the FD hygiene code and automatically "closed" in the new USAP.
+ * @param args_known Arguments for specialization are available; no need to read from a socket
  * @param is_priority_fork  Controls the nice level assigned to the newly created process
- * @return
+ * @return child pid in the parent, 0 in the child
  */
 NO_PAC_FUNC
-static jint com_android_internal_os_Zygote_nativeForkUsap(JNIEnv* env,
-                                                          jclass,
-                                                          jint read_pipe_fd,
-                                                          jint write_pipe_fd,
-                                                          jintArray managed_session_socket_fds,
-                                                          jboolean is_priority_fork) {
-  std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()),
-                   fds_to_ignore(fds_to_close);
-
+static jint com_android_internal_os_Zygote_nativeForkApp(JNIEnv* env,
+                                                         jclass,
+                                                         jint read_pipe_fd,
+                                                         jint write_pipe_fd,
+                                                         jintArray managed_session_socket_fds,
+                                                         jboolean args_known,
+                                                         jboolean is_priority_fork) {
   std::vector<int> session_socket_fds =
       ExtractJIntArray(env, "USAP", nullptr, managed_session_socket_fds)
           .value_or(std::vector<int>());
+  return zygote::forkApp(env, read_pipe_fd, write_pipe_fd, session_socket_fds,
+                            args_known == JNI_TRUE, is_priority_fork == JNI_TRUE, true);
+}
 
-  // The USAP Pool Event FD is created during the initialization of the
-  // USAP pool and should always be valid here.
+NO_PAC_FUNC
+int zygote::forkApp(JNIEnv* env,
+                    int read_pipe_fd,
+                    int write_pipe_fd,
+                    const std::vector<int>& session_socket_fds,
+                    bool args_known,
+                    bool is_priority_fork,
+                    bool purge) {
+
+  std::vector<int> fds_to_close(MakeUsapPipeReadFDVector()),
+                   fds_to_ignore(fds_to_close);
 
   fds_to_close.push_back(gZygoteSocketFD);
-  fds_to_close.push_back(gUsapPoolEventFD);
-  fds_to_close.insert(fds_to_close.end(), session_socket_fds.begin(), session_socket_fds.end());
   if (gSystemServerSocketFd != -1) {
       fds_to_close.push_back(gSystemServerSocketFd);
   }
+  if (args_known) {
+      fds_to_close.push_back(gUsapPoolSocketFD);
+  }
+  fds_to_close.insert(fds_to_close.end(), session_socket_fds.begin(), session_socket_fds.end());
 
-  fds_to_ignore.push_back(gZygoteSocketFD);
   fds_to_ignore.push_back(gUsapPoolSocketFD);
-  fds_to_ignore.push_back(gUsapPoolEventFD);
-  fds_to_ignore.push_back(read_pipe_fd);
-  fds_to_ignore.push_back(write_pipe_fd);
+  fds_to_ignore.push_back(gZygoteSocketFD);
+  if (read_pipe_fd != -1) {
+      fds_to_ignore.push_back(read_pipe_fd);
+  }
+  if (write_pipe_fd != -1) {
+      fds_to_ignore.push_back(write_pipe_fd);
+  }
   fds_to_ignore.insert(fds_to_ignore.end(), session_socket_fds.begin(), session_socket_fds.end());
+
+  if (gUsapPoolEventFD != -1) {
+      fds_to_close.push_back(gUsapPoolEventFD);
+      fds_to_ignore.push_back(gUsapPoolEventFD);
+  }
   if (gSystemServerSocketFd != -1) {
+      if (args_known) {
+          fds_to_close.push_back(gSystemServerSocketFd);
+      }
       fds_to_ignore.push_back(gSystemServerSocketFd);
   }
-
-  pid_t usap_pid = ForkCommon(env, /* is_system_server= */ false, fds_to_close, fds_to_ignore,
-                              is_priority_fork == JNI_TRUE);
-
-  if (usap_pid != 0) {
-    ++gUsapPoolCount;
-    AddUsapTableEntry(usap_pid, read_pipe_fd);
-  }
-
-  return usap_pid;
+  return zygote::ForkCommon(env, /* is_system_server= */ false, fds_to_close,
+                            fds_to_ignore, is_priority_fork == JNI_TRUE, purge);
 }
 
 static void com_android_internal_os_Zygote_nativeAllowFileAcrossFork(
@@ -2374,7 +2391,7 @@
    */
 
   if (!SetTaskProfiles(0, {})) {
-    ZygoteFailure(env, "zygote", nullptr, "Zygote SetTaskProfiles failed");
+    zygote::ZygoteFailure(env, "zygote", nullptr, "Zygote SetTaskProfiles failed");
   }
 }
 
@@ -2392,15 +2409,21 @@
   return managed_usap_fds;
 }
 
+/*
+ * Add the given pid and file descriptor to the Usap table. CriticalNative method.
+ */
+static void com_android_internal_os_Zygote_nativeAddUsapTableEntry(jint pid, jint read_pipe_fd) {
+  AddUsapTableEntry(pid, read_pipe_fd);
+}
+
 /**
- * A JNI wrapper around RemoveUsapTableEntry.
+ * A JNI wrapper around RemoveUsapTableEntry. CriticalNative method.
  *
  * @param env  Managed runtime environment
  * @param usap_pid  Process ID of the USAP entry to invalidate
  * @return  True if an entry was invalidated; false otherwise.
  */
-static jboolean com_android_internal_os_Zygote_nativeRemoveUsapTableEntry(JNIEnv* env, jclass,
-                                                                          jint usap_pid) {
+static jboolean com_android_internal_os_Zygote_nativeRemoveUsapTableEntry(jint usap_pid) {
   return RemoveUsapTableEntry(usap_pid);
 }
 
@@ -2415,7 +2438,8 @@
 static jint com_android_internal_os_Zygote_nativeGetUsapPoolEventFD(JNIEnv* env, jclass) {
   if (gUsapPoolEventFD == -1) {
     if ((gUsapPoolEventFD = eventfd(0, 0)) == -1) {
-      ZygoteFailure(env, "zygote", nullptr, StringPrintf("Unable to create eventfd: %s", strerror(errno)));
+      zygote::ZygoteFailure(env, "zygote", nullptr,
+                            StringPrintf("Unable to create eventfd: %s", strerror(errno)));
     }
   }
 
@@ -2458,12 +2482,12 @@
 }
 
 static void com_android_internal_os_Zygote_nativeBlockSigTerm(JNIEnv* env, jclass) {
-  auto fail_fn = std::bind(ZygoteFailure, env, "usap", nullptr, _1);
+  auto fail_fn = std::bind(zygote::ZygoteFailure, env, "usap", nullptr, _1);
   BlockSignal(SIGTERM, fail_fn);
 }
 
 static void com_android_internal_os_Zygote_nativeUnblockSigTerm(JNIEnv* env, jclass) {
-  auto fail_fn = std::bind(ZygoteFailure, env, "usap", nullptr, _1);
+  auto fail_fn = std::bind(zygote::ZygoteFailure, env, "usap", nullptr, _1);
   UnblockSignal(SIGTERM, fail_fn);
 }
 
@@ -2569,7 +2593,10 @@
          (void*)com_android_internal_os_Zygote_nativePreApplicationInit},
         {"nativeInstallSeccompUidGidFilter", "(II)V",
          (void*)com_android_internal_os_Zygote_nativeInstallSeccompUidGidFilter},
-        {"nativeForkUsap", "(II[IZ)I", (void*)com_android_internal_os_Zygote_nativeForkUsap},
+        {"nativeForkApp", "(II[IZZ)I", (void*)com_android_internal_os_Zygote_nativeForkApp},
+        // @CriticalNative
+        {"nativeAddUsapTableEntry", "(II)V",
+         (void*)com_android_internal_os_Zygote_nativeAddUsapTableEntry},
         {"nativeSpecializeAppProcess",
          "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/"
          "String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)V",
@@ -2578,6 +2605,10 @@
          (void*)com_android_internal_os_Zygote_nativeInitNativeState},
         {"nativeGetUsapPipeFDs", "()[I",
          (void*)com_android_internal_os_Zygote_nativeGetUsapPipeFDs},
+        // @CriticalNative
+        {"nativeAddUsapTableEntry", "(II)V",
+         (void*)com_android_internal_os_Zygote_nativeAddUsapTableEntry},
+        // @CriticalNative
         {"nativeRemoveUsapTableEntry", "(I)Z",
          (void*)com_android_internal_os_Zygote_nativeRemoveUsapTableEntry},
         {"nativeGetUsapPoolEventFD", "()I",
diff --git a/core/jni/com_android_internal_os_Zygote.h b/core/jni/com_android_internal_os_Zygote.h
new file mode 100644
index 0000000..d2da914
--- /dev/null
+++ b/core/jni/com_android_internal_os_Zygote.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef _COM_ANDROID_INTERNAL_OS_ZYGOTE_H
+#define _COM_ANDROID_INTERNAL_OS_ZYGOTE_H
+
+#define LOG_TAG "Zygote"
+#define ATRACE_TAG ATRACE_TAG_DALVIK
+
+/* Functions in the callchain during the fork shall not be protected with
+   Armv8.3-A Pointer Authentication, otherwise child will not be able to return. */
+#ifdef __ARM_FEATURE_PAC_DEFAULT
+#ifdef __ARM_FEATURE_BTI_DEFAULT
+#define NO_PAC_FUNC __attribute__((target("branch-protection=bti")))
+#else
+#define NO_PAC_FUNC __attribute__((target("branch-protection=none")))
+#endif /* __ARM_FEATURE_BTI_DEFAULT */
+#else /* !__ARM_FEATURE_PAC_DEFAULT */
+#define NO_PAC_FUNC
+#endif /* __ARM_FEATURE_PAC_DEFAULT */
+
+#include <jni.h>
+#include <vector>
+#include <android-base/stringprintf.h>
+
+#define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \
+                              append(StringPrintf(__VA_ARGS__))
+
+namespace android {
+namespace zygote {
+
+NO_PAC_FUNC
+pid_t ForkCommon(JNIEnv* env,bool is_system_server,
+                 const std::vector<int>& fds_to_close,
+                 const std::vector<int>& fds_to_ignore,
+                 bool is_priority_fork,
+                 bool purge = true);
+
+/**
+ * Fork a process. The pipe fds are used for usap communication, or -1 in
+ * other cases. Session_socket_fds are FDs used for zygote communication that must be dealt
+ * with hygienically, but are not otherwise used here. Args_known indicates that the process
+ * will be immediately specialized with arguments that are already known, so no usap
+ * communication is required. Is_priority_fork should be true if this is on the app startup
+ * critical path. Purge specifies that unused pages should be purged before the fork.
+ */
+NO_PAC_FUNC
+int forkApp(JNIEnv* env,
+            int read_pipe_fd,
+            int write_pipe_fd,
+            const std::vector<int>& session_socket_fds,
+            bool args_known,
+            bool is_priority_fork,
+            bool purge);
+
+[[noreturn]]
+void ZygoteFailure(JNIEnv* env,
+                   const char* process_name,
+                   jstring managed_process_name,
+                   const std::string& msg);
+
+}  // namespace zygote
+}  // namespace android
+
+#endif // _COM_ANDROID_INTERNAL_OS_ZYGOTE_
diff --git a/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
new file mode 100644
index 0000000..011e8f8
--- /dev/null
+++ b/core/jni/com_android_internal_os_ZygoteCommandBuffer.cpp
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "com_android_internal_os_Zygote.h"
+
+#include <algorithm>
+#include <android-base/logging.h>
+#include <async_safe/log.h>
+#include <cctype>
+#include <chrono>
+#include <core_jni_helpers.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <jni.h>
+#include <nativehelper/JNIHelp.h>
+#include <optional>
+#include <poll.h>
+#include <unistd.h>
+#include <utility>
+#include <utils/misc.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <vector>
+
+namespace android {
+
+using namespace std::placeholders;
+using android::base::StringPrintf;
+using android::zygote::ZygoteFailure;
+
+// WARNING: Knows a little about the wire protocol used to communicate with Zygote.
+// TODO: Fix error handling.
+
+constexpr size_t MAX_COMMAND_BYTES = 12200;
+constexpr size_t NICE_NAME_BYTES = 50;
+
+// A buffer optionally bundled with a file descriptor from which we can fill it.
+// Does not own the file descriptor; destroying a NativeCommandBuffer does not
+// close the descriptor.
+class NativeCommandBuffer {
+ public:
+  NativeCommandBuffer(int sourceFd): mEnd(0), mNext(0), mLinesLeft(0), mFd(sourceFd) {}
+
+  // Read mNext line from mFd, filling mBuffer from file descriptor, as needed.
+  // Return a pair of pointers pointing to the first character, and one past the
+  // mEnd of the line, i.e. at the newline. Returns nothing on failure.
+  template<class FailFn>
+  std::optional<std::pair<char*, char*>> readLine(FailFn fail_fn) {
+    char* result = mBuffer + mNext;
+    while (true) {
+      if (mNext == mEnd) {
+        if (mEnd == MAX_COMMAND_BYTES) {
+          return {};
+        }
+        if (mFd == -1) {
+          fail_fn("ZygoteCommandBuffer.readLine attempted to read from mFd -1");
+        }
+        ssize_t nread = TEMP_FAILURE_RETRY(read(mFd, mBuffer + mEnd, MAX_COMMAND_BYTES - mEnd));
+        if (nread <= 0) {
+          if (nread == 0) {
+            return {};
+          }
+          fail_fn(CREATE_ERROR("session socket read failed: %s", strerror(errno)));
+        } else if (nread == MAX_COMMAND_BYTES - mEnd) {
+          // This is pessimistic by one character, but close enough.
+          fail_fn("ZygoteCommandBuffer overflowed: command too long");
+        }
+        mEnd += nread;
+      }
+      // UTF-8 does not allow newline to occur as part of a multibyte character.
+      char* nl = static_cast<char *>(memchr(mBuffer + mNext, '\n', mEnd - mNext));
+      if (nl == nullptr) {
+        mNext = mEnd;
+      } else {
+        mNext = nl - mBuffer + 1;
+        if (--mLinesLeft < 0) {
+          fail_fn("ZygoteCommandBuffer.readLine attempted to read past mEnd of command");
+        }
+        return std::make_pair(result, nl);
+      }
+    }
+  }
+
+  void reset() {
+    mNext = 0;
+  }
+
+  // Make sure the current command is fully buffered, without reading past the current command.
+  template<class FailFn>
+  void readAllLines(FailFn fail_fn) {
+     while (mLinesLeft > 0) {
+       readLine(fail_fn);
+    }
+  }
+
+  void clear() {
+    // Don't bother to actually clear the buffer; it'll be unmapped in the child anyway.
+    reset();
+    mNiceName[0] = '\0';
+    mEnd = 0;
+  }
+
+  // Insert line into the mBuffer. Checks that the mBuffer is not associated with an mFd.
+  // Implicitly adds newline separators. Allows mBuffer contents to be explicitly set.
+  void insert(const char* line, size_t lineLen) {
+    DCHECK(mFd == -1);
+    CHECK(mEnd + lineLen < MAX_COMMAND_BYTES);
+    strncpy(mBuffer + mEnd, line, lineLen);
+    mBuffer[mEnd + lineLen] = '\n';
+    mEnd += lineLen + 1;
+  }
+
+  // Clear mBuffer, start reading new command, return the number of arguments, leaving mBuffer
+  // positioned at the beginning of first argument. Return 0 on EOF.
+  template<class FailFn>
+  int getCount(FailFn fail_fn) {
+    mLinesLeft = 1;
+    auto line = readLine(fail_fn);
+    if (!line.has_value()) {
+      return 0;
+    }
+    char* countString = line.value().first;  // Newline terminated.
+    long nArgs = atol(countString);
+    if (nArgs <= 0 || nArgs >= MAX_COMMAND_BYTES / 2) {
+      fail_fn(CREATE_ERROR("Unreasonable argument count %ld", nArgs));
+    }
+    mLinesLeft = nArgs;
+    return static_cast<int>(nArgs);
+  }
+
+  // Is the mBuffer a simple fork command?
+  // We disallow request to wrap the child process, child zygotes, anything that
+  // mentions capabilities or requests uid < minUid.
+  // We insist that --setuid and --setgid arguments are explicitly included and that the
+  // command starts with --runtime-args.
+  // Assumes we are positioned at the beginning of the command after the argument count,
+  // and leaves the position at some indeterminate position in the buffer.
+  // As a side effect, this sets mNiceName to a non-empty string, if possible.
+  template<class FailFn>
+  bool isSimpleForkCommand(int minUid, FailFn fail_fn) {
+    if (mLinesLeft <= 0 || mLinesLeft  >= MAX_COMMAND_BYTES / 2) {
+      return false;
+    }
+    static const char* RUNTIME_ARGS = "--runtime-args";
+    static const char* INVOKE_WITH = "--invoke-with";
+    static const char* CHILD_ZYGOTE = "--start-child-zygote";
+    static const char* SETUID = "--setuid=";
+    static const char* SETGID = "--setgid=";
+    static const char* CAPABILITIES = "--capabilities";
+    static const char* NICE_NAME = "--nice-name=";
+    static const size_t RA_LENGTH = strlen(RUNTIME_ARGS);
+    static const size_t IW_LENGTH = strlen(INVOKE_WITH);
+    static const size_t CZ_LENGTH = strlen(CHILD_ZYGOTE);
+    static const size_t SU_LENGTH = strlen(SETUID);
+    static const size_t SG_LENGTH = strlen(SETGID);
+    static const size_t CA_LENGTH = strlen(CAPABILITIES);
+    static const size_t NN_LENGTH = strlen(NICE_NAME);
+
+    bool saw_setuid = false, saw_setgid = false;
+    bool saw_runtime_args = false;
+
+    while (mLinesLeft > 0) {
+      auto read_result = readLine(fail_fn);
+      if (!read_result.has_value()) {
+        return false;
+      }
+      auto [arg_start, arg_end] = read_result.value();
+      if (arg_end - arg_start == RA_LENGTH
+          && strncmp(arg_start, RUNTIME_ARGS, RA_LENGTH) == 0) {
+        saw_runtime_args = true;
+        continue;
+      }
+      if (arg_end - arg_start >= NN_LENGTH
+          && strncmp(arg_start, NICE_NAME, NN_LENGTH) == 0) {
+        size_t name_len = arg_end - (arg_start + NN_LENGTH);
+        size_t copy_len = std::min(name_len, NICE_NAME_BYTES - 1);
+        memcpy(mNiceName, arg_start + NN_LENGTH, copy_len);
+        mNiceName[copy_len] = '\0';
+        continue;
+      }
+      if (arg_end - arg_start == IW_LENGTH
+          && strncmp(arg_start, INVOKE_WITH, IW_LENGTH) == 0) {
+        // This also removes the need for invoke-with security checks here.
+        return false;
+      }
+      if (arg_end - arg_start == CZ_LENGTH
+          && strncmp(arg_start, CHILD_ZYGOTE, CZ_LENGTH) == 0) {
+        return false;
+      }
+      if (arg_end - arg_start >= CA_LENGTH
+          && strncmp(arg_start, CAPABILITIES, CA_LENGTH) == 0) {
+        return false;
+      }
+      if (arg_end - arg_start >= SU_LENGTH
+          && strncmp(arg_start, SETUID, SU_LENGTH) == 0) {
+        int uid = digitsVal(arg_start + SU_LENGTH, arg_end);
+        if (uid < minUid) {
+          return false;
+        }
+        saw_setuid = true;
+        continue;
+      }
+      if (arg_end - arg_start >= SG_LENGTH
+          && strncmp(arg_start, SETGID, SG_LENGTH) == 0) {
+        int gid = digitsVal(arg_start + SG_LENGTH, arg_end);
+        if (gid == -1) {
+          return false;
+        }
+        saw_setgid = true;
+      }
+    }
+    return saw_runtime_args && saw_setuid && saw_setgid;
+  }
+
+  void setFd(int new_fd) {
+    mFd = new_fd;
+  }
+
+  int getFd() const {
+    return mFd;
+  }
+
+  const char* niceNameAddr() const {
+    return mNiceName;
+  }
+
+  // Debug only:
+  void logState() const {
+    ALOGD("mbuffer starts with %c%c, nice name is %s, "
+          "mEnd = %u, mNext = %u, mLinesLeft = %d, mFd = %d",
+          mBuffer[0], (mBuffer[1] == '\n' ? ' ' : mBuffer[1]),
+          niceNameAddr(),
+          static_cast<unsigned>(mEnd), static_cast<unsigned>(mNext),
+          static_cast<int>(mLinesLeft), mFd);
+  }
+
+ private:
+  // Picky version of atoi(). No sign or unexpected characters allowed. Return -1 on failure.
+  static int digitsVal(char* start, char* end) {
+    int result = 0;
+    if (end - start > 6) {
+      return -1;
+    }
+    for (char* dp = start; dp < end; ++dp) {
+      if (*dp < '0' || *dp > '9') {
+        ALOGW("Argument failed integer format check");
+        return -1;
+      }
+      result = 10 * result + (*dp - '0');
+    }
+    return result;
+  }
+
+  uint32_t mEnd;  // Index of first empty byte in the mBuffer.
+  uint32_t mNext;  // Index of first character past last line returned by readLine.
+  int32_t mLinesLeft;  // Lines in current command that haven't yet been read.
+  int mFd;  // Open file descriptor from which we can read more. -1 if none.
+  char mNiceName[NICE_NAME_BYTES];
+  char mBuffer[MAX_COMMAND_BYTES];
+};
+
+static_assert(sizeof(NativeCommandBuffer) < 3 * 4096);
+
+static int buffersAllocd(0);
+
+// Get a new NativeCommandBuffer. Can only be called once between freeNativeBuffer calls,
+// so that only one buffer exists at a time.
+jlong com_android_internal_os_ZygoteCommandBuffer_getNativeBuffer(JNIEnv* env, jclass, jint fd) {
+  CHECK(buffersAllocd == 0);
+  ++buffersAllocd;
+  // MMap explicitly to get it page aligned.
+  void *bufferMem = mmap(NULL, sizeof(NativeCommandBuffer), PROT_READ | PROT_WRITE,
+                         MAP_ANONYMOUS | MAP_PRIVATE | MAP_POPULATE, -1, 0);
+  // Currently we mmap and unmap one for every request handled by the Java code.
+  // That could be improved, but unclear it matters.
+  if (bufferMem == MAP_FAILED) {
+    ZygoteFailure(env, nullptr, nullptr, "Failed to map argument buffer");
+  }
+  return (jlong) new(bufferMem) NativeCommandBuffer(fd);
+}
+
+// Delete native command buffer.
+void com_android_internal_os_ZygoteCommandBuffer_freeNativeBuffer(JNIEnv* env, jclass,
+                                                                  jlong j_buffer) {
+  CHECK(buffersAllocd == 1);
+  NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer);
+  n_buffer->~NativeCommandBuffer();
+  if (munmap(n_buffer, sizeof(NativeCommandBuffer)) != 0) {
+    ZygoteFailure(env, nullptr, nullptr, "Failed to unmap argument buffer");
+  }
+  --buffersAllocd;
+}
+
+// Clear the buffer, read the line containing the count, and return the count.
+jint com_android_internal_os_ZygoteCommandBuffer_nativeGetCount(JNIEnv* env, jclass,
+                                                                jlong j_buffer) {
+  NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer);
+  auto fail_fn = std::bind(ZygoteFailure, env, nullptr, nullptr, _1);
+  return n_buffer->getCount(fail_fn);
+}
+
+// Explicitly insert a string as the last line (argument) of the buffer.
+void com_android_internal_os_ZygoteCommandBuffer_insert(JNIEnv* env, jclass, jlong j_buffer,
+                                                        jstring line) {
+  NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer);
+  size_t lineLen = static_cast<size_t>(env->GetStringUTFLength(line));
+  const char* cstring = env->GetStringUTFChars(line, NULL);
+  n_buffer->insert(cstring, lineLen);
+  env->ReleaseStringUTFChars(line, cstring);
+}
+
+// Read a line from the buffer, refilling as necessary.
+jstring com_android_internal_os_ZygoteCommandBuffer_nativeNextArg(JNIEnv* env, jclass,
+                                                                  jlong j_buffer) {
+  NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer);
+  auto fail_fn = std::bind(ZygoteFailure, env, n_buffer->niceNameAddr(), nullptr, _1);
+  auto line = n_buffer->readLine(fail_fn);
+  if (!line.has_value()) {
+    fail_fn("Incomplete zygote command");
+  }
+  auto [cresult, endp] = line.value();
+  // OK to temporarily clobber the buffer, since this is not thread safe, and we're modifying
+  // the buffer anyway.
+  *endp = '\0';
+  jstring result = env->NewStringUTF(cresult);
+  *endp = '\n';
+  return result;
+}
+
+// Read all lines from the current command into the buffer, and then reset the buffer, so
+// we will start reading again at the beginning of the command, starting with the argument
+// count. And we don't need access to the fd to do so.
+void com_android_internal_os_ZygoteCommandBuffer_nativeReadFullyAndReset(JNIEnv* env, jclass,
+                                                                         jlong j_buffer) {
+  NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer);
+  auto fail_fn = std::bind(ZygoteFailure, env, n_buffer->niceNameAddr(), nullptr, _1);
+  n_buffer->readAllLines(fail_fn);
+  n_buffer->reset();
+}
+
+// Fork a child as specified by the current command buffer, and refill the command
+// buffer from the given socket. So long as the result is another simple fork command,
+// repeat this process.
+// It must contain a fork command, which is currently restricted not to fork another
+// zygote or involve a wrapper process.
+// The initial buffer should be partially or entirely read; we read it fully and reset it.
+// When we return, the buffer contains the command we couldn't handle, and has been reset().
+// We return false in the parent when we see a command we didn't understand, and thus the
+// command in the buffer still needs to be executed.
+// We return true in each child.
+// We only process fork commands if the peer uid matches expected_uid.
+// For every fork command after the first, we check that the requested uid is at
+// least minUid.
+NO_PAC_FUNC
+jboolean com_android_internal_os_ZygoteCommandBuffer_nativeForkRepeatedly(
+            JNIEnv* env,
+            jclass,
+            jlong j_buffer,
+            jint zygote_socket_fd,
+            jint expected_uid,
+            jint minUid,
+            jstring managed_nice_name) {
+
+  NativeCommandBuffer* n_buffer = reinterpret_cast<NativeCommandBuffer*>(j_buffer);
+  int session_socket = n_buffer->getFd();
+  std::vector<int> session_socket_fds {session_socket};
+  auto fail_fn_1 = std::bind(ZygoteFailure, env, static_cast<const char*>(nullptr),
+                             static_cast<jstring>(managed_nice_name), _1);
+  // This binds to the nice name address; the actual names are updated by isSimpleForkCommand:
+  auto fail_fn_n = std::bind(ZygoteFailure, env, n_buffer->niceNameAddr(),
+                             static_cast<jstring>(nullptr), _1);
+  auto fail_fn_z = std::bind(ZygoteFailure, env, "zygote", nullptr, _1);
+
+  struct pollfd fd_structs[2];
+  static const int ZYGOTE_IDX = 0;
+  static const int SESSION_IDX = 1;
+  fd_structs[ZYGOTE_IDX].fd = zygote_socket_fd;
+  fd_structs[ZYGOTE_IDX].events = POLLIN;
+  fd_structs[SESSION_IDX].fd = session_socket;
+  fd_structs[SESSION_IDX].events = POLLIN;
+
+  struct timeval timeout;
+  socklen_t timeout_size = sizeof timeout;
+  if (getsockopt(session_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, &timeout_size) != 0) {
+    fail_fn_z("Failed to retrieve session socket timeout");
+  }
+
+  struct ucred credentials;
+  socklen_t cred_size = sizeof credentials;
+  if (getsockopt(n_buffer->getFd(), SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1
+      || cred_size != sizeof credentials) {
+    fail_fn_1("ForkMany failed to get initial credentials, %s", strerror(errno));
+  }
+
+  bool first_time = true;
+  do {
+    if (credentials.uid != expected_uid) {
+      return JNI_FALSE;
+    }
+    n_buffer->readAllLines(first_time ? fail_fn_1 : fail_fn_n);
+    n_buffer->reset();
+    int pid = zygote::forkApp(env, /* no pipe FDs */ -1, -1, session_socket_fds,
+                              /*args_known=*/ true, /*is_priority_fork=*/ true,
+                              /*purge=*/ first_time);
+    if (pid == 0) {
+      return JNI_TRUE;
+    }
+    // We're in the parent. Write big-endian pid, followed by a boolean.
+    char pid_buf[5];
+    int tmp_pid = pid;
+    for (int i = 3; i >= 0; --i) {
+      pid_buf[i] = tmp_pid & 0xff;
+      tmp_pid >>= 8;
+    }
+    pid_buf[4] = 0;  // Process is not wrapped.
+    int res = write(session_socket, pid_buf, 5);
+    if (res != 5) {
+      if (res == -1) {
+        (first_time ? fail_fn_1 : fail_fn_n)
+            (CREATE_ERROR("Pid write error %d: %s", errno, strerror(errno)));
+      } else {
+        (first_time ? fail_fn_1 : fail_fn_n)
+            (CREATE_ERROR("Write unexpectedly returned short: %d < 5", res));
+      }
+    }
+    // Clear buffer and get count from next command.
+    n_buffer->clear();
+    for (;;) {
+      // Poll isn't strictly necessary for now. But without it, disconnect is hard to detect.
+      int poll_res = TEMP_FAILURE_RETRY(poll(fd_structs, 2, -1 /* infinite timeout */));
+      if ((fd_structs[SESSION_IDX].revents & POLLIN) != 0) {
+        if (n_buffer->getCount(fail_fn_z) != 0) {
+          break;
+        }  // else disconnected;
+      } else if (poll_res == 0 || (fd_structs[ZYGOTE_IDX].revents & POLLIN) == 0) {
+        fail_fn_z(
+            CREATE_ERROR("Poll returned with no descriptors ready! Poll returned %d", poll_res));
+      }
+      // We've now seen either a disconnect or connect request.
+      close(session_socket);
+      int new_fd = accept(zygote_socket_fd, nullptr, nullptr);
+      if (new_fd == -1) {
+        fail_fn_z("Accept(%d) failed: %s", zygote_socket_fd, strerror(errno));
+      }
+      if (new_fd != session_socket) {
+          // Move new_fd back to the old value, so that we don't have to change Java-level data
+          // structures to reflect a change. This implicitly closes the old one.
+          if (dup2(new_fd, session_socket) != session_socket) {
+            fail_fn_z(CREATE_ERROR("Failed to move fd %d to %d: %s",
+                                   new_fd, session_socket, strerror(errno)));
+          }
+          close(new_fd);
+      }
+      // If we ever return, we effectively reuse the old Java ZygoteConnection.
+      // None of its state needs to change.
+      if (setsockopt(session_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, timeout_size) != 0) {
+        fail_fn_z(CREATE_ERROR("Failed to set receive timeout for socket %d: %s",
+                               session_socket, strerror(errno)));
+      }
+      if (setsockopt(session_socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, timeout_size) != 0) {
+        fail_fn_z(CREATE_ERROR("Failed to set send timeout for socket %d: %s",
+                               session_socket, strerror(errno)));
+      }
+      if (getsockopt(session_socket, SOL_SOCKET, SO_PEERCRED, &credentials, &cred_size) == -1) {
+        fail_fn_z(CREATE_ERROR("ForkMany failed to get credentials: %s", strerror(errno)));
+      }
+      if (cred_size != sizeof credentials) {
+        fail_fn_z(CREATE_ERROR("ForkMany credential size = %d, should be %d",
+                               cred_size, static_cast<int>(sizeof credentials)));
+      }
+    }
+    first_time = false;
+  } while (n_buffer->isSimpleForkCommand(minUid, fail_fn_n));
+  ALOGW("forkRepeatedly terminated due to non-simple command");
+  n_buffer->logState();
+  n_buffer->reset();
+  return JNI_FALSE;
+}
+
+#define METHOD_NAME(m) com_android_internal_os_ZygoteCommandBuffer_ ## m
+
+static const JNINativeMethod gMethods[] = {
+        {"getNativeBuffer", "(I)J", (void *) METHOD_NAME(getNativeBuffer)},
+        {"freeNativeBuffer", "(J)V", (void *) METHOD_NAME(freeNativeBuffer)},
+        {"insert", "(JLjava/lang/String;)V", (void *) METHOD_NAME(insert)},
+        {"nativeNextArg", "(J)Ljava/lang/String;", (void *) METHOD_NAME(nativeNextArg)},
+        {"nativeReadFullyAndReset", "(J)V", (void *) METHOD_NAME(nativeReadFullyAndReset)},
+        {"nativeGetCount", "(J)I", (void *) METHOD_NAME(nativeGetCount)},
+        {"nativeForkRepeatedly", "(JIIILjava/lang/String;)Z",
+          (void *) METHOD_NAME(nativeForkRepeatedly)},
+};
+
+int register_com_android_internal_os_ZygoteCommandBuffer(JNIEnv* env) {
+  return RegisterMethodsOrDie(env, "com/android/internal/os/ZygoteCommandBuffer", gMethods,
+                              NELEM(gMethods));
+}
+
+}  // namespace android
diff --git a/core/proto/android/content/package_item_info.proto b/core/proto/android/content/package_item_info.proto
index e683306..bb39ea8 100644
--- a/core/proto/android/content/package_item_info.proto
+++ b/core/proto/android/content/package_item_info.proto
@@ -110,6 +110,8 @@
         optional int32 network_security_config_res = 17;
         optional int32 category = 18;
         optional int32 enable_gwp_asan = 19;
+        optional int32 enable_memtag = 20;
+        optional bool native_heap_zero_init = 21;
     }
     optional Detail detail = 17;
 }
diff --git a/core/proto/android/service/netstats.proto b/core/proto/android/service/netstats.proto
index 8ebb4a9..c8cdfdd 100644
--- a/core/proto/android/service/netstats.proto
+++ b/core/proto/android/service/netstats.proto
@@ -80,6 +80,8 @@
     optional bool metered = 5;
 
     optional bool default_network = 6;
+
+    optional int32 oem_managed_network = 7;
 }
 
 // Corresponds to NetworkStatsRecorder.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d1e6111..dc935c0 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1270,11 +1270,13 @@
         android:protectionLevel="dangerous|instant" />
 
     <!-- ====================================================================== -->
-    <!-- Permissions for accessing the UCE Service                              -->
+    <!-- Permissions for accessing the vendor UCE Service                       -->
     <!-- ====================================================================== -->
 
     <!-- @hide Allows an application to Access UCE-Presence.
          <p>Protection level: signature|privileged
+         @deprecated Framework should no longer use this permission to access the vendor UCE service
+         using AIDL, it is instead implemented by RcsCapabilityExchangeImplBase
     -->
     <permission android:name="android.permission.ACCESS_UCE_PRESENCE_SERVICE"
         android:permissionGroup="android.permission-group.PHONE"
@@ -1282,6 +1284,8 @@
 
     <!-- @hide Allows an application to Access UCE-OPTIONS.
          <p>Protection level: signature|privileged
+         @deprecated Framework should no longer use this permission to access the vendor UCE service
+         using AIDL, it is instead implemented by RcsCapabilityExchangeImplBase
     -->
     <permission android:name="android.permission.ACCESS_UCE_OPTIONS_SERVICE"
         android:permissionGroup="android.permission-group.PHONE"
@@ -2366,6 +2370,13 @@
     <permission android:name="android.permission.BIND_GBA_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- Required for an Application to access APIs related to RCS User Capability Exchange.
+         <p>Protection level: signature|privileged
+         @SystemApi
+         @hide -->
+    <permission android:name="android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE"
+        android:protectionLevel="signature|privileged" />
+
     <!-- ================================== -->
     <!-- Permissions for sdcard interaction -->
     <!-- ================================== -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 0c63c10..47dbd64 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1560,6 +1560,13 @@
        <enum name="always" value="1" />
     </attr>
 
+    <attr name="memtagMode">
+       <enum name="default" value="-1" />
+       <enum name="off" value="0" />
+       <enum name="async" value="1" />
+       <enum name="sync" value="2" />
+    </attr>
+
     <!-- The <code>manifest</code> tag is the root of an
          <code>AndroidManifest.xml</code> file,
          describing the contents of an Android package (.apk) file.  One
@@ -1827,6 +1834,10 @@
 
         <attr name="gwpAsanMode" />
 
+        <attr name="memtagMode" />
+
+        <attr name="nativeHeapZeroInit" format="boolean" />
+
         <!-- @hide no longer used, kept to preserve padding -->
         <attr name="allowAutoRevokePermissionsExemption" format="boolean" />
 
@@ -2350,6 +2361,8 @@
         <!-- Required name of the process that is allowed -->
         <attr name="process" />
         <attr name="gwpAsanMode" />
+        <attr name="memtagMode" />
+        <attr name="nativeHeapZeroInit" />
     </declare-styleable>
 
     <!-- The <code>deny-permission</code> tag specifies that a permission is to be denied
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index ee45249..93758b6 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4414,4 +4414,7 @@
 
     <!-- Whether to select voice/data/sms preference without user confirmation -->
     <bool name="config_voice_data_sms_auto_fallback">false</bool>
+
+    <!-- Whether to allow the caching of the SIM PIN for verification after unattended reboot -->
+    <bool name="config_allow_pin_storage_for_unattended_reboot">true</bool>
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0874a77..0f846d3 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3046,6 +3046,8 @@
     <public name="canPauseRecording" />
     <!-- attribute definitions go here -->
     <public name="requireDeviceScreenOn" />
+    <public name="memtagMode" />
+    <public name="nativeHeapZeroInit" />
   </public-group>
 
   <public-group type="drawable" first-id="0x010800b5">
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4509b4e..fc75463 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2612,6 +2612,7 @@
   <java-symbol type="bool" name="config_defaultWindowFeatureContextMenu" />
   <java-symbol type="bool" name="config_overrideRemoteViewsActivityTransition" />
   <java-symbol type="attr" name="colorProgressBackgroundNormal" />
+  <java-symbol type="bool" name="config_allow_pin_storage_for_unattended_reboot" />
 
   <java-symbol type="layout" name="simple_account_item" />
   <java-symbol type="string" name="prohibit_manual_network_selection_in_gobal_mode" />
diff --git a/core/tests/coretests/src/android/view/OWNERS b/core/tests/coretests/src/android/view/OWNERS
index 5031ff9..fa1aa5e 100644
--- a/core/tests/coretests/src/android/view/OWNERS
+++ b/core/tests/coretests/src/android/view/OWNERS
@@ -1,7 +1,7 @@
 # Input
-per-file *MotionEventTest.* = michaelwr@google.com, svv@google.com
-per-file *KeyEventTest.* = michaelwr@google.com, svv@google.com
-per-file VelocityTest.java = michaelwr@google.com, svv@google.com
+per-file *MotionEventTest.* = file:/services/core/java/com/android/server/input/OWNERS
+per-file *KeyEventTest.* = file:/services/core/java/com/android/server/input/OWNERS
+per-file VelocityTest.java = file:/services/core/java/com/android/server/input/OWNERS
 
 # WindowManager
 per-file *Display* = file:/services/core/java/com/android/server/wm/OWNERS
@@ -9,3 +9,6 @@
 per-file *Insets* = file:/services/core/java/com/android/server/wm/OWNERS
 per-file *View* = file:/services/core/java/com/android/server/wm/OWNERS
 per-file *Visibility* = file:/services/core/java/com/android/server/wm/OWNERS
+
+# Scroll Capture
+per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/tests/coretests/src/com/android/internal/view/OWNERS b/core/tests/coretests/src/com/android/internal/view/OWNERS
new file mode 100644
index 0000000..1dad10d
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/view/OWNERS
@@ -0,0 +1,3 @@
+# Scroll Capture
+per-file *ScrollCapture*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
+per-file *CaptureHelper*.java = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
diff --git a/core/tests/overlaytests/device/AndroidTest.xml b/core/tests/overlaytests/device/AndroidTest.xml
index ebbdda5..2d7d9b4 100644
--- a/core/tests/overlaytests/device/AndroidTest.xml
+++ b/core/tests/overlaytests/device/AndroidTest.xml
@@ -19,17 +19,13 @@
     <option name="test-suite-tag" value="apct" />
     <option name="test-suite-tag" value="apct-instrumentation" />
 
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
         <option name="cleanup" value="true" />
         <option name="remount-system" value="true" />
         <option name="push" value="OverlayDeviceTests.apk->/system/app/OverlayDeviceTests.apk" />
     </target_preparer>
-
-    <!-- Reboot to have the test APK scanned by PM and reboot after to remove the test APK. -->
-    <target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer">
-      <option name="pre-reboot" value="true" />
-      <option name="post-reboot" value="true" />
-    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer" />
 
     <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
         <option name="cleanup-apks" value="true" />
diff --git a/core/tests/overlaytests/remount/test-apps/overlaid_apex/Android.bp b/core/tests/overlaytests/remount/test-apps/overlaid_apex/Android.bp
index 42421ce..3536c40 100644
--- a/core/tests/overlaytests/remount/test-apps/overlaid_apex/Android.bp
+++ b/core/tests/overlaytests/remount/test-apps/overlaid_apex/Android.bp
@@ -50,4 +50,5 @@
     key: "com.android.overlaytest.overlaid.key",
     apps: ["OverlayRemountedTest_Target"],
     installable: false,
+    updatable: false,
 }
diff --git a/core/tests/overlaytests/remount/test-apps/overlay_apex/Android.bp b/core/tests/overlaytests/remount/test-apps/overlay_apex/Android.bp
index 0b52dcc..f041404 100644
--- a/core/tests/overlaytests/remount/test-apps/overlay_apex/Android.bp
+++ b/core/tests/overlaytests/remount/test-apps/overlay_apex/Android.bp
@@ -50,4 +50,5 @@
     key: "com.android.overlaytest.overlay.key",
     apps: ["OverlayRemountedTest_Overlay"],
     installable: false,
+    updatable: false,
 }
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 5b32641..eb6bf3e 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -305,6 +305,7 @@
         <!-- Needed for test only -->
         <permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
         <permission name="android.permission.ACCESS_LOWPAN_STATE"/>
+        <permission name="android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE"/>
         <permission name="android.permission.BACKUP"/>
         <permission name="android.permission.BATTERY_STATS"/>
         <permission name="android.permission.BIND_APPWIDGET"/>
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index 4c214b5..d2b47c6 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -60,7 +60,7 @@
     <alias name="sans-serif-condensed-medium" to="sans-serif-condensed" weight="500" />
 
     <family name="serif">
-        <font weight="400" style="normal">NotoSerif-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSerif.ttf</font>
         <font weight="700" style="normal">NotoSerif-Bold.ttf</font>
         <font weight="400" style="italic">NotoSerif-Italic.ttf</font>
         <font weight="700" style="italic">NotoSerif-BoldItalic.ttf</font>
@@ -112,33 +112,33 @@
 
     <!-- fallback fonts -->
     <family lang="und-Arab" variant="elegant">
-        <font weight="400" style="normal">NotoNaskhArabic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoNaskhArabic.ttf</font>
         <font weight="700" style="normal">NotoNaskhArabic-Bold.ttf</font>
     </family>
     <family lang="und-Arab" variant="compact">
-        <font weight="400" style="normal">NotoNaskhArabicUI-Regular.ttf</font>
+        <font weight="400" style="normal">NotoNaskhArabicUI.ttf</font>
         <font weight="700" style="normal">NotoNaskhArabicUI-Bold.ttf</font>
     </family>
     <family lang="und-Ethi">
-        <font weight="400" style="normal">NotoSansEthiopic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansEthiopic.ttf</font>
         <font weight="700" style="normal">NotoSansEthiopic-Bold.ttf</font>
         <font weight="400" style="normal" fallbackFor="serif">NotoSerifEthiopic-Regular.otf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifEthiopic-Bold.otf</font>
     </family>
     <family lang="und-Hebr">
-        <font weight="400" style="normal">NotoSansHebrew-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansHebrew.ttf</font>
         <font weight="700" style="normal">NotoSansHebrew-Bold.ttf</font>
         <font weight="400" style="normal" fallbackFor="serif">NotoSerifHebrew-Regular.ttf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifHebrew-Bold.ttf</font>
     </family>
     <family lang="und-Thai" variant="elegant">
-        <font weight="400" style="normal">NotoSansThai-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansThai.ttf</font>
         <font weight="700" style="normal">NotoSansThai-Bold.ttf</font>
-        <font weight="400" style="normal" fallbackFor="serif">NotoSerifThai-Regular.ttf</font>
+        <font weight="400" style="normal" fallbackFor="serif">NotoSerifThai.ttf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifThai-Bold.ttf</font>
     </family>
     <family lang="und-Thai" variant="compact">
-        <font weight="400" style="normal">NotoSansThaiUI-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansThaiUI.ttf</font>
         <font weight="700" style="normal">NotoSansThaiUI-Bold.ttf</font>
     </family>
     <family lang="und-Armn">
@@ -149,28 +149,28 @@
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifArmenian-Bold.otf</font>
     </family>
     <family lang="und-Geor,und-Geok">
-        <font weight="400" style="normal">NotoSansGeorgian-VF.ttf
+        <font weight="400" style="normal">NotoSansGeorgian-Regular.ttf
             <axis tag="wght" stylevalue="400" />
         </font>
-        <font weight="500" style="normal">NotoSansGeorgian-VF.ttf
+        <font weight="500" style="normal">NotoSansGeorgian-Regular.ttf
             <axis tag="wght" stylevalue="500" />
         </font>
-        <font weight="600" style="normal">NotoSansGeorgian-VF.ttf
+        <font weight="600" style="normal">NotoSansGeorgian-Regular.ttf
             <axis tag="wght" stylevalue="600" />
         </font>
-        <font weight="700" style="normal">NotoSansGeorgian-VF.ttf
+        <font weight="700" style="normal">NotoSansGeorgian-Regular.ttf
             <axis tag="wght" stylevalue="700" />
         </font>
-        <font weight="400" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
+        <font weight="400" style="normal" fallbackFor="serif">NotoSerifGeorgian-Regular.ttf
             <axis tag="wght" stylevalue="400" />
         </font>
-        <font weight="500" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
+        <font weight="500" style="normal" fallbackFor="serif">NotoSerifGeorgian-Regular.ttf
             <axis tag="wght" stylevalue="500" />
         </font>
-        <font weight="600" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
+        <font weight="600" style="normal" fallbackFor="serif">NotoSerifGeorgian-Regular.ttf
             <axis tag="wght" stylevalue="600" />
         </font>
-        <font weight="700" style="normal" fallbackFor="serif">NotoSerifGeorgian-VF.ttf
+        <font weight="700" style="normal" fallbackFor="serif">NotoSerifGeorgian-Regular.ttf
             <axis tag="wght" stylevalue="700" />
         </font>
     </family>
@@ -178,7 +178,7 @@
         <font weight="400" style="normal">NotoSansDevanagari-Regular.otf</font>
         <font weight="500" style="normal">NotoSansDevanagari-Medium.otf</font>
         <font weight="700" style="normal">NotoSansDevanagari-Bold.otf</font>
-        <font weight="400" style="normal" fallbackFor="serif">NotoSerifDevanagari-Regular.ttf</font>
+        <font weight="400" style="normal" fallbackFor="serif">NotoSerifDevanagari.ttf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifDevanagari-Bold.ttf</font>
     </family>
     <family lang="und-Deva" variant="compact">
@@ -191,23 +191,23 @@
          danda characters.
     -->
     <family lang="und-Gujr" variant="elegant">
-        <font weight="400" style="normal">NotoSansGujarati-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansGujarati.ttf</font>
         <font weight="700" style="normal">NotoSansGujarati-Bold.ttf</font>
-        <font weight="400" style="normal" fallbackFor="serif">NotoSerifGujarati-Regular.ttf</font>
+        <font weight="400" style="normal" fallbackFor="serif">NotoSerifGujarati.ttf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifGujarati-Bold.ttf</font>
     </family>
     <family lang="und-Gujr" variant="compact">
-        <font weight="400" style="normal">NotoSansGujaratiUI-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansGujaratiUI.ttf</font>
         <font weight="700" style="normal">NotoSansGujaratiUI-Bold.ttf</font>
     </family>
     <family lang="und-Guru" variant="elegant">
-        <font weight="400" style="normal">NotoSansGurmukhi-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansGurmukhi.ttf</font>
         <font weight="700" style="normal">NotoSansGurmukhi-Bold.ttf</font>
         <font weight="400" style="normal" fallbackFor="serif">NotoSerifGurmukhi-Regular.otf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifGurmukhi-Bold.otf</font>
     </family>
     <family lang="und-Guru" variant="compact">
-        <font weight="400" style="normal">NotoSansGurmukhiUI-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansGurmukhiUI.ttf</font>
         <font weight="700" style="normal">NotoSansGurmukhiUI-Bold.ttf</font>
     </family>
     <family lang="und-Taml" variant="elegant">
@@ -226,7 +226,7 @@
         <font weight="400" style="normal">NotoSansMalayalam-Regular.otf</font>
         <font weight="500" style="normal">NotoSansMalayalam-Medium.otf</font>
         <font weight="700" style="normal">NotoSansMalayalam-Bold.otf</font>
-        <font weight="400" style="normal" fallbackFor="serif">NotoSerifMalayalam-Regular.ttf</font>
+        <font weight="400" style="normal" fallbackFor="serif">NotoSerifMalayalam.ttf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifMalayalam-Bold.ttf</font>
     </family>
     <family lang="und-Mlym" variant="compact">
@@ -238,7 +238,7 @@
         <font weight="400" style="normal">NotoSansBengali-Regular.otf</font>
         <font weight="500" style="normal">NotoSansBengali-Medium.otf</font>
         <font weight="700" style="normal">NotoSansBengali-Bold.otf</font>
-        <font weight="400" style="normal" fallbackFor="serif">NotoSerifBengali-Regular.ttf</font>
+        <font weight="400" style="normal" fallbackFor="serif">NotoSerifBengali.ttf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifBengali-Bold.ttf</font>
     </family>
     <family lang="und-Beng" variant="compact">
@@ -247,31 +247,31 @@
         <font weight="700" style="normal">NotoSansBengaliUI-Bold.otf</font>
     </family>
     <family lang="und-Telu" variant="elegant">
-        <font weight="400" style="normal">NotoSansTelugu-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansTelugu.ttf</font>
         <font weight="700" style="normal">NotoSansTelugu-Bold.ttf</font>
-        <font weight="400" style="normal" fallbackFor="serif">NotoSerifTelugu-Regular.ttf</font>
+        <font weight="400" style="normal" fallbackFor="serif">NotoSerifTelugu.ttf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifTelugu-Bold.ttf</font>
     </family>
     <family lang="und-Telu" variant="compact">
-        <font weight="400" style="normal">NotoSansTeluguUI-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansTeluguUI.ttf</font>
         <font weight="700" style="normal">NotoSansTeluguUI-Bold.ttf</font>
     </family>
     <family lang="und-Knda" variant="elegant">
-        <font weight="400" style="normal">NotoSansKannada-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansKannada.ttf</font>
         <font weight="700" style="normal">NotoSansKannada-Bold.ttf</font>
-        <font weight="400" style="normal" fallbackFor="serif">NotoSerifKannada-Regular.ttf</font>
+        <font weight="400" style="normal" fallbackFor="serif">NotoSerifKannada.ttf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifKannada-Bold.ttf</font>
     </family>
     <family lang="und-Knda" variant="compact">
-        <font weight="400" style="normal">NotoSansKannadaUI-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansKannadaUI.ttf</font>
         <font weight="700" style="normal">NotoSansKannadaUI-Bold.ttf</font>
     </family>
     <family lang="und-Orya" variant="elegant">
-        <font weight="400" style="normal">NotoSansOriya-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansOriya.ttf</font>
         <font weight="700" style="normal">NotoSansOriya-Bold.ttf</font>
     </family>
     <family lang="und-Orya" variant="compact">
-        <font weight="400" style="normal">NotoSansOriyaUI-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansOriyaUI.ttf</font>
         <font weight="700" style="normal">NotoSansOriyaUI-Bold.ttf</font>
     </family>
 
@@ -288,39 +288,39 @@
         <font weight="700" style="normal">NotoSansSinhalaUI-Bold.otf</font>
     </family>
     <family lang="und-Khmr" variant="elegant">
-        <font weight="100" style="normal">NotoSansKhmer-VF.ttf
+        <font weight="100" style="normal">NotoSansKhmer-Regular.ttf
             <axis tag="wdth" stylevalue="100.0" />
             <axis tag="wght" stylevalue="26.0" />
         </font>
-        <font weight="200" style="normal">NotoSansKhmer-VF.ttf
+        <font weight="200" style="normal">NotoSansKhmer-Regular.ttf
             <axis tag="wdth" stylevalue="100.0" />
             <axis tag="wght" stylevalue="39.0" />
         </font>
-        <font weight="300" style="normal">NotoSansKhmer-VF.ttf
+        <font weight="300" style="normal">NotoSansKhmer-Regular.ttf
             <axis tag="wdth" stylevalue="100.0" />
             <axis tag="wght" stylevalue="58.0" />
         </font>
-        <font weight="400" style="normal">NotoSansKhmer-VF.ttf
+        <font weight="400" style="normal">NotoSansKhmer-Regular.ttf
             <axis tag="wdth" stylevalue="100.0" />
             <axis tag="wght" stylevalue="90.0" />
         </font>
-        <font weight="500" style="normal">NotoSansKhmer-VF.ttf
+        <font weight="500" style="normal">NotoSansKhmer-Regular.ttf
             <axis tag="wdth" stylevalue="100.0" />
             <axis tag="wght" stylevalue="108.0" />
         </font>
-        <font weight="600" style="normal">NotoSansKhmer-VF.ttf
+        <font weight="600" style="normal">NotoSansKhmer-Regular.ttf
             <axis tag="wdth" stylevalue="100.0" />
             <axis tag="wght" stylevalue="128.0" />
         </font>
-        <font weight="700" style="normal">NotoSansKhmer-VF.ttf
+        <font weight="700" style="normal">NotoSansKhmer-Regular.ttf
             <axis tag="wdth" stylevalue="100.0" />
             <axis tag="wght" stylevalue="151.0" />
         </font>
-        <font weight="800" style="normal">NotoSansKhmer-VF.ttf
+        <font weight="800" style="normal">NotoSansKhmer-Regular.ttf
             <axis tag="wdth" stylevalue="100.0" />
             <axis tag="wght" stylevalue="169.0" />
         </font>
-        <font weight="900" style="normal">NotoSansKhmer-VF.ttf
+        <font weight="900" style="normal">NotoSansKhmer-Regular.ttf
             <axis tag="wdth" stylevalue="100.0" />
             <axis tag="wght" stylevalue="190.0" />
         </font>
@@ -328,17 +328,17 @@
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifKhmer-Bold.otf</font>
       </family>
     <family lang="und-Khmr" variant="compact">
-        <font weight="400" style="normal">NotoSansKhmerUI-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansKhmerUI.ttf</font>
         <font weight="700" style="normal">NotoSansKhmerUI-Bold.ttf</font>
     </family>
     <family lang="und-Laoo" variant="elegant">
-        <font weight="400" style="normal">NotoSansLao-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansLao.ttf</font>
         <font weight="700" style="normal">NotoSansLao-Bold.ttf</font>
-        <font weight="400" style="normal" fallbackFor="serif">NotoSerifLao-Regular.ttf</font>
+        <font weight="400" style="normal" fallbackFor="serif">NotoSerifLao.ttf</font>
         <font weight="700" style="normal" fallbackFor="serif">NotoSerifLao-Bold.ttf</font>
     </family>
     <family lang="und-Laoo" variant="compact">
-        <font weight="400" style="normal">NotoSansLaoUI-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansLaoUI.ttf</font>
         <font weight="700" style="normal">NotoSansLaoUI-Bold.ttf</font>
     </family>
     <family lang="und-Mymr" variant="elegant">
@@ -354,56 +354,56 @@
         <font weight="700" style="normal">NotoSansMyanmarUI-Bold.otf</font>
     </family>
     <family lang="und-Thaa">
-        <font weight="400" style="normal">NotoSansThaana-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansThaana.ttf</font>
         <font weight="700" style="normal">NotoSansThaana-Bold.ttf</font>
     </family>
     <family lang="und-Cham">
-        <font weight="400" style="normal">NotoSansCham-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansCham.ttf</font>
         <font weight="700" style="normal">NotoSansCham-Bold.ttf</font>
     </family>
     <family lang="und-Ahom">
         <font weight="400" style="normal">NotoSansAhom-Regular.otf</font>
     </family>
     <family lang="und-Adlm">
-        <font weight="400" style="normal">NotoSansAdlam-VF.ttf
+        <font weight="400" style="normal">NotoSansAdlam-Regular.ttf
             <axis tag="wght" stylevalue="400" />
         </font>
-        <font weight="500" style="normal">NotoSansAdlam-VF.ttf
+        <font weight="500" style="normal">NotoSansAdlam-Regular.ttf
             <axis tag="wght" stylevalue="500" />
         </font>
-        <font weight="600" style="normal">NotoSansAdlam-VF.ttf
+        <font weight="600" style="normal">NotoSansAdlam-Regular.ttf
             <axis tag="wght" stylevalue="600" />
         </font>
-        <font weight="700" style="normal">NotoSansAdlam-VF.ttf
+        <font weight="700" style="normal">NotoSansAdlam-Regular.ttf
             <axis tag="wght" stylevalue="700" />
         </font>
     </family>
     <family lang="und-Avst">
-        <font weight="400" style="normal">NotoSansAvestan-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansAvestan.ttf</font>
     </family>
     <family lang="und-Bali">
-        <font weight="400" style="normal">NotoSansBalinese-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansBalinese.ttf</font>
     </family>
     <family lang="und-Bamu">
-        <font weight="400" style="normal">NotoSansBamum-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansBamum.ttf</font>
     </family>
     <family lang="und-Batk">
-        <font weight="400" style="normal">NotoSansBatak-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansBatak.ttf</font>
     </family>
     <family lang="und-Brah">
-        <font weight="400" style="normal">NotoSansBrahmi-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansBrahmi.ttf</font>
     </family>
     <family lang="und-Bugi">
-        <font weight="400" style="normal">NotoSansBuginese-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansBuginese.ttf</font>
     </family>
     <family lang="und-Buhd">
-        <font weight="400" style="normal">NotoSansBuhid-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansBuhid.ttf</font>
     </family>
     <family lang="und-Cans">
-        <font weight="400" style="normal">NotoSansCanadianAboriginal-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansCanadianAboriginal.ttf</font>
     </family>
     <family lang="und-Cari">
-        <font weight="400" style="normal">NotoSansCarian-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansCarian.ttf</font>
     </family>
     <family lang="und-Cakm">
         <font weight="400" style="normal">NotoSansChakma-Regular.otf</font>
@@ -412,184 +412,184 @@
         <font weight="400" style="normal">NotoSansCherokee-Regular.ttf</font>
     </family>
     <family lang="und-Copt">
-        <font weight="400" style="normal">NotoSansCoptic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansCoptic.ttf</font>
     </family>
     <family lang="und-Xsux">
-        <font weight="400" style="normal">NotoSansCuneiform-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansCuneiform.ttf</font>
     </family>
     <family lang="und-Cprt">
-        <font weight="400" style="normal">NotoSansCypriot-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansCypriot.ttf</font>
     </family>
     <family lang="und-Dsrt">
-        <font weight="400" style="normal">NotoSansDeseret-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansDeseret.ttf</font>
     </family>
     <family lang="und-Egyp">
-        <font weight="400" style="normal">NotoSansEgyptianHieroglyphs-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansEgyptianHieroglyphs.ttf</font>
     </family>
     <family lang="und-Elba">
         <font weight="400" style="normal">NotoSansElbasan-Regular.otf</font>
     </family>
     <family lang="und-Glag">
-        <font weight="400" style="normal">NotoSansGlagolitic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansGlagolitic.ttf</font>
     </family>
     <family lang="und-Goth">
-        <font weight="400" style="normal">NotoSansGothic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansGothic.ttf</font>
     </family>
     <family lang="und-Hano">
-        <font weight="400" style="normal">NotoSansHanunoo-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansHanunoo.ttf</font>
     </family>
     <family lang="und-Armi">
-        <font weight="400" style="normal">NotoSansImperialAramaic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansImperialAramaic.ttf</font>
     </family>
     <family lang="und-Phli">
-        <font weight="400" style="normal">NotoSansInscriptionalPahlavi-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansInscriptionalPahlavi.ttf</font>
     </family>
     <family lang="und-Prti">
-        <font weight="400" style="normal">NotoSansInscriptionalParthian-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansInscriptionalParthian.ttf</font>
     </family>
     <family lang="und-Java">
         <font weight="400" style="normal">NotoSansJavanese-Regular.ttf</font>
     </family>
     <family lang="und-Kthi">
-        <font weight="400" style="normal">NotoSansKaithi-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansKaithi.ttf</font>
     </family>
     <family lang="und-Kali">
-        <font weight="400" style="normal">NotoSansKayahLi-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansKayahLi.ttf</font>
     </family>
     <family lang="und-Khar">
-        <font weight="400" style="normal">NotoSansKharoshthi-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansKharoshthi.ttf</font>
     </family>
     <family lang="und-Lepc">
-        <font weight="400" style="normal">NotoSansLepcha-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansLepcha.ttf</font>
     </family>
     <family lang="und-Limb">
-        <font weight="400" style="normal">NotoSansLimbu-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansLimbu.ttf</font>
     </family>
     <family lang="und-Linb">
-        <font weight="400" style="normal">NotoSansLinearB-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansLinearB.ttf</font>
     </family>
     <family lang="und-Lisu">
-        <font weight="400" style="normal">NotoSansLisu-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansLisu.ttf</font>
     </family>
     <family lang="und-Lyci">
-        <font weight="400" style="normal">NotoSansLycian-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansLycian.ttf</font>
     </family>
     <family lang="und-Lydi">
-        <font weight="400" style="normal">NotoSansLydian-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansLydian.ttf</font>
     </family>
     <family lang="und-Mand">
-        <font weight="400" style="normal">NotoSansMandaic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansMandaic.ttf</font>
     </family>
     <family lang="und-Mtei">
-        <font weight="400" style="normal">NotoSansMeeteiMayek-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansMeeteiMayek.ttf</font>
     </family>
     <family lang="und-Talu">
-        <font weight="400" style="normal">NotoSansNewTaiLue-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansNewTaiLue.ttf</font>
     </family>
     <family lang="und-Nkoo">
-        <font weight="400" style="normal">NotoSansNKo-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansNKo.ttf</font>
     </family>
     <family lang="und-Ogam">
-        <font weight="400" style="normal">NotoSansOgham-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansOgham.ttf</font>
     </family>
     <family lang="und-Olck">
-        <font weight="400" style="normal">NotoSansOlChiki-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansOlChiki.ttf</font>
     </family>
     <family lang="und-Ital">
-        <font weight="400" style="normal">NotoSansOldItalic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansOldItalic.ttf</font>
     </family>
     <family lang="und-Xpeo">
-        <font weight="400" style="normal">NotoSansOldPersian-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansOldPersian.ttf</font>
     </family>
     <family lang="und-Sarb">
-        <font weight="400" style="normal">NotoSansOldSouthArabian-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansOldSouthArabian.ttf</font>
     </family>
     <family lang="und-Orkh">
-        <font weight="400" style="normal">NotoSansOldTurkic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansOldTurkic.ttf</font>
     </family>
     <family lang="und-Osge">
         <font weight="400" style="normal">NotoSansOsage-Regular.ttf</font>
     </family>
     <family lang="und-Osma">
-        <font weight="400" style="normal">NotoSansOsmanya-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansOsmanya.ttf</font>
     </family>
     <family lang="und-Phnx">
-        <font weight="400" style="normal">NotoSansPhoenician-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansPhoenician.ttf</font>
     </family>
     <family lang="und-Rjng">
-        <font weight="400" style="normal">NotoSansRejang-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansRejang.ttf</font>
     </family>
     <family lang="und-Runr">
-        <font weight="400" style="normal">NotoSansRunic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansRunic.ttf</font>
     </family>
     <family lang="und-Samr">
-        <font weight="400" style="normal">NotoSansSamaritan-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansSamaritan.ttf</font>
     </family>
     <family lang="und-Saur">
-        <font weight="400" style="normal">NotoSansSaurashtra-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansSaurashtra.ttf</font>
     </family>
     <family lang="und-Shaw">
-        <font weight="400" style="normal">NotoSansShavian-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansShavian.ttf</font>
     </family>
     <family lang="und-Sund">
-        <font weight="400" style="normal">NotoSansSundanese-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansSundanese.ttf</font>
     </family>
     <family lang="und-Sylo">
-        <font weight="400" style="normal">NotoSansSylotiNagri-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansSylotiNagri.ttf</font>
     </family>
     <!-- Esrangela should precede Eastern and Western Syriac, since it's our default form. -->
     <family lang="und-Syre">
-        <font weight="400" style="normal">NotoSansSyriacEstrangela-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansSyriacEstrangela.ttf</font>
     </family>
     <family lang="und-Syrn">
-        <font weight="400" style="normal">NotoSansSyriacEastern-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansSyriacEastern.ttf</font>
     </family>
     <family lang="und-Syrj">
-        <font weight="400" style="normal">NotoSansSyriacWestern-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansSyriacWestern.ttf</font>
     </family>
     <family lang="und-Tglg">
-        <font weight="400" style="normal">NotoSansTagalog-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansTagalog.ttf</font>
     </family>
     <family lang="und-Tagb">
-        <font weight="400" style="normal">NotoSansTagbanwa-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansTagbanwa.ttf</font>
     </family>
     <family lang="und-Lana">
-        <font weight="400" style="normal">NotoSansTaiTham-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansTaiTham.ttf</font>
     </family>
     <family lang="und-Tavt">
-        <font weight="400" style="normal">NotoSansTaiViet-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansTaiViet.ttf</font>
     </family>
     <family lang="und-Tibt">
-        <font weight="400" style="normal">NotoSansTibetan-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansTibetan.ttf</font>
         <font weight="700" style="normal">NotoSansTibetan-Bold.ttf</font>
     </family>
     <family lang="und-Tfng">
         <font weight="400" style="normal">NotoSansTifinagh-Regular.otf</font>
     </family>
     <family lang="und-Ugar">
-        <font weight="400" style="normal">NotoSansUgaritic-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansUgaritic.ttf</font>
     </family>
     <family lang="und-Vaii">
-        <font weight="400" style="normal">NotoSansVai-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansVai.ttf</font>
     </family>
     <family>
         <font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted.ttf</font>
     </family>
     <family lang="zh-Hans">
-        <font weight="400" style="normal" index="2">NotoSansCJK-Regular.ttc</font>
-        <font weight="400" style="normal" index="2" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
+        <font weight="400" style="normal" index="2">NotoSansCJKjp-Regular.otc</font>
+        <font weight="400" style="normal" index="2" fallbackFor="serif">NotoSerifCJKjp-Regular.otc</font>
     </family>
     <family lang="zh-Hant,zh-Bopo">
-        <font weight="400" style="normal" index="3">NotoSansCJK-Regular.ttc</font>
-        <font weight="400" style="normal" index="3" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
+        <font weight="400" style="normal" index="3">NotoSansCJKjp-Regular.otc</font>
+        <font weight="400" style="normal" index="3" fallbackFor="serif">NotoSerifCJKjp-Regular.otc</font>
     </family>
     <family lang="ja">
-        <font weight="400" style="normal" index="0">NotoSansCJK-Regular.ttc</font>
-        <font weight="400" style="normal" index="0" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
+        <font weight="400" style="normal" index="0">NotoSansCJKjp-Regular.otc</font>
+        <font weight="400" style="normal" index="0" fallbackFor="serif">NotoSerifCJKjp-Regular.otc</font>
     </family>
     <family lang="ko">
-        <font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
-        <font weight="400" style="normal" index="1" fallbackFor="serif">NotoSerifCJK-Regular.ttc</font>
+        <font weight="400" style="normal" index="1">NotoSansCJKjp-Regular.otc</font>
+        <font weight="400" style="normal" index="1" fallbackFor="serif">NotoSerifCJKjp-Regular.otc</font>
     </family>
     <family lang="und-Zsye">
         <font weight="400" style="normal">NotoColorEmoji.ttf</font>
@@ -602,16 +602,16 @@
         override the East Asian punctuation for Chinese.
     -->
     <family lang="und-Tale">
-        <font weight="400" style="normal">NotoSansTaiLe-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansTaiLe.ttf</font>
     </family>
     <family lang="und-Yiii">
-        <font weight="400" style="normal">NotoSansYi-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansYi.ttf</font>
     </family>
     <family lang="und-Mong">
-        <font weight="400" style="normal">NotoSansMongolian-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansMongolian.ttf</font>
     </family>
     <family lang="und-Phag">
-        <font weight="400" style="normal">NotoSansPhagsPa-Regular.ttf</font>
+        <font weight="400" style="normal">NotoSansPhagsPa.ttf</font>
     </family>
     <family lang="und-Hluw">
         <font weight="400" style="normal">NotoSansAnatolianHieroglyphs-Regular.otf</font>
diff --git a/data/keyboards/OWNERS b/data/keyboards/OWNERS
index c4f6df8..0ce8350 100644
--- a/data/keyboards/OWNERS
+++ b/data/keyboards/OWNERS
@@ -1,5 +1,3 @@
 set noparent
 
-michaelwr@google.com
-svv@google.com
-lzye@google.com
+include /services/core/java/com/android/server/input/OWNERS
diff --git a/keystore/java/android/security/AndroidKeyStoreMaintenance.java b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
new file mode 100644
index 0000000..ed789f0
--- /dev/null
+++ b/keystore/java/android/security/AndroidKeyStoreMaintenance.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2021 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.security;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
+import android.security.usermanager.IKeystoreUserManager;
+import android.system.keystore2.Domain;
+import android.system.keystore2.ResponseCode;
+import android.util.Log;
+
+/**
+ * @hide This is the client side for IKeystoreUserManager AIDL.
+ * It shall only be used by the LockSettingsService.
+ */
+public class AndroidKeyStoreMaintenance {
+    private static final String TAG = "AndroidKeyStoreMaintenance";
+
+    public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR;
+
+    private static IKeystoreUserManager getService() {
+        return IKeystoreUserManager.Stub.asInterface(
+                ServiceManager.checkService("android.security.usermanager"));
+    }
+
+    /**
+     * Informs Keystore 2.0 about adding a user
+     *
+     * @param userId - Android user id of the user being added
+     * @return 0 if successful or a {@code ResponseCode}
+     * @hide
+     */
+    public static int onUserAdded(@NonNull int userId) {
+        if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
+        try {
+            getService().onUserAdded(userId);
+            return 0;
+        } catch (ServiceSpecificException e) {
+            Log.e(TAG, "onUserAdded failed", e);
+            return e.errorCode;
+        } catch (Exception e) {
+            Log.e(TAG, "Can not connect to keystore", e);
+            return SYSTEM_ERROR;
+        }
+    }
+
+    /**
+     * Informs Keystore 2.0 about removing a usergit mer
+     *
+     * @param userId - Android user id of the user being removed
+     * @return 0 if successful or a {@code ResponseCode}
+     * @hide
+     */
+    public static int onUserRemoved(int userId) {
+        if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
+        try {
+            getService().onUserRemoved(userId);
+            return 0;
+        } catch (ServiceSpecificException e) {
+            Log.e(TAG, "onUserRemoved failed", e);
+            return e.errorCode;
+        } catch (Exception e) {
+            Log.e(TAG, "Can not connect to keystore", e);
+            return SYSTEM_ERROR;
+        }
+    }
+
+    /**
+     * Informs Keystore 2.0 about changing user's password
+     *
+     * @param userId   - Android user id of the user
+     * @param password - a secret derived from the synthetic password provided by the
+     *                 LockSettingService
+     * @return 0 if successful or a {@code ResponseCode}
+     * @hide
+     */
+    public static int onUserPasswordChanged(int userId, @Nullable byte[] password) {
+        if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
+        try {
+            getService().onUserPasswordChanged(userId, password);
+            return 0;
+        } catch (ServiceSpecificException e) {
+            Log.e(TAG, "onUserPasswordChanged failed", e);
+            return e.errorCode;
+        } catch (Exception e) {
+            Log.e(TAG, "Can not connect to keystore", e);
+            return SYSTEM_ERROR;
+        }
+    }
+
+    /**
+     * Informs Keystore 2.0 that an app was uninstalled and the corresponding namspace is to
+     * be cleared.
+     */
+    public static int clearNamespace(@Domain int domain, long namespace) {
+        if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
+        try {
+            getService().clearNamespace(domain, namespace);
+            return 0;
+        } catch (ServiceSpecificException e) {
+            Log.e(TAG, "clearNamespace failed", e);
+            return e.errorCode;
+        } catch (Exception e) {
+            Log.e(TAG, "Can not connect to keystore", e);
+            return SYSTEM_ERROR;
+        }
+    }
+}
diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/Authorization.java
index 21d23b1..50a9082 100644
--- a/keystore/java/android/security/Authorization.java
+++ b/keystore/java/android/security/Authorization.java
@@ -33,20 +33,12 @@
  */
 public class Authorization {
     private static final String TAG = "KeystoreAuthorization";
-    private static IKeystoreAuthorization sIKeystoreAuthorization;
 
     public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR;
 
-    public Authorization() {
-        sIKeystoreAuthorization = null;
-    }
-
-    private static synchronized IKeystoreAuthorization getService() {
-        if (sIKeystoreAuthorization == null) {
-            sIKeystoreAuthorization = IKeystoreAuthorization.Stub.asInterface(
+    private static IKeystoreAuthorization getService() {
+        return IKeystoreAuthorization.Stub.asInterface(
                     ServiceManager.checkService("android.security.authorization"));
-        }
-        return sIKeystoreAuthorization;
     }
 
     /**
@@ -55,12 +47,12 @@
      * @param authToken created by Android authenticators.
      * @return 0 if successful or {@code ResponseCode.SYSTEM_ERROR}.
      */
-    public int addAuthToken(@NonNull HardwareAuthToken authToken) {
+    public static int addAuthToken(@NonNull HardwareAuthToken authToken) {
         if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
         try {
             getService().addAuthToken(authToken);
             return 0;
-        } catch (RemoteException e) {
+        } catch (RemoteException | NullPointerException e) {
             Log.w(TAG, "Can not connect to keystore", e);
             return SYSTEM_ERROR;
         } catch (ServiceSpecificException e) {
@@ -73,7 +65,7 @@
      * @param authToken
      * @return 0 if successful or a {@code ResponseCode}.
      */
-    public int addAuthToken(@NonNull byte[] authToken) {
+    public static int addAuthToken(@NonNull byte[] authToken) {
         return addAuthToken(AuthTokenUtils.toHardwareAuthToken(authToken));
     }
 
@@ -86,7 +78,7 @@
      *
      * @return 0 if successful or a {@code ResponseCode}.
      */
-    public int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId,
+    public static int onLockScreenEvent(@NonNull boolean locked, @NonNull int userId,
             @Nullable byte[] syntheticPassword) {
         if (!android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) return 0;
         try {
@@ -96,7 +88,7 @@
                 getService().onLockScreenEvent(LockScreenEvent.UNLOCK, userId, syntheticPassword);
             }
             return 0;
-        } catch (RemoteException e) {
+        } catch (RemoteException | NullPointerException e) {
             Log.w(TAG, "Can not connect to keystore", e);
             return SYSTEM_ERROR;
         } catch (ServiceSpecificException e) {
diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl
index f708298..d00f5f6 100644
--- a/keystore/java/android/security/IKeyChainService.aidl
+++ b/keystore/java/android/security/IKeyChainService.aidl
@@ -37,8 +37,6 @@
     void setUserSelectable(String alias, boolean isUserSelectable);
 
     int generateKeyPair(in String algorithm, in ParcelableKeyGenParameterSpec spec);
-    int attestKey(in String alias, in byte[] challenge, in int[] idAttestationFlags,
-            out KeymasterCertificateChain chain);
     boolean setKeyPairCertificate(String alias, in byte[] userCert, in byte[] certChain);
 
     // APIs used by CertInstaller and DevicePolicyManager
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 63690d3..d59ca98 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -40,6 +40,8 @@
 import android.security.keystore.AndroidKeyStoreProvider;
 import android.security.keystore.KeyPermanentlyInvalidatedException;
 import android.security.keystore.KeyProperties;
+import android.system.keystore2.Domain;
+import android.system.keystore2.KeyDescriptor;
 
 import com.android.org.conscrypt.TrustedCertificateStore;
 
@@ -622,6 +624,33 @@
         return null;
     }
 
+    /**
+     * This prefix is used to disambiguate grant aliase strings from normal key alias strings.
+     * Technically, a key alias string can use the same prefix. However, a collision does not
+     * lead to privilege escalation, because grants are access controlled in the Keystore daemon.
+     * @hide
+     */
+    public static final String GRANT_ALIAS_PREFIX = "ks2_keychain_grant_id:";
+
+    private static KeyDescriptor getGrantDescriptor(String keyid) {
+        KeyDescriptor result = new KeyDescriptor();
+        result.domain = Domain.GRANT;
+        result.blob = null;
+        result.alias = null;
+        try {
+            result.nspace = Long.parseUnsignedLong(
+                    keyid.substring(GRANT_ALIAS_PREFIX.length()), 16 /* radix */);
+        } catch (NumberFormatException e) {
+            return null;
+        }
+        return result;
+    }
+
+    /** @hide */
+    public static String getGrantString(KeyDescriptor key) {
+        return String.format(GRANT_ALIAS_PREFIX + "%016X", key.nspace);
+    }
+
     /** @hide */
     @Nullable @WorkerThread
     public static KeyPair getKeyPair(@NonNull Context context, @NonNull String alias)
@@ -645,11 +674,23 @@
 
         if (keyId == null) {
             return null;
+        }
+
+        if (AndroidKeyStoreProvider.isKeystore2Enabled()) {
+            try {
+                return android.security.keystore2.AndroidKeyStoreProvider
+                        .loadAndroidKeyStoreKeyPairFromKeystore(
+                                KeyStore2.getInstance(),
+                                getGrantDescriptor(keyId));
+            } catch (UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
+                throw new KeyChainException(e);
+            }
         } else {
             try {
                 return AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(
                         KeyStore.getInstance(), keyId, KeyStore.UID_SELF);
-            } catch (RuntimeException | UnrecoverableKeyException | KeyPermanentlyInvalidatedException e) {
+            } catch (RuntimeException | UnrecoverableKeyException
+                    | KeyPermanentlyInvalidatedException e) {
                 throw new KeyChainException(e);
             }
         }
@@ -767,11 +808,8 @@
     @Deprecated
     public static boolean isBoundKeyAlgorithm(
             @NonNull @KeyProperties.KeyAlgorithmEnum String algorithm) {
-        if (!isKeyAlgorithmSupported(algorithm)) {
-            return false;
-        }
-
-        return KeyStore.getInstance().isHardwareBacked(algorithm);
+        // All supported algorithms are hardware backed. Individual keys may not be.
+        return true;
     }
 
     /** @hide */
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index e19d88c..93658e6 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -43,6 +43,7 @@
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeystoreResponse;
 import android.security.keystore.UserNotAuthenticatedException;
+import android.system.keystore2.Domain;
 import android.util.Log;
 
 import com.android.internal.org.bouncycastle.asn1.ASN1InputStream;
@@ -466,6 +467,9 @@
 
     public boolean clearUid(int uid) {
         try {
+            if (android.security.keystore2.AndroidKeyStoreProvider.isInstalled()) {
+                return AndroidKeyStoreMaintenance.clearNamespace(Domain.APP, uid) == 0;
+            }
             return mBinder.clear_uid(uid) == NO_ERROR;
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
@@ -996,7 +1000,7 @@
      */
     public int addAuthToken(byte[] authToken) {
         try {
-            new Authorization().addAuthToken(authToken);
+            Authorization.addAuthToken(authToken);
             return mBinder.addAuthToken(authToken);
         } catch (RemoteException e) {
             Log.w(TAG, "Cannot connect to keystore", e);
diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java
index f7477bf..6ac3821 100644
--- a/keystore/java/android/security/KeyStore2.java
+++ b/keystore/java/android/security/KeyStore2.java
@@ -24,6 +24,7 @@
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
 import android.security.keymaster.KeymasterDefs;
+import android.system.keystore2.Domain;
 import android.system.keystore2.IKeystoreService;
 import android.system.keystore2.KeyDescriptor;
 import android.system.keystore2.KeyEntryResponse;
@@ -107,7 +108,6 @@
             try {
                 return request.execute(service);
             } catch (ServiceSpecificException e) {
-                Log.e(TAG, "KeyStore exception", e);
                 throw getKeyStoreException(e.errorCode);
             } catch (RemoteException e) {
                 if (firstTry) {
@@ -158,6 +158,50 @@
     }
 
     /**
+     * Grant string prefix as used by the keystore boringssl engine. Must be kept in sync
+     * with system/security/keystore-engine. Note: The prefix here includes the 0x which
+     * std::stringstream used in keystore-engine needs to identify the number as hex represented.
+     * Here we include it in the prefix, because Long#parseUnsignedLong does not understand it
+     * and gets the radix as explicit argument.
+     * @hide
+     */
+    private static final String KEYSTORE_ENGINE_GRANT_ALIAS_PREFIX =
+            "ks2_keystore-engine_grant_id:0x";
+
+    /**
+     * This function turns a grant identifier into a specific string that is understood by the
+     * keystore-engine in system/security/keystore-engine. Is only used by VPN and WI-FI components
+     * to allow certain system components like racoon or vendor components like WPA supplicant
+     * to use keystore keys with boring ssl.
+     *
+     * @param grantId the grant id as returned by {@link #grant} in the {@code nspace} filed of
+     *                the resulting {@code KeyDescriptor}.
+     * @return The grant descriptor string.
+     * @hide
+     */
+    public static String makeKeystoreEngineGrantString(long grantId) {
+        return String.format("%s%016X", KEYSTORE_ENGINE_GRANT_ALIAS_PREFIX, grantId);
+    }
+
+    /**
+     * Convenience function to turn a keystore engine grant string as returned by
+     * {@link #makeKeystoreEngineGrantString(long)} back into a grant KeyDescriptor.
+     *
+     * @param grantString As string returned by {@link #makeKeystoreEngineGrantString(long)}
+     * @return The grant key descriptor.
+     * @hide
+     */
+    public static KeyDescriptor keystoreEngineGrantString2KeyDescriptor(String grantString) {
+        KeyDescriptor key = new KeyDescriptor();
+        key.domain = Domain.GRANT;
+        key.nspace = Long.parseUnsignedLong(
+                grantString.substring(KEYSTORE_ENGINE_GRANT_ALIAS_PREFIX.length()), 16);
+        key.alias = null;
+        key.blob = null;
+        return key;
+    }
+
+    /**
      * Create a grant that allows the grantee identified by {@code granteeUid} to use
      * the key specified by {@code descriptor} withint the restrictions given by
      * {@code accessVectore}.
diff --git a/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java b/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java
index c20cf01..a6e3366 100644
--- a/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/ParcelableKeyGenParameterSpec.java
@@ -59,7 +59,7 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeString(mSpec.getKeystoreAlias());
         out.writeInt(mSpec.getPurposes());
-        out.writeInt(mSpec.getUid());
+        out.writeInt(mSpec.getNamespace());
         out.writeInt(mSpec.getKeySize());
 
         // Only needs to support RSAKeyGenParameterSpec and ECGenParameterSpec.
@@ -125,7 +125,7 @@
     private ParcelableKeyGenParameterSpec(Parcel in) {
         final String keystoreAlias = in.readString();
         final int purposes = in.readInt();
-        final int uid = in.readInt();
+        final int namespace = in.readInt();
         final int keySize = in.readInt();
 
         final int keySpecType = in.readInt();
@@ -177,7 +177,7 @@
         // KeyGenParameterSpec constructor (whereas using a builder would silently drop them).
         mSpec = new KeyGenParameterSpec(
                 keystoreAlias,
-                uid,
+                namespace,
                 keySize,
                 algorithmSpec,
                 certificateSubject,
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index b3bfd6a..e401add 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -154,7 +154,7 @@
     private KeyGenParameterSpec mSpec;
 
     private String mEntryAlias;
-    private int mEntryUid;
+    private int mEntryNamespace;
     private @KeyProperties.KeyAlgorithmEnum String mJcaKeyAlgorithm;
     private int mKeymasterAlgorithm = -1;
     private int mKeySizeBits;
@@ -218,7 +218,7 @@
             }
 
             mEntryAlias = spec.getKeystoreAlias();
-            mEntryUid = spec.getUid();
+            mEntryNamespace = spec.getNamespace();
             mSpec = spec;
             mKeymasterAlgorithm = keymasterAlgorithm;
             mKeySizeBits = spec.getKeySize();
@@ -439,7 +439,7 @@
 
     private void resetAll() {
         mEntryAlias = null;
-        mEntryUid = KeyProperties.NAMESPACE_APPLICATION;
+        mEntryNamespace = KeyProperties.NAMESPACE_APPLICATION;
         mJcaKeyAlgorithm = null;
         mKeymasterAlgorithm = -1;
         mKeymasterPurposes = null;
@@ -541,10 +541,10 @@
 
         KeyDescriptor descriptor = new KeyDescriptor();
         descriptor.alias = mEntryAlias;
-        descriptor.domain = mEntryUid == KeyProperties.NAMESPACE_APPLICATION
+        descriptor.domain = mEntryNamespace == KeyProperties.NAMESPACE_APPLICATION
                 ? Domain.APP
                 : Domain.SELINUX;
-        descriptor.nspace = mEntryUid;
+        descriptor.nspace = mEntryNamespace;
         descriptor.blob = null;
 
         boolean success = false;
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index e101115..d36695b 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -43,6 +43,7 @@
 
 import javax.crypto.Cipher;
 import javax.crypto.Mac;
+import javax.crypto.SecretKey;
 
 /**
  * A provider focused on providing JCA interfaces for the Android KeyStore.
@@ -273,10 +274,10 @@
     /** @hide **/
     @NonNull
     public static KeyPair loadAndroidKeyStoreKeyPairFromKeystore(
-            @NonNull KeyStore2 keyStore, @NonNull String privateKeyAlias, int namespace)
+            @NonNull KeyStore2 keyStore, @NonNull KeyDescriptor descriptor)
             throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
         AndroidKeyStoreKey key =
-                loadAndroidKeyStoreKeyFromKeystore(keyStore, privateKeyAlias, namespace);
+                loadAndroidKeyStoreKeyFromKeystore(keyStore, descriptor);
         if (key instanceof AndroidKeyStorePublicKey) {
             AndroidKeyStorePublicKey publicKey = (AndroidKeyStorePublicKey) key;
             return new KeyPair(publicKey, publicKey.getPrivateKey());
@@ -299,13 +300,26 @@
         }
     }
 
+    /** @hide **/
+    @NonNull
+    public static SecretKey loadAndroidKeyStoreSecretKeyFromKeystore(
+            @NonNull KeyStore2 keyStore, @NonNull KeyDescriptor descriptor)
+            throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
+
+        AndroidKeyStoreKey key =
+                loadAndroidKeyStoreKeyFromKeystore(keyStore, descriptor);
+        if (key instanceof SecretKey) {
+            return (SecretKey) key;
+        } else {
+            throw new UnrecoverableKeyException("No secret key found by the given alias.");
+        }
+    }
 
     @NonNull
     private static AndroidKeyStoreSecretKey makeAndroidKeyStoreSecretKeyFromKeyEntryResponse(
             @NonNull KeyDescriptor descriptor,
             @NonNull KeyEntryResponse response, int algorithm, int digest)
             throws UnrecoverableKeyException {
-
         @KeyProperties.KeyAlgorithmEnum String keyAlgorithmString;
         try {
             keyAlgorithmString = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm(
@@ -336,8 +350,7 @@
     @NonNull
     public static AndroidKeyStoreKey loadAndroidKeyStoreKeyFromKeystore(
             @NonNull KeyStore2 keyStore, @NonNull String alias, int namespace)
-            throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException  {
-
+            throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
         KeyDescriptor descriptor = new KeyDescriptor();
         if (namespace == KeyProperties.NAMESPACE_APPLICATION) {
             descriptor.nspace = KeyProperties.NAMESPACE_APPLICATION; // ignored;
@@ -348,6 +361,18 @@
         }
         descriptor.alias = alias;
         descriptor.blob = null;
+
+        final AndroidKeyStoreKey key = loadAndroidKeyStoreKeyFromKeystore(keyStore, descriptor);
+        if (key instanceof AndroidKeyStorePublicKey) {
+            return ((AndroidKeyStorePublicKey) key).getPrivateKey();
+        } else {
+            return key;
+        }
+    }
+
+    private static AndroidKeyStoreKey loadAndroidKeyStoreKeyFromKeystore(
+            @NonNull KeyStore2 keyStore, @NonNull KeyDescriptor descriptor)
+            throws UnrecoverableKeyException, KeyPermanentlyInvalidatedException {
         KeyEntryResponse response = null;
         try {
             response = keyStore.getKeyEntry(descriptor);
@@ -397,7 +422,7 @@
                 keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC) {
             return makeAndroidKeyStorePublicKeyFromKeyEntryResponse(descriptor, response.metadata,
                     new KeyStoreSecurityLevel(response.iSecurityLevel),
-                    keymasterAlgorithm).getPrivateKey();
+                    keymasterAlgorithm);
         } else {
             throw new UnrecoverableKeyException("Key algorithm unknown");
         }
diff --git a/libs/androidfw/TEST_MAPPING b/libs/androidfw/TEST_MAPPING
index 777aa0b..766714c 100644
--- a/libs/androidfw/TEST_MAPPING
+++ b/libs/androidfw/TEST_MAPPING
@@ -1,10 +1,6 @@
 {
   "presubmit": [
     {
-      "name": "libandroidfw_tests",
-      "host": true
-    },
-    {
       "name": "CtsResourcesLoaderTests"
     }
   ]
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index fdb278e..6220abe 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -343,12 +343,13 @@
         "libharfbuzz_ng",
         "liblog",
         "libminikin",
-        "libnativehelper",
         "libz",
         "libziparchive",
         "libjpeg",
     ],
 
+    static_libs: ["libnativehelper_lazy"],
+
     target: {
         android: {
             srcs: [ // sources that depend on android only libraries
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index dc467c4..41ecd5e 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -401,10 +401,11 @@
 struct DrawTextBlob final : Op {
     static const auto kType = Type::DrawTextBlob;
     DrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
-            : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint) {}
+        : blob(sk_ref_sp(blob)), x(x), y(y), paint(paint), drawTextBlobMode(gDrawTextBlobMode) {}
     sk_sp<const SkTextBlob> blob;
     SkScalar x, y;
     SkPaint paint;
+    DrawTextBlobMode drawTextBlobMode;
     void draw(SkCanvas* c, const SkMatrix&) const { c->drawTextBlob(blob.get(), x, y, paint); }
 };
 
@@ -791,6 +792,24 @@
     }
 }
 
+template<>
+constexpr color_transform_fn colorTransformForOp<DrawTextBlob>() {
+    return [](const void *opRaw, ColorTransform transform) {
+        const DrawTextBlob *op = reinterpret_cast<const DrawTextBlob*>(opRaw);
+        switch (op->drawTextBlobMode) {
+        case DrawTextBlobMode::HctOutline:
+            const_cast<SkPaint&>(op->paint).setColor(SK_ColorBLACK);
+            break;
+        case DrawTextBlobMode::HctInner:
+            const_cast<SkPaint&>(op->paint).setColor(SK_ColorWHITE);
+            break;
+        default:
+            transformPaint(transform, const_cast<SkPaint*>(&(op->paint)));
+            break;
+        }
+    };
+}
+
 #define X(T) colorTransformForOp<T>(),
 static const color_transform_fn color_transform_fns[] = {
 #include "DisplayListOps.in"
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index c138a32..14906d5 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -111,6 +111,7 @@
             bool darken = channelSum < (128 * 3);
 
             // outline
+            gDrawTextBlobMode = DrawTextBlobMode::HctOutline;
             Paint outlinePaint(paint);
             simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, &outlinePaint);
             outlinePaint.setStyle(SkPaint::kStrokeAndFill_Style);
@@ -118,11 +119,14 @@
                                bounds.mRight, bounds.mBottom, totalAdvance);
 
             // inner
+            gDrawTextBlobMode = DrawTextBlobMode::HctInner;
             Paint innerPaint(paint);
             simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, &innerPaint);
             innerPaint.setStyle(SkPaint::kFill_Style);
             canvas->drawGlyphs(glyphFunc, glyphCount, innerPaint, x, y, bounds.mLeft, bounds.mTop,
                                bounds.mRight, bounds.mBottom, totalAdvance);
+
+            gDrawTextBlobMode = DrawTextBlobMode::Normal;
         } else {
             // standard draw path
             canvas->drawGlyphs(glyphFunc, glyphCount, paint, x, y, bounds.mLeft, bounds.mTop,
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 27dfed3..d992805 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -87,6 +87,14 @@
 class Paint;
 struct Typeface;
 
+enum class DrawTextBlobMode {
+    Normal,
+    HctOutline,
+    HctInner,
+};
+
+inline DrawTextBlobMode gDrawTextBlobMode = DrawTextBlobMode::Normal;
+
 class ANDROID_API Canvas {
 public:
     virtual ~Canvas(){};
diff --git a/media/java/android/media/soundtrigger/OWNERS b/media/java/android/media/soundtrigger/OWNERS
index 6a351d3..e5d0370 100644
--- a/media/java/android/media/soundtrigger/OWNERS
+++ b/media/java/android/media/soundtrigger/OWNERS
@@ -1 +1,2 @@
+ytai@google.com
 elaurent@google.com
diff --git a/media/jni/soundpool/Android.bp b/media/jni/soundpool/Android.bp
index 7b498e0..b3406cd 100644
--- a/media/jni/soundpool/Android.bp
+++ b/media/jni/soundpool/Android.bp
@@ -45,26 +45,30 @@
     "modernize-return-braced-init-list",
     "modernize-shrink-to-fit",
     "modernize-unary-static-assert",
-    "modernize-use-auto",  // debatable - auto can obscure type
+    // "modernize-use-auto",  // found in StreamManager.h, debatable - auto can obscure type
     "modernize-use-bool-literals",
     "modernize-use-default-member-init",
     "modernize-use-emplace",
     "modernize-use-equals-default",
     "modernize-use-equals-delete",
-    "modernize-use-nodiscard",
+    // "modernize-use-nodiscard", // found in SteamManager.h
     "modernize-use-noexcept",
     "modernize-use-nullptr",
     "modernize-use-override",
     //"modernize-use-trailing-return-type", // not necessarily more readable
     "modernize-use-transparent-functors",
     "modernize-use-uncaught-exceptions",
-    "modernize-use-using",
+    //"modernize-use-using", // found in SoundManager.h
     "performance-*",
 
     // Remove some pedantic stylistic requirements.
     "-google-readability-casting", // C++ casts not always necessary and may be verbose
     "-google-readability-todo",    // do not require TODO(info)
     "-google-build-using-namespace", // Reenable and fix later.
+
+    "-google-explicit-constructor", // found in StreamManager.h
+    "-misc-non-private-member-variables-in-classes", // found in SoundManager.h
+    "-performance-unnecessary-value-param", // found in StreamManager.h
 ]
 
 cc_defaults {
@@ -96,8 +100,7 @@
     tidy_checks: tidy_errors,
     tidy_checks_as_errors: tidy_errors,
     tidy_flags: [
-      "-format-style='file'",
-      "--header-filter='frameworks/base/media/jni/soundpool'",
+      "-format-style=file",
     ],
 }
 
diff --git a/packages/Connectivity/framework/Android.bp b/packages/Connectivity/framework/Android.bp
index 3326ea9..9da27d2 100644
--- a/packages/Connectivity/framework/Android.bp
+++ b/packages/Connectivity/framework/Android.bp
@@ -14,7 +14,6 @@
 // limitations under the License.
 //
 
-// TODO: use a java_library in the bootclasspath instead
 package {
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
@@ -24,15 +23,64 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
+// TODO: use a java_library in the bootclasspath instead
 filegroup {
-    name: "framework-connectivity-sources",
+    name: "framework-connectivity-internal-sources",
     srcs: [
         "src/**/*.java",
         "src/**/*.aidl",
     ],
     path: "src",
     visibility: [
+        "//visibility:private",
+    ],
+}
+
+filegroup {
+    name: "framework-connectivity-aidl-export-sources",
+    srcs: [
+        "aidl-export/**/*.aidl",
+    ],
+    path: "aidl-export",
+    visibility: [
+        "//visibility:private",
+    ],
+}
+
+// TODO: use a java_library in the bootclasspath instead
+filegroup {
+    name: "framework-connectivity-sources",
+    srcs: [
+        ":framework-connectivity-internal-sources",
+        ":framework-connectivity-aidl-export-sources",
+    ],
+    visibility: [
         "//frameworks/base",
         "//packages/modules/Connectivity:__subpackages__",
     ],
 }
+
+java_sdk_library {
+    name: "framework-connectivity",
+    api_only: true,
+    defaults: ["framework-module-defaults"],
+    // TODO: build against module API
+    platform_apis: true,
+    srcs: [
+        ":framework-connectivity-sources",
+    ],
+    aidl: {
+        include_dirs: [
+            // Include directories for parcelables that are part of the stable API, and need a
+            // one-line "parcelable X" .aidl declaration to be used in AIDL interfaces.
+            // TODO(b/180293679): remove these dependencies as they should not be necessary once
+            // the module builds against API (the parcelable declarations exist in framework.aidl)
+            "frameworks/base/core/java", // For framework parcelables
+            "frameworks/native/aidl/binder", // For PersistableBundle.aidl
+        ],
+    },
+    libs: [
+        "unsupportedappusage",
+    ],
+    permitted_packages: ["android.net", "com.android.connectivity.aidl"],
+}
diff --git a/packages/Connectivity/framework/src/android/net/CaptivePortalData.aidl b/packages/Connectivity/framework/aidl-export/android/net/CaptivePortalData.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/CaptivePortalData.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/CaptivePortalData.aidl
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.aidl b/packages/Connectivity/framework/aidl-export/android/net/ConnectivityDiagnosticsManager.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/ConnectivityDiagnosticsManager.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/ConnectivityDiagnosticsManager.aidl
diff --git a/packages/Connectivity/framework/src/android/net/DhcpInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/DhcpInfo.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/DhcpInfo.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/DhcpInfo.aidl
diff --git a/packages/Connectivity/framework/src/android/net/IpConfiguration.aidl b/packages/Connectivity/framework/aidl-export/android/net/IpConfiguration.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/IpConfiguration.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/IpConfiguration.aidl
diff --git a/packages/Connectivity/framework/src/android/net/IpPrefix.aidl b/packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/IpPrefix.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/IpPrefix.aidl
diff --git a/packages/Connectivity/framework/src/android/net/KeepalivePacketData.aidl b/packages/Connectivity/framework/aidl-export/android/net/KeepalivePacketData.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/KeepalivePacketData.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/KeepalivePacketData.aidl
diff --git a/packages/Connectivity/framework/src/android/net/LinkAddress.aidl b/packages/Connectivity/framework/aidl-export/android/net/LinkAddress.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/LinkAddress.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/LinkAddress.aidl
diff --git a/packages/Connectivity/framework/src/android/net/LinkProperties.aidl b/packages/Connectivity/framework/aidl-export/android/net/LinkProperties.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/LinkProperties.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/LinkProperties.aidl
diff --git a/packages/Connectivity/framework/src/android/net/MacAddress.aidl b/packages/Connectivity/framework/aidl-export/android/net/MacAddress.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/MacAddress.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/MacAddress.aidl
diff --git a/packages/Connectivity/framework/src/android/net/Network.aidl b/packages/Connectivity/framework/aidl-export/android/net/Network.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/Network.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/Network.aidl
diff --git a/packages/Connectivity/framework/src/android/net/NetworkAgentConfig.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkAgentConfig.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/NetworkAgentConfig.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/NetworkAgentConfig.aidl
diff --git a/packages/Connectivity/framework/src/android/net/NetworkCapabilities.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkCapabilities.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/NetworkCapabilities.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/NetworkCapabilities.aidl
diff --git a/packages/Connectivity/framework/src/android/net/NetworkInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkInfo.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/NetworkInfo.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/NetworkInfo.aidl
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.aidl b/packages/Connectivity/framework/aidl-export/android/net/NetworkRequest.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/NetworkRequest.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/NetworkRequest.aidl
diff --git a/packages/Connectivity/framework/src/android/net/ProxyInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/ProxyInfo.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/ProxyInfo.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/ProxyInfo.aidl
diff --git a/packages/Connectivity/framework/src/android/net/RouteInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/RouteInfo.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/RouteInfo.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/RouteInfo.aidl
diff --git a/packages/Connectivity/framework/src/android/net/StaticIpConfiguration.aidl b/packages/Connectivity/framework/aidl-export/android/net/StaticIpConfiguration.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/StaticIpConfiguration.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/StaticIpConfiguration.aidl
diff --git a/packages/Connectivity/framework/src/android/net/TestNetworkInterface.aidl b/packages/Connectivity/framework/aidl-export/android/net/TestNetworkInterface.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/TestNetworkInterface.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/TestNetworkInterface.aidl
diff --git a/packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.aidl b/packages/Connectivity/framework/aidl-export/android/net/apf/ApfCapabilities.aidl
similarity index 100%
rename from packages/Connectivity/framework/src/android/net/apf/ApfCapabilities.aidl
rename to packages/Connectivity/framework/aidl-export/android/net/apf/ApfCapabilities.aidl
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
new file mode 100644
index 0000000..d4262a8
--- /dev/null
+++ b/packages/Connectivity/framework/api/current.txt
@@ -0,0 +1,469 @@
+// Signature format: 2.0
+package android.net {
+
+  public class CaptivePortal implements android.os.Parcelable {
+    method public int describeContents();
+    method public void ignoreNetwork();
+    method public void reportCaptivePortalDismissed();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortal> CREATOR;
+  }
+
+  public class ConnectivityDiagnosticsManager {
+    method public void registerConnectivityDiagnosticsCallback(@NonNull android.net.NetworkRequest, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback);
+    method public void unregisterConnectivityDiagnosticsCallback(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback);
+  }
+
+  public abstract static class ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback {
+    ctor public ConnectivityDiagnosticsManager.ConnectivityDiagnosticsCallback();
+    method public void onConnectivityReportAvailable(@NonNull android.net.ConnectivityDiagnosticsManager.ConnectivityReport);
+    method public void onDataStallSuspected(@NonNull android.net.ConnectivityDiagnosticsManager.DataStallReport);
+    method public void onNetworkConnectivityReported(@NonNull android.net.Network, boolean);
+  }
+
+  public static final class ConnectivityDiagnosticsManager.ConnectivityReport implements android.os.Parcelable {
+    ctor public ConnectivityDiagnosticsManager.ConnectivityReport(@NonNull android.net.Network, long, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkCapabilities, @NonNull android.os.PersistableBundle);
+    method public int describeContents();
+    method @NonNull public android.os.PersistableBundle getAdditionalInfo();
+    method @NonNull public android.net.LinkProperties getLinkProperties();
+    method @NonNull public android.net.Network getNetwork();
+    method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
+    method public long getReportTimestamp();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.ConnectivityDiagnosticsManager.ConnectivityReport> CREATOR;
+    field public static final String KEY_NETWORK_PROBES_ATTEMPTED_BITMASK = "networkProbesAttempted";
+    field public static final String KEY_NETWORK_PROBES_SUCCEEDED_BITMASK = "networkProbesSucceeded";
+    field public static final String KEY_NETWORK_VALIDATION_RESULT = "networkValidationResult";
+    field public static final int NETWORK_PROBE_DNS = 4; // 0x4
+    field public static final int NETWORK_PROBE_FALLBACK = 32; // 0x20
+    field public static final int NETWORK_PROBE_HTTP = 8; // 0x8
+    field public static final int NETWORK_PROBE_HTTPS = 16; // 0x10
+    field public static final int NETWORK_PROBE_PRIVATE_DNS = 64; // 0x40
+    field public static final int NETWORK_VALIDATION_RESULT_INVALID = 0; // 0x0
+    field public static final int NETWORK_VALIDATION_RESULT_PARTIALLY_VALID = 2; // 0x2
+    field public static final int NETWORK_VALIDATION_RESULT_SKIPPED = 3; // 0x3
+    field public static final int NETWORK_VALIDATION_RESULT_VALID = 1; // 0x1
+  }
+
+  public static final class ConnectivityDiagnosticsManager.DataStallReport implements android.os.Parcelable {
+    ctor public ConnectivityDiagnosticsManager.DataStallReport(@NonNull android.net.Network, long, int, @NonNull android.net.LinkProperties, @NonNull android.net.NetworkCapabilities, @NonNull android.os.PersistableBundle);
+    method public int describeContents();
+    method public int getDetectionMethod();
+    method @NonNull public android.net.LinkProperties getLinkProperties();
+    method @NonNull public android.net.Network getNetwork();
+    method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
+    method public long getReportTimestamp();
+    method @NonNull public android.os.PersistableBundle getStallDetails();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.ConnectivityDiagnosticsManager.DataStallReport> CREATOR;
+    field public static final int DETECTION_METHOD_DNS_EVENTS = 1; // 0x1
+    field public static final int DETECTION_METHOD_TCP_METRICS = 2; // 0x2
+    field public static final String KEY_DNS_CONSECUTIVE_TIMEOUTS = "dnsConsecutiveTimeouts";
+    field public static final String KEY_TCP_METRICS_COLLECTION_PERIOD_MILLIS = "tcpMetricsCollectionPeriodMillis";
+    field public static final String KEY_TCP_PACKET_FAIL_RATE = "tcpPacketFailRate";
+  }
+
+  public class ConnectivityManager {
+    method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
+    method public boolean bindProcessToNetwork(@Nullable android.net.Network);
+    method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network getActiveNetwork();
+    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
+    method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
+    method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
+    method @Deprecated public boolean getBackgroundDataSetting();
+    method @Nullable public android.net.Network getBoundNetworkForProcess();
+    method public int getConnectionOwnerUid(int, @NonNull java.net.InetSocketAddress, @NonNull java.net.InetSocketAddress);
+    method @Nullable public android.net.ProxyInfo getDefaultProxy();
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.LinkProperties getLinkProperties(@Nullable android.net.Network);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getMultipathPreference(@Nullable android.net.Network);
+    method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkCapabilities getNetworkCapabilities(@Nullable android.net.Network);
+    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(int);
+    method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(@Nullable android.net.Network);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getNetworkPreference();
+    method @Nullable public byte[] getNetworkWatchlistConfigHash();
+    method @Deprecated @Nullable public static android.net.Network getProcessDefaultNetwork();
+    method public int getRestrictBackgroundStatus();
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public boolean isActiveNetworkMetered();
+    method public boolean isDefaultNetworkActive();
+    method @Deprecated public static boolean isNetworkTypeValid(int);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
+    method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerNetworkCallback(@NonNull android.net.NetworkRequest, @NonNull android.app.PendingIntent);
+    method public void releaseNetworkRequest(@NonNull android.app.PendingIntent);
+    method public void removeDefaultNetworkActiveListener(@NonNull android.net.ConnectivityManager.OnNetworkActiveListener);
+    method @Deprecated public void reportBadNetwork(@Nullable android.net.Network);
+    method public void reportNetworkConnectivity(@Nullable android.net.Network, boolean);
+    method public boolean requestBandwidthUpdate(@NonNull android.net.Network);
+    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback);
+    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
+    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, int);
+    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler, int);
+    method public void requestNetwork(@NonNull android.net.NetworkRequest, @NonNull android.app.PendingIntent);
+    method @Deprecated public void setNetworkPreference(int);
+    method @Deprecated public static boolean setProcessDefaultNetwork(@Nullable android.net.Network);
+    method public void unregisterNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback);
+    method public void unregisterNetworkCallback(@NonNull android.app.PendingIntent);
+    field @Deprecated public static final String ACTION_BACKGROUND_DATA_SETTING_CHANGED = "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED";
+    field public static final String ACTION_CAPTIVE_PORTAL_SIGN_IN = "android.net.conn.CAPTIVE_PORTAL";
+    field public static final String ACTION_RESTRICT_BACKGROUND_CHANGED = "android.net.conn.RESTRICT_BACKGROUND_CHANGED";
+    field @Deprecated public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
+    field @Deprecated public static final int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
+    field public static final String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
+    field public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
+    field @Deprecated public static final String EXTRA_EXTRA_INFO = "extraInfo";
+    field @Deprecated public static final String EXTRA_IS_FAILOVER = "isFailover";
+    field public static final String EXTRA_NETWORK = "android.net.extra.NETWORK";
+    field @Deprecated public static final String EXTRA_NETWORK_INFO = "networkInfo";
+    field public static final String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
+    field @Deprecated public static final String EXTRA_NETWORK_TYPE = "networkType";
+    field public static final String EXTRA_NO_CONNECTIVITY = "noConnectivity";
+    field @Deprecated public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
+    field public static final String EXTRA_REASON = "reason";
+    field public static final int MULTIPATH_PREFERENCE_HANDOVER = 1; // 0x1
+    field public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 4; // 0x4
+    field public static final int MULTIPATH_PREFERENCE_RELIABILITY = 2; // 0x2
+    field public static final int RESTRICT_BACKGROUND_STATUS_DISABLED = 1; // 0x1
+    field public static final int RESTRICT_BACKGROUND_STATUS_ENABLED = 3; // 0x3
+    field public static final int RESTRICT_BACKGROUND_STATUS_WHITELISTED = 2; // 0x2
+    field @Deprecated public static final int TYPE_BLUETOOTH = 7; // 0x7
+    field @Deprecated public static final int TYPE_DUMMY = 8; // 0x8
+    field @Deprecated public static final int TYPE_ETHERNET = 9; // 0x9
+    field @Deprecated public static final int TYPE_MOBILE = 0; // 0x0
+    field @Deprecated public static final int TYPE_MOBILE_DUN = 4; // 0x4
+    field @Deprecated public static final int TYPE_MOBILE_HIPRI = 5; // 0x5
+    field @Deprecated public static final int TYPE_MOBILE_MMS = 2; // 0x2
+    field @Deprecated public static final int TYPE_MOBILE_SUPL = 3; // 0x3
+    field @Deprecated public static final int TYPE_VPN = 17; // 0x11
+    field @Deprecated public static final int TYPE_WIFI = 1; // 0x1
+    field @Deprecated public static final int TYPE_WIMAX = 6; // 0x6
+  }
+
+  public static class ConnectivityManager.NetworkCallback {
+    ctor public ConnectivityManager.NetworkCallback();
+    method public void onAvailable(@NonNull android.net.Network);
+    method public void onBlockedStatusChanged(@NonNull android.net.Network, boolean);
+    method public void onCapabilitiesChanged(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities);
+    method public void onLinkPropertiesChanged(@NonNull android.net.Network, @NonNull android.net.LinkProperties);
+    method public void onLosing(@NonNull android.net.Network, int);
+    method public void onLost(@NonNull android.net.Network);
+    method public void onUnavailable();
+  }
+
+  public static interface ConnectivityManager.OnNetworkActiveListener {
+    method public void onNetworkActive();
+  }
+
+  public class DhcpInfo implements android.os.Parcelable {
+    ctor public DhcpInfo();
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.DhcpInfo> CREATOR;
+    field public int dns1;
+    field public int dns2;
+    field public int gateway;
+    field public int ipAddress;
+    field public int leaseDuration;
+    field public int netmask;
+    field public int serverAddress;
+  }
+
+  public final class DnsResolver {
+    method @NonNull public static android.net.DnsResolver getInstance();
+    method public void query(@Nullable android.net.Network, @NonNull String, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
+    method public void query(@Nullable android.net.Network, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super java.util.List<java.net.InetAddress>>);
+    method public void rawQuery(@Nullable android.net.Network, @NonNull byte[], int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
+    method public void rawQuery(@Nullable android.net.Network, @NonNull String, int, int, int, @NonNull java.util.concurrent.Executor, @Nullable android.os.CancellationSignal, @NonNull android.net.DnsResolver.Callback<? super byte[]>);
+    field public static final int CLASS_IN = 1; // 0x1
+    field public static final int ERROR_PARSE = 0; // 0x0
+    field public static final int ERROR_SYSTEM = 1; // 0x1
+    field public static final int FLAG_EMPTY = 0; // 0x0
+    field public static final int FLAG_NO_CACHE_LOOKUP = 4; // 0x4
+    field public static final int FLAG_NO_CACHE_STORE = 2; // 0x2
+    field public static final int FLAG_NO_RETRY = 1; // 0x1
+    field public static final int TYPE_A = 1; // 0x1
+    field public static final int TYPE_AAAA = 28; // 0x1c
+  }
+
+  public static interface DnsResolver.Callback<T> {
+    method public void onAnswer(@NonNull T, int);
+    method public void onError(@NonNull android.net.DnsResolver.DnsException);
+  }
+
+  public static class DnsResolver.DnsException extends java.lang.Exception {
+    field public final int code;
+  }
+
+  public class InetAddresses {
+    method public static boolean isNumericAddress(@NonNull String);
+    method @NonNull public static java.net.InetAddress parseNumericAddress(@NonNull String);
+  }
+
+  public final class IpPrefix implements android.os.Parcelable {
+    method public boolean contains(@NonNull java.net.InetAddress);
+    method public int describeContents();
+    method @NonNull public java.net.InetAddress getAddress();
+    method @IntRange(from=0, to=128) public int getPrefixLength();
+    method @NonNull public byte[] getRawAddress();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
+  }
+
+  public class LinkAddress implements android.os.Parcelable {
+    method public int describeContents();
+    method public java.net.InetAddress getAddress();
+    method public int getFlags();
+    method @IntRange(from=0, to=128) public int getPrefixLength();
+    method public int getScope();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkAddress> CREATOR;
+  }
+
+  public final class LinkProperties implements android.os.Parcelable {
+    ctor public LinkProperties();
+    method public boolean addRoute(@NonNull android.net.RouteInfo);
+    method public void clear();
+    method public int describeContents();
+    method @Nullable public java.net.Inet4Address getDhcpServerAddress();
+    method @NonNull public java.util.List<java.net.InetAddress> getDnsServers();
+    method @Nullable public String getDomains();
+    method @Nullable public android.net.ProxyInfo getHttpProxy();
+    method @Nullable public String getInterfaceName();
+    method @NonNull public java.util.List<android.net.LinkAddress> getLinkAddresses();
+    method public int getMtu();
+    method @Nullable public android.net.IpPrefix getNat64Prefix();
+    method @Nullable public String getPrivateDnsServerName();
+    method @NonNull public java.util.List<android.net.RouteInfo> getRoutes();
+    method public boolean isPrivateDnsActive();
+    method public boolean isWakeOnLanSupported();
+    method public void setDhcpServerAddress(@Nullable java.net.Inet4Address);
+    method public void setDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
+    method public void setDomains(@Nullable String);
+    method public void setHttpProxy(@Nullable android.net.ProxyInfo);
+    method public void setInterfaceName(@Nullable String);
+    method public void setLinkAddresses(@NonNull java.util.Collection<android.net.LinkAddress>);
+    method public void setMtu(int);
+    method public void setNat64Prefix(@Nullable android.net.IpPrefix);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.LinkProperties> CREATOR;
+  }
+
+  public final class MacAddress implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public static android.net.MacAddress fromBytes(@NonNull byte[]);
+    method @NonNull public static android.net.MacAddress fromString(@NonNull String);
+    method public int getAddressType();
+    method @Nullable public java.net.Inet6Address getLinkLocalIpv6FromEui48Mac();
+    method public boolean isLocallyAssigned();
+    method public boolean matches(@NonNull android.net.MacAddress, @NonNull android.net.MacAddress);
+    method @NonNull public byte[] toByteArray();
+    method @NonNull public String toOuiString();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.net.MacAddress BROADCAST_ADDRESS;
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.MacAddress> CREATOR;
+    field public static final int TYPE_BROADCAST = 3; // 0x3
+    field public static final int TYPE_MULTICAST = 2; // 0x2
+    field public static final int TYPE_UNICAST = 1; // 0x1
+  }
+
+  public class Network implements android.os.Parcelable {
+    method public void bindSocket(java.net.DatagramSocket) throws java.io.IOException;
+    method public void bindSocket(java.net.Socket) throws java.io.IOException;
+    method public void bindSocket(java.io.FileDescriptor) throws java.io.IOException;
+    method public int describeContents();
+    method public static android.net.Network fromNetworkHandle(long);
+    method public java.net.InetAddress[] getAllByName(String) throws java.net.UnknownHostException;
+    method public java.net.InetAddress getByName(String) throws java.net.UnknownHostException;
+    method public long getNetworkHandle();
+    method public javax.net.SocketFactory getSocketFactory();
+    method public java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
+    method public java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException;
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.Network> CREATOR;
+  }
+
+  public final class NetworkCapabilities implements android.os.Parcelable {
+    ctor public NetworkCapabilities();
+    ctor public NetworkCapabilities(android.net.NetworkCapabilities);
+    method public int describeContents();
+    method public int getLinkDownstreamBandwidthKbps();
+    method public int getLinkUpstreamBandwidthKbps();
+    method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
+    method public int getOwnerUid();
+    method public int getSignalStrength();
+    method @Nullable public android.net.TransportInfo getTransportInfo();
+    method public boolean hasCapability(int);
+    method public boolean hasTransport(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
+    field public static final int NET_CAPABILITY_CAPTIVE_PORTAL = 17; // 0x11
+    field public static final int NET_CAPABILITY_CBS = 5; // 0x5
+    field public static final int NET_CAPABILITY_DUN = 2; // 0x2
+    field public static final int NET_CAPABILITY_EIMS = 10; // 0xa
+    field public static final int NET_CAPABILITY_FOREGROUND = 19; // 0x13
+    field public static final int NET_CAPABILITY_FOTA = 3; // 0x3
+    field public static final int NET_CAPABILITY_IA = 7; // 0x7
+    field public static final int NET_CAPABILITY_IMS = 4; // 0x4
+    field public static final int NET_CAPABILITY_INTERNET = 12; // 0xc
+    field public static final int NET_CAPABILITY_MCX = 23; // 0x17
+    field public static final int NET_CAPABILITY_MMS = 0; // 0x0
+    field public static final int NET_CAPABILITY_NOT_CONGESTED = 20; // 0x14
+    field public static final int NET_CAPABILITY_NOT_METERED = 11; // 0xb
+    field public static final int NET_CAPABILITY_NOT_RESTRICTED = 13; // 0xd
+    field public static final int NET_CAPABILITY_NOT_ROAMING = 18; // 0x12
+    field public static final int NET_CAPABILITY_NOT_SUSPENDED = 21; // 0x15
+    field public static final int NET_CAPABILITY_NOT_VPN = 15; // 0xf
+    field public static final int NET_CAPABILITY_RCS = 8; // 0x8
+    field public static final int NET_CAPABILITY_SUPL = 1; // 0x1
+    field public static final int NET_CAPABILITY_TEMPORARILY_NOT_METERED = 25; // 0x19
+    field public static final int NET_CAPABILITY_TRUSTED = 14; // 0xe
+    field public static final int NET_CAPABILITY_VALIDATED = 16; // 0x10
+    field public static final int NET_CAPABILITY_WIFI_P2P = 6; // 0x6
+    field public static final int NET_CAPABILITY_XCAP = 9; // 0x9
+    field public static final int SIGNAL_STRENGTH_UNSPECIFIED = -2147483648; // 0x80000000
+    field public static final int TRANSPORT_BLUETOOTH = 2; // 0x2
+    field public static final int TRANSPORT_CELLULAR = 0; // 0x0
+    field public static final int TRANSPORT_ETHERNET = 3; // 0x3
+    field public static final int TRANSPORT_LOWPAN = 6; // 0x6
+    field public static final int TRANSPORT_VPN = 4; // 0x4
+    field public static final int TRANSPORT_WIFI = 1; // 0x1
+    field public static final int TRANSPORT_WIFI_AWARE = 5; // 0x5
+  }
+
+  @Deprecated public class NetworkInfo implements android.os.Parcelable {
+    ctor @Deprecated public NetworkInfo(int, int, @Nullable String, @Nullable String);
+    method @Deprecated public int describeContents();
+    method @Deprecated @NonNull public android.net.NetworkInfo.DetailedState getDetailedState();
+    method @Deprecated public String getExtraInfo();
+    method @Deprecated public String getReason();
+    method @Deprecated public android.net.NetworkInfo.State getState();
+    method @Deprecated public int getSubtype();
+    method @Deprecated public String getSubtypeName();
+    method @Deprecated public int getType();
+    method @Deprecated public String getTypeName();
+    method @Deprecated public boolean isAvailable();
+    method @Deprecated public boolean isConnected();
+    method @Deprecated public boolean isConnectedOrConnecting();
+    method @Deprecated public boolean isFailover();
+    method @Deprecated public boolean isRoaming();
+    method @Deprecated public void setDetailedState(@NonNull android.net.NetworkInfo.DetailedState, @Nullable String, @Nullable String);
+    method @Deprecated public void writeToParcel(android.os.Parcel, int);
+    field @Deprecated @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
+  }
+
+  @Deprecated public enum NetworkInfo.DetailedState {
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState AUTHENTICATING;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState BLOCKED;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CAPTIVE_PORTAL_CHECK;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CONNECTED;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState CONNECTING;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState DISCONNECTED;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState DISCONNECTING;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState FAILED;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState IDLE;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState OBTAINING_IPADDR;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState SCANNING;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState SUSPENDED;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.DetailedState VERIFYING_POOR_LINK;
+  }
+
+  @Deprecated public enum NetworkInfo.State {
+    enum_constant @Deprecated public static final android.net.NetworkInfo.State CONNECTED;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.State CONNECTING;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.State DISCONNECTED;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.State DISCONNECTING;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.State SUSPENDED;
+    enum_constant @Deprecated public static final android.net.NetworkInfo.State UNKNOWN;
+  }
+
+  public class NetworkRequest implements android.os.Parcelable {
+    method public boolean canBeSatisfiedBy(@Nullable android.net.NetworkCapabilities);
+    method public int describeContents();
+    method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
+    method public boolean hasCapability(int);
+    method public boolean hasTransport(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkRequest> CREATOR;
+  }
+
+  public static class NetworkRequest.Builder {
+    ctor public NetworkRequest.Builder();
+    method public android.net.NetworkRequest.Builder addCapability(int);
+    method public android.net.NetworkRequest.Builder addTransportType(int);
+    method public android.net.NetworkRequest build();
+    method @NonNull public android.net.NetworkRequest.Builder clearCapabilities();
+    method public android.net.NetworkRequest.Builder removeCapability(int);
+    method public android.net.NetworkRequest.Builder removeTransportType(int);
+    method @Deprecated public android.net.NetworkRequest.Builder setNetworkSpecifier(String);
+    method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
+  }
+
+  public final class Proxy {
+    ctor public Proxy();
+    method @Deprecated public static String getDefaultHost();
+    method @Deprecated public static int getDefaultPort();
+    method @Deprecated public static String getHost(android.content.Context);
+    method @Deprecated public static int getPort(android.content.Context);
+    field @Deprecated public static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
+    field public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
+  }
+
+  public class ProxyInfo implements android.os.Parcelable {
+    ctor public ProxyInfo(@Nullable android.net.ProxyInfo);
+    method public static android.net.ProxyInfo buildDirectProxy(String, int);
+    method public static android.net.ProxyInfo buildDirectProxy(String, int, java.util.List<java.lang.String>);
+    method public static android.net.ProxyInfo buildPacProxy(android.net.Uri);
+    method @NonNull public static android.net.ProxyInfo buildPacProxy(@NonNull android.net.Uri, int);
+    method public int describeContents();
+    method public String[] getExclusionList();
+    method public String getHost();
+    method public android.net.Uri getPacFileUrl();
+    method public int getPort();
+    method public boolean isValid();
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.ProxyInfo> CREATOR;
+  }
+
+  public final class RouteInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method @NonNull public android.net.IpPrefix getDestination();
+    method @Nullable public java.net.InetAddress getGateway();
+    method @Nullable public String getInterface();
+    method public boolean hasGateway();
+    method public boolean isDefaultRoute();
+    method public boolean matches(java.net.InetAddress);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.RouteInfo> CREATOR;
+  }
+
+  public abstract class SocketKeepalive implements java.lang.AutoCloseable {
+    method public final void close();
+    method public final void start(@IntRange(from=0xa, to=0xe10) int);
+    method public final void stop();
+    field public static final int ERROR_HARDWARE_ERROR = -31; // 0xffffffe1
+    field public static final int ERROR_INSUFFICIENT_RESOURCES = -32; // 0xffffffe0
+    field public static final int ERROR_INVALID_INTERVAL = -24; // 0xffffffe8
+    field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
+    field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
+    field public static final int ERROR_INVALID_NETWORK = -20; // 0xffffffec
+    field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
+    field public static final int ERROR_INVALID_SOCKET = -25; // 0xffffffe7
+    field public static final int ERROR_SOCKET_NOT_IDLE = -26; // 0xffffffe6
+    field public static final int ERROR_UNSUPPORTED = -30; // 0xffffffe2
+  }
+
+  public static class SocketKeepalive.Callback {
+    ctor public SocketKeepalive.Callback();
+    method public void onDataReceived();
+    method public void onError(int);
+    method public void onStarted();
+    method public void onStopped();
+  }
+
+  public interface TransportInfo {
+  }
+
+}
+
diff --git a/packages/Connectivity/framework/api/lint-baseline.txt b/packages/Connectivity/framework/api/lint-baseline.txt
new file mode 100644
index 0000000..2f4004a
--- /dev/null
+++ b/packages/Connectivity/framework/api/lint-baseline.txt
@@ -0,0 +1,4 @@
+// Baseline format: 1.0
+VisiblySynchronized: android.net.NetworkInfo#toString():
+    Internal locks must not be exposed (synchronizing on this or class is still
+    externally observable): method android.net.NetworkInfo.toString()
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
new file mode 100644
index 0000000..3af855e
--- /dev/null
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -0,0 +1,66 @@
+// Signature format: 2.0
+package android.net {
+
+  public final class ConnectivityFrameworkInitializer {
+    method public static void registerServiceWrappers();
+  }
+
+  public class ConnectivityManager {
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void requestBackgroundNetwork(@NonNull android.net.NetworkRequest, @Nullable android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
+  }
+
+  public final class NetworkAgentConfig implements android.os.Parcelable {
+    method @Nullable public String getSubscriberId();
+  }
+
+  public static final class NetworkAgentConfig.Builder {
+    method @NonNull public android.net.NetworkAgentConfig.Builder setSubscriberId(@Nullable String);
+  }
+
+  public final class NetworkCapabilities implements android.os.Parcelable {
+    field public static final int TRANSPORT_TEST = 7; // 0x7
+  }
+
+  public final class Proxy {
+    method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo);
+  }
+
+  public final class TcpRepairWindow {
+    ctor public TcpRepairWindow(int, int, int, int, int, int);
+    field public final int maxWindow;
+    field public final int rcvWnd;
+    field public final int rcvWndScale;
+    field public final int rcvWup;
+    field public final int sndWl1;
+    field public final int sndWnd;
+  }
+
+  public final class TestNetworkInterface implements android.os.Parcelable {
+    ctor public TestNetworkInterface(@NonNull android.os.ParcelFileDescriptor, @NonNull String);
+    method public int describeContents();
+    method @NonNull public android.os.ParcelFileDescriptor getFileDescriptor();
+    method @NonNull public String getInterfaceName();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TestNetworkInterface> CREATOR;
+  }
+
+  public class TestNetworkManager {
+    method @NonNull public android.net.TestNetworkInterface createTapInterface();
+    method @NonNull public android.net.TestNetworkInterface createTunInterface(@NonNull java.util.Collection<android.net.LinkAddress>);
+    method public void setupTestNetwork(@NonNull String, @NonNull android.os.IBinder);
+    method public void teardownTestNetwork(@NonNull android.net.Network);
+    field public static final String TEST_TAP_PREFIX = "testtap";
+  }
+
+  public final class VpnTransportInfo implements android.os.Parcelable android.net.TransportInfo {
+    ctor public VpnTransportInfo(int);
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.VpnTransportInfo> CREATOR;
+    field public final int type;
+  }
+
+}
+
diff --git a/packages/Connectivity/framework/api/module-lib-removed.txt b/packages/Connectivity/framework/api/module-lib-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Connectivity/framework/api/module-lib-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Connectivity/framework/api/removed.txt b/packages/Connectivity/framework/api/removed.txt
new file mode 100644
index 0000000..303a1e61
--- /dev/null
+++ b/packages/Connectivity/framework/api/removed.txt
@@ -0,0 +1,11 @@
+// Signature format: 2.0
+package android.net {
+
+  public class ConnectivityManager {
+    method @Deprecated public boolean requestRouteToHost(int, int);
+    method @Deprecated public int startUsingNetworkFeature(int, String);
+    method @Deprecated public int stopUsingNetworkFeature(int, String);
+  }
+
+}
+
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
new file mode 100644
index 0000000..41ebc57
--- /dev/null
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -0,0 +1,407 @@
+// Signature format: 2.0
+package android.net {
+
+  public class CaptivePortal implements android.os.Parcelable {
+    method public void logEvent(int, @NonNull String);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void reevaluateNetwork();
+    method public void useNetwork();
+    field public static final int APP_REQUEST_REEVALUATION_REQUIRED = 100; // 0x64
+    field public static final int APP_RETURN_DISMISSED = 0; // 0x0
+    field public static final int APP_RETURN_UNWANTED = 1; // 0x1
+    field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2
+  }
+
+  public final class CaptivePortalData implements android.os.Parcelable {
+    method public int describeContents();
+    method public long getByteLimit();
+    method public long getExpiryTimeMillis();
+    method public long getRefreshTimeMillis();
+    method @Nullable public android.net.Uri getUserPortalUrl();
+    method public int getUserPortalUrlSource();
+    method @Nullable public String getVenueFriendlyName();
+    method @Nullable public android.net.Uri getVenueInfoUrl();
+    method public int getVenueInfoUrlSource();
+    method public boolean isCaptive();
+    method public boolean isSessionExtendable();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field public static final int CAPTIVE_PORTAL_DATA_SOURCE_OTHER = 0; // 0x0
+    field public static final int CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT = 1; // 0x1
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.CaptivePortalData> CREATOR;
+  }
+
+  public static class CaptivePortalData.Builder {
+    ctor public CaptivePortalData.Builder();
+    ctor public CaptivePortalData.Builder(@Nullable android.net.CaptivePortalData);
+    method @NonNull public android.net.CaptivePortalData build();
+    method @NonNull public android.net.CaptivePortalData.Builder setBytesRemaining(long);
+    method @NonNull public android.net.CaptivePortalData.Builder setCaptive(boolean);
+    method @NonNull public android.net.CaptivePortalData.Builder setExpiryTime(long);
+    method @NonNull public android.net.CaptivePortalData.Builder setRefreshTime(long);
+    method @NonNull public android.net.CaptivePortalData.Builder setSessionExtendable(boolean);
+    method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri);
+    method @NonNull public android.net.CaptivePortalData.Builder setUserPortalUrl(@Nullable android.net.Uri, int);
+    method @NonNull public android.net.CaptivePortalData.Builder setVenueFriendlyName(@Nullable String);
+    method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri);
+    method @NonNull public android.net.CaptivePortalData.Builder setVenueInfoUrl(@Nullable android.net.Uri, int);
+  }
+
+  public class ConnectivityManager {
+    method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createNattKeepalive(@NonNull android.net.Network, @NonNull android.os.ParcelFileDescriptor, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
+    method @NonNull @RequiresPermission(android.Manifest.permission.PACKET_KEEPALIVE_OFFLOAD) public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull java.net.Socket, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS) public String getCaptivePortalServerUrl();
+    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void getLatestTetheringEntitlementResult(int, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEntitlementResultListener);
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public boolean isTetheringSupported();
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public int registerNetworkProvider(@NonNull android.net.NetworkProvider);
+    method public void registerQosCallback(@NonNull android.net.QosSocketInfo, @NonNull android.net.QosCallback, @NonNull java.util.concurrent.Executor);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void registerTetheringEventCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
+    method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void requestNetwork(@NonNull android.net.NetworkRequest, int, int, @NonNull android.os.Handler, @NonNull android.net.ConnectivityManager.NetworkCallback);
+    method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_AIRPLANE_MODE, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_SETUP_WIZARD, android.Manifest.permission.NETWORK_STACK}) public void setAirplaneMode(boolean);
+    method @RequiresPermission(android.Manifest.permission.CONTROL_OEM_PAID_NETWORK_PREFERENCE) public void setOemNetworkPreference(@NonNull android.net.OemNetworkPreferences, @Nullable java.util.concurrent.Executor, @Nullable android.net.ConnectivityManager.OnSetOemNetworkPreferenceListener);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public boolean shouldAvoidBadWifi();
+    method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public void startCaptivePortalApp(@NonNull android.net.Network, @NonNull android.os.Bundle);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void stopTethering(int);
+    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_FACTORY}) public void unregisterNetworkProvider(@NonNull android.net.NetworkProvider);
+    method public void unregisterQosCallback(@NonNull android.net.QosCallback);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED) public void unregisterTetheringEventCallback(@NonNull android.net.ConnectivityManager.OnTetheringEventCallback);
+    field public static final String EXTRA_CAPTIVE_PORTAL_PROBE_SPEC = "android.net.extra.CAPTIVE_PORTAL_PROBE_SPEC";
+    field public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT = "android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
+    field public static final int TETHERING_BLUETOOTH = 2; // 0x2
+    field public static final int TETHERING_USB = 1; // 0x1
+    field public static final int TETHERING_WIFI = 0; // 0x0
+    field @Deprecated public static final int TETHER_ERROR_ENTITLEMENT_UNKONWN = 13; // 0xd
+    field @Deprecated public static final int TETHER_ERROR_NO_ERROR = 0; // 0x0
+    field @Deprecated public static final int TETHER_ERROR_PROVISION_FAILED = 11; // 0xb
+    field public static final int TYPE_NONE = -1; // 0xffffffff
+    field @Deprecated public static final int TYPE_PROXY = 16; // 0x10
+    field @Deprecated public static final int TYPE_WIFI_P2P = 13; // 0xd
+  }
+
+  public static interface ConnectivityManager.OnSetOemNetworkPreferenceListener {
+    method public void onComplete();
+  }
+
+  @Deprecated public abstract static class ConnectivityManager.OnStartTetheringCallback {
+    ctor @Deprecated public ConnectivityManager.OnStartTetheringCallback();
+    method @Deprecated public void onTetheringFailed();
+    method @Deprecated public void onTetheringStarted();
+  }
+
+  @Deprecated public static interface ConnectivityManager.OnTetheringEntitlementResultListener {
+    method @Deprecated public void onTetheringEntitlementResult(int);
+  }
+
+  @Deprecated public abstract static class ConnectivityManager.OnTetheringEventCallback {
+    ctor @Deprecated public ConnectivityManager.OnTetheringEventCallback();
+    method @Deprecated public void onUpstreamChanged(@Nullable android.net.Network);
+  }
+
+  public final class InvalidPacketException extends java.lang.Exception {
+    ctor public InvalidPacketException(int);
+    method public int getError();
+    field public static final int ERROR_INVALID_IP_ADDRESS = -21; // 0xffffffeb
+    field public static final int ERROR_INVALID_LENGTH = -23; // 0xffffffe9
+    field public static final int ERROR_INVALID_PORT = -22; // 0xffffffea
+  }
+
+  public final class IpConfiguration implements android.os.Parcelable {
+    ctor public IpConfiguration();
+    ctor public IpConfiguration(@NonNull android.net.IpConfiguration);
+    method public int describeContents();
+    method @Nullable public android.net.ProxyInfo getHttpProxy();
+    method @NonNull public android.net.IpConfiguration.IpAssignment getIpAssignment();
+    method @NonNull public android.net.IpConfiguration.ProxySettings getProxySettings();
+    method @Nullable public android.net.StaticIpConfiguration getStaticIpConfiguration();
+    method public void setHttpProxy(@Nullable android.net.ProxyInfo);
+    method public void setIpAssignment(@NonNull android.net.IpConfiguration.IpAssignment);
+    method public void setProxySettings(@NonNull android.net.IpConfiguration.ProxySettings);
+    method public void setStaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.IpConfiguration> CREATOR;
+  }
+
+  public enum IpConfiguration.IpAssignment {
+    enum_constant public static final android.net.IpConfiguration.IpAssignment DHCP;
+    enum_constant public static final android.net.IpConfiguration.IpAssignment STATIC;
+    enum_constant public static final android.net.IpConfiguration.IpAssignment UNASSIGNED;
+  }
+
+  public enum IpConfiguration.ProxySettings {
+    enum_constant public static final android.net.IpConfiguration.ProxySettings NONE;
+    enum_constant public static final android.net.IpConfiguration.ProxySettings PAC;
+    enum_constant public static final android.net.IpConfiguration.ProxySettings STATIC;
+    enum_constant public static final android.net.IpConfiguration.ProxySettings UNASSIGNED;
+  }
+
+  public final class IpPrefix implements android.os.Parcelable {
+    ctor public IpPrefix(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
+    ctor public IpPrefix(@NonNull String);
+  }
+
+  public class KeepalivePacketData {
+    ctor protected KeepalivePacketData(@NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull java.net.InetAddress, @IntRange(from=0, to=65535) int, @NonNull byte[]) throws android.net.InvalidPacketException;
+    method @NonNull public java.net.InetAddress getDstAddress();
+    method public int getDstPort();
+    method @NonNull public byte[] getPacket();
+    method @NonNull public java.net.InetAddress getSrcAddress();
+    method public int getSrcPort();
+  }
+
+  public class LinkAddress implements android.os.Parcelable {
+    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int);
+    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int, int, int, long, long);
+    ctor public LinkAddress(@NonNull java.net.InetAddress, @IntRange(from=0, to=128) int);
+    ctor public LinkAddress(@NonNull String);
+    ctor public LinkAddress(@NonNull String, int, int);
+    method public long getDeprecationTime();
+    method public long getExpirationTime();
+    method public boolean isGlobalPreferred();
+    method public boolean isIpv4();
+    method public boolean isIpv6();
+    method public boolean isSameAddressAs(@Nullable android.net.LinkAddress);
+    field public static final long LIFETIME_PERMANENT = 9223372036854775807L; // 0x7fffffffffffffffL
+    field public static final long LIFETIME_UNKNOWN = -1L; // 0xffffffffffffffffL
+  }
+
+  public final class LinkProperties implements android.os.Parcelable {
+    ctor public LinkProperties(@Nullable android.net.LinkProperties);
+    ctor public LinkProperties(@Nullable android.net.LinkProperties, boolean);
+    method public boolean addDnsServer(@NonNull java.net.InetAddress);
+    method public boolean addLinkAddress(@NonNull android.net.LinkAddress);
+    method public boolean addPcscfServer(@NonNull java.net.InetAddress);
+    method @NonNull public java.util.List<java.net.InetAddress> getAddresses();
+    method @NonNull public java.util.List<java.lang.String> getAllInterfaceNames();
+    method @NonNull public java.util.List<android.net.LinkAddress> getAllLinkAddresses();
+    method @NonNull public java.util.List<android.net.RouteInfo> getAllRoutes();
+    method @Nullable public android.net.Uri getCaptivePortalApiUrl();
+    method @Nullable public android.net.CaptivePortalData getCaptivePortalData();
+    method @NonNull public java.util.List<java.net.InetAddress> getPcscfServers();
+    method @Nullable public String getTcpBufferSizes();
+    method @NonNull public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers();
+    method public boolean hasGlobalIpv6Address();
+    method public boolean hasIpv4Address();
+    method public boolean hasIpv4DefaultRoute();
+    method public boolean hasIpv4DnsServer();
+    method public boolean hasIpv6DefaultRoute();
+    method public boolean hasIpv6DnsServer();
+    method public boolean isIpv4Provisioned();
+    method public boolean isIpv6Provisioned();
+    method public boolean isProvisioned();
+    method public boolean isReachable(@NonNull java.net.InetAddress);
+    method public boolean removeDnsServer(@NonNull java.net.InetAddress);
+    method public boolean removeLinkAddress(@NonNull android.net.LinkAddress);
+    method public boolean removeRoute(@NonNull android.net.RouteInfo);
+    method public void setCaptivePortalApiUrl(@Nullable android.net.Uri);
+    method public void setCaptivePortalData(@Nullable android.net.CaptivePortalData);
+    method public void setPcscfServers(@NonNull java.util.Collection<java.net.InetAddress>);
+    method public void setPrivateDnsServerName(@Nullable String);
+    method public void setTcpBufferSizes(@Nullable String);
+    method public void setUsePrivateDns(boolean);
+    method public void setValidatedPrivateDnsServers(@NonNull java.util.Collection<java.net.InetAddress>);
+  }
+
+  public final class NattKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable {
+    ctor public NattKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[]) throws android.net.InvalidPacketException;
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.NattKeepalivePacketData> CREATOR;
+  }
+
+  public class Network implements android.os.Parcelable {
+    ctor public Network(@NonNull android.net.Network);
+    method public int getNetId();
+    method @NonNull public android.net.Network getPrivateDnsBypassingCopy();
+  }
+
+  public abstract class NetworkAgent {
+    ctor public NetworkAgent(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, int, @NonNull android.net.NetworkAgentConfig, @Nullable android.net.NetworkProvider);
+    method @Nullable public android.net.Network getNetwork();
+    method public void markConnected();
+    method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
+    method public void onAutomaticReconnectDisabled();
+    method public void onNetworkUnwanted();
+    method public void onQosCallbackRegistered(int, @NonNull android.net.QosFilter);
+    method public void onQosCallbackUnregistered(int);
+    method public void onRemoveKeepalivePacketFilter(int);
+    method public void onSaveAcceptUnvalidated(boolean);
+    method public void onSignalStrengthThresholdsUpdated(@NonNull int[]);
+    method public void onStartSocketKeepalive(int, @NonNull java.time.Duration, @NonNull android.net.KeepalivePacketData);
+    method public void onStopSocketKeepalive(int);
+    method public void onValidationStatus(int, @Nullable android.net.Uri);
+    method @NonNull public android.net.Network register();
+    method public final void sendLinkProperties(@NonNull android.net.LinkProperties);
+    method public final void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
+    method public final void sendNetworkScore(@IntRange(from=0, to=99) int);
+    method public final void sendQosCallbackError(int, int);
+    method public final void sendQosSessionAvailable(int, int, @NonNull android.telephony.data.EpsBearerQosSessionAttributes);
+    method public final void sendQosSessionLost(int, int);
+    method public final void sendSocketKeepaliveEvent(int, int);
+    method public final void setUnderlyingNetworks(@Nullable java.util.List<android.net.Network>);
+    method public void unregister();
+    field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
+    field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
+  }
+
+  public final class NetworkAgentConfig implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getLegacyType();
+    method @NonNull public String getLegacyTypeName();
+    method public boolean isExplicitlySelected();
+    method public boolean isPartialConnectivityAcceptable();
+    method public boolean isUnvalidatedConnectivityAcceptable();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkAgentConfig> CREATOR;
+  }
+
+  public static final class NetworkAgentConfig.Builder {
+    ctor public NetworkAgentConfig.Builder();
+    method @NonNull public android.net.NetworkAgentConfig build();
+    method @NonNull public android.net.NetworkAgentConfig.Builder setExplicitlySelected(boolean);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyType(int);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setLegacyTypeName(@NonNull String);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setPartialConnectivityAcceptable(boolean);
+    method @NonNull public android.net.NetworkAgentConfig.Builder setUnvalidatedConnectivityAcceptable(boolean);
+  }
+
+  public final class NetworkCapabilities implements android.os.Parcelable {
+    ctor public NetworkCapabilities(@Nullable android.net.NetworkCapabilities, boolean);
+    method @NonNull public int[] getAdministratorUids();
+    method @Nullable public String getSsid();
+    method @NonNull public int[] getTransportTypes();
+    method public boolean isPrivateDnsBroken();
+    method public boolean satisfiedByNetworkCapabilities(@Nullable android.net.NetworkCapabilities);
+    field public static final int NET_CAPABILITY_NOT_VCN_MANAGED = 28; // 0x1c
+    field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
+    field public static final int NET_CAPABILITY_OEM_PRIVATE = 26; // 0x1a
+    field public static final int NET_CAPABILITY_PARTIAL_CONNECTIVITY = 24; // 0x18
+    field public static final int NET_CAPABILITY_VEHICLE_INTERNAL = 27; // 0x1b
+  }
+
+  public static final class NetworkCapabilities.Builder {
+    ctor public NetworkCapabilities.Builder();
+    ctor public NetworkCapabilities.Builder(@NonNull android.net.NetworkCapabilities);
+    method @NonNull public android.net.NetworkCapabilities.Builder addCapability(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder addTransportType(int);
+    method @NonNull public android.net.NetworkCapabilities build();
+    method @NonNull public android.net.NetworkCapabilities.Builder clearAll();
+    method @NonNull public android.net.NetworkCapabilities.Builder removeCapability(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder removeTransportType(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setAdministratorUids(@NonNull int[]);
+    method @NonNull public android.net.NetworkCapabilities.Builder setLinkDownstreamBandwidthKbps(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder setLinkUpstreamBandwidthKbps(int);
+    method @NonNull public android.net.NetworkCapabilities.Builder setNetworkSpecifier(@Nullable android.net.NetworkSpecifier);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setOwnerUid(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorPackageName(@Nullable String);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setRequestorUid(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkCapabilities.Builder setSignalStrength(int);
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public android.net.NetworkCapabilities.Builder setSsid(@Nullable String);
+    method @NonNull public android.net.NetworkCapabilities.Builder setTransportInfo(@Nullable android.net.TransportInfo);
+  }
+
+  public class NetworkProvider {
+    ctor public NetworkProvider(@NonNull android.content.Context, @NonNull android.os.Looper, @NonNull String);
+    method @RequiresPermission(android.Manifest.permission.NETWORK_FACTORY) public void declareNetworkRequestUnfulfillable(@NonNull android.net.NetworkRequest);
+    method public int getProviderId();
+    method public void onNetworkRequestWithdrawn(@NonNull android.net.NetworkRequest);
+    method public void onNetworkRequested(@NonNull android.net.NetworkRequest, @IntRange(from=0, to=99) int, int);
+    field public static final int ID_NONE = -1; // 0xffffffff
+  }
+
+  public class NetworkRequest implements android.os.Parcelable {
+    method @Nullable public String getRequestorPackageName();
+    method public int getRequestorUid();
+  }
+
+  public static class NetworkRequest.Builder {
+    method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
+  }
+
+  public final class RouteInfo implements android.os.Parcelable {
+    ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int);
+    ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int, int);
+    method public int getMtu();
+    method public int getType();
+    field public static final int RTN_THROW = 9; // 0x9
+    field public static final int RTN_UNICAST = 1; // 0x1
+    field public static final int RTN_UNREACHABLE = 7; // 0x7
+  }
+
+  public abstract class SocketKeepalive implements java.lang.AutoCloseable {
+    field public static final int SUCCESS = 0; // 0x0
+  }
+
+  public final class StaticIpConfiguration implements android.os.Parcelable {
+    ctor public StaticIpConfiguration();
+    ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
+    method public void addDnsServer(@NonNull java.net.InetAddress);
+    method public void clear();
+    method public int describeContents();
+    method @NonNull public java.util.List<java.net.InetAddress> getDnsServers();
+    method @Nullable public String getDomains();
+    method @Nullable public java.net.InetAddress getGateway();
+    method @Nullable public android.net.LinkAddress getIpAddress();
+    method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.StaticIpConfiguration> CREATOR;
+  }
+
+  public static final class StaticIpConfiguration.Builder {
+    ctor public StaticIpConfiguration.Builder();
+    method @NonNull public android.net.StaticIpConfiguration build();
+    method @NonNull public android.net.StaticIpConfiguration.Builder setDnsServers(@NonNull Iterable<java.net.InetAddress>);
+    method @NonNull public android.net.StaticIpConfiguration.Builder setDomains(@Nullable String);
+    method @NonNull public android.net.StaticIpConfiguration.Builder setGateway(@Nullable java.net.InetAddress);
+    method @NonNull public android.net.StaticIpConfiguration.Builder setIpAddress(@Nullable android.net.LinkAddress);
+  }
+
+  public final class TcpKeepalivePacketData extends android.net.KeepalivePacketData implements android.os.Parcelable {
+    ctor public TcpKeepalivePacketData(@NonNull java.net.InetAddress, int, @NonNull java.net.InetAddress, int, @NonNull byte[], int, int, int, int, int, int) throws android.net.InvalidPacketException;
+    method public int describeContents();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.net.TcpKeepalivePacketData> CREATOR;
+    field public final int ipTos;
+    field public final int ipTtl;
+    field public final int tcpAck;
+    field public final int tcpSeq;
+    field public final int tcpWindow;
+    field public final int tcpWindowScale;
+  }
+
+  public interface TransportInfo {
+    method public default boolean hasLocationSensitiveFields();
+    method @NonNull public default android.net.TransportInfo makeCopy(boolean);
+  }
+
+}
+
+package android.net.apf {
+
+  public final class ApfCapabilities implements android.os.Parcelable {
+    ctor public ApfCapabilities(int, int, int);
+    method public int describeContents();
+    method public static boolean getApfDrop8023Frames();
+    method @NonNull public static int[] getApfEtherTypeBlackList();
+    method public boolean hasDataAccess();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.net.apf.ApfCapabilities> CREATOR;
+    field public final int apfPacketFormat;
+    field public final int apfVersionSupported;
+    field public final int maximumApfProgramSize;
+  }
+
+}
+
+package android.net.util {
+
+  public final class SocketUtils {
+    method public static void bindSocketToInterface(@NonNull java.io.FileDescriptor, @NonNull String) throws android.system.ErrnoException;
+    method public static void closeSocket(@Nullable java.io.FileDescriptor) throws java.io.IOException;
+    method @NonNull public static java.net.SocketAddress makeNetlinkSocketAddress(int, int);
+    method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int);
+    method @Deprecated @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
+    method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int, @NonNull byte[]);
+  }
+
+}
+
diff --git a/packages/Connectivity/framework/api/system-lint-baseline.txt b/packages/Connectivity/framework/api/system-lint-baseline.txt
new file mode 100644
index 0000000..9a97707
--- /dev/null
+++ b/packages/Connectivity/framework/api/system-lint-baseline.txt
@@ -0,0 +1 @@
+// Baseline format: 1.0
diff --git a/packages/Connectivity/framework/api/system-removed.txt b/packages/Connectivity/framework/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/packages/Connectivity/framework/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
index f4b46e9..eafda4d 100644
--- a/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
+++ b/packages/Connectivity/framework/src/android/net/CaptivePortalData.java
@@ -44,7 +44,7 @@
     private final boolean mCaptive;
     private final String mVenueFriendlyName;
     private final int mVenueInfoUrlSource;
-    private final int mTermsAndConditionsSource;
+    private final int mUserPortalUrlSource;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -65,7 +65,7 @@
 
     private CaptivePortalData(long refreshTimeMillis, Uri userPortalUrl, Uri venueInfoUrl,
             boolean isSessionExtendable, long byteLimit, long expiryTimeMillis, boolean captive,
-            String venueFriendlyName, int venueInfoUrlSource, int termsAndConditionsSource) {
+            String venueFriendlyName, int venueInfoUrlSource, int userPortalUrlSource) {
         mRefreshTimeMillis = refreshTimeMillis;
         mUserPortalUrl = userPortalUrl;
         mVenueInfoUrl = venueInfoUrl;
@@ -75,7 +75,7 @@
         mCaptive = captive;
         mVenueFriendlyName = venueFriendlyName;
         mVenueInfoUrlSource = venueInfoUrlSource;
-        mTermsAndConditionsSource = termsAndConditionsSource;
+        mUserPortalUrlSource = userPortalUrlSource;
     }
 
     private CaptivePortalData(Parcel p) {
@@ -100,7 +100,7 @@
         dest.writeBoolean(mCaptive);
         dest.writeString(mVenueFriendlyName);
         dest.writeInt(mVenueInfoUrlSource);
-        dest.writeInt(mTermsAndConditionsSource);
+        dest.writeInt(mUserPortalUrlSource);
     }
 
     /**
@@ -130,7 +130,7 @@
         public Builder(@Nullable CaptivePortalData data) {
             if (data == null) return;
             setRefreshTime(data.mRefreshTimeMillis)
-                    .setUserPortalUrl(data.mUserPortalUrl, data.mTermsAndConditionsSource)
+                    .setUserPortalUrl(data.mUserPortalUrl, data.mUserPortalUrlSource)
                     .setVenueInfoUrl(data.mVenueInfoUrl, data.mVenueInfoUrlSource)
                     .setSessionExtendable(data.mIsSessionExtendable)
                     .setBytesRemaining(data.mByteLimit)
@@ -314,7 +314,7 @@
      * @return The source that the user portal URL was obtained from
      */
     public @CaptivePortalDataSource int getUserPortalUrlSource() {
-        return mTermsAndConditionsSource;
+        return mUserPortalUrlSource;
     }
 
     /**
@@ -342,7 +342,7 @@
     public int hashCode() {
         return Objects.hash(mRefreshTimeMillis, mUserPortalUrl, mVenueInfoUrl,
                 mIsSessionExtendable, mByteLimit, mExpiryTimeMillis, mCaptive, mVenueFriendlyName,
-                mVenueInfoUrlSource, mTermsAndConditionsSource);
+                mVenueInfoUrlSource, mUserPortalUrlSource);
     }
 
     @Override
@@ -358,7 +358,7 @@
                 && mCaptive == other.mCaptive
                 && Objects.equals(mVenueFriendlyName, other.mVenueFriendlyName)
                 && mVenueInfoUrlSource == other.mVenueInfoUrlSource
-                && mTermsAndConditionsSource == other.mTermsAndConditionsSource;
+                && mUserPortalUrlSource == other.mUserPortalUrlSource;
     }
 
     @Override
@@ -373,7 +373,7 @@
                 + ", captive: " + mCaptive
                 + ", venueFriendlyName: " + mVenueFriendlyName
                 + ", venueInfoUrlSource: " + mVenueInfoUrlSource
-                + ", termsAndConditionsSource: " + mTermsAndConditionsSource
+                + ", userPortalUrlSource: " + mUserPortalUrlSource
                 + "}";
     }
 }
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index c7bb2a7..6273f4b 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -49,8 +49,6 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.INetworkActivityListener;
-import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
@@ -835,7 +833,6 @@
 
     private final Context mContext;
 
-    private INetworkManagementService mNMService;
     private INetworkPolicyManager mNPManager;
     private final TetheringManager mTetheringManager;
 
@@ -1070,58 +1067,6 @@
     }
 
     /**
-     * Calls VpnManager#isAlwaysOnVpnPackageSupportedForUser.
-     * @deprecated TODO: remove when callers have migrated to VpnManager.
-     * @hide
-     */
-    @Deprecated
-    public boolean isAlwaysOnVpnPackageSupportedForUser(int userId, @Nullable String vpnPackage) {
-        return getVpnManager().isAlwaysOnVpnPackageSupportedForUser(userId, vpnPackage);
-    }
-
-    /**
-    * Calls VpnManager#setAlwaysOnVpnPackageForUser.
-     * @deprecated TODO: remove when callers have migrated to VpnManager.
-     * @hide
-     */
-    @Deprecated
-    public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
-            boolean lockdownEnabled, @Nullable List<String> lockdownAllowlist) {
-        return getVpnManager().setAlwaysOnVpnPackageForUser(userId, vpnPackage, lockdownEnabled,
-                lockdownAllowlist);
-    }
-
-    /**
-     * Calls VpnManager#getAlwaysOnVpnPackageForUser.
-     * @deprecated TODO: remove when callers have migrated to VpnManager.
-     * @hide
-     */
-    @Deprecated
-    public String getAlwaysOnVpnPackageForUser(int userId) {
-        return getVpnManager().getAlwaysOnVpnPackageForUser(userId);
-    }
-
-    /**
-     * Calls VpnManager#isVpnLockdownEnabled.
-     * @deprecated TODO: remove when callers have migrated to VpnManager.
-     * @hide
-     */
-    @Deprecated
-    public boolean isVpnLockdownEnabled(int userId) {
-        return getVpnManager().isVpnLockdownEnabled(userId);
-    }
-
-    /**
-     * Calls VpnManager#getVpnLockdownAllowlist.
-     * @deprecated TODO: remove when callers have migrated to VpnManager.
-     * @hide
-     */
-    @Deprecated
-    public List<String> getVpnLockdownAllowlist(int userId) {
-        return getVpnManager().getVpnLockdownAllowlist(userId);
-    }
-
-    /**
      * Adds or removes a requirement for given UID ranges to use the VPN.
      *
      * If set to {@code true}, informs the system that the UIDs in the specified ranges must not
@@ -2211,17 +2156,6 @@
         void onNetworkActive();
     }
 
-    private INetworkManagementService getNetworkManagementService() {
-        synchronized (this) {
-            if (mNMService != null) {
-                return mNMService;
-            }
-            IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-            mNMService = INetworkManagementService.Stub.asInterface(b);
-            return mNMService;
-        }
-    }
-
     private final ArrayMap<OnNetworkActiveListener, INetworkActivityListener>
             mNetworkActivityListeners = new ArrayMap<>();
 
@@ -2246,7 +2180,7 @@
         };
 
         try {
-            getNetworkManagementService().registerNetworkActivityListener(rl);
+            mService.registerNetworkActivityListener(rl);
             mNetworkActivityListeners.put(l, rl);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
@@ -2263,7 +2197,7 @@
         INetworkActivityListener rl = mNetworkActivityListeners.get(l);
         Preconditions.checkArgument(rl != null, "Listener was not registered.");
         try {
-            getNetworkManagementService().unregisterNetworkActivityListener(rl);
+            mService.registerNetworkActivityListener(rl);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -2279,7 +2213,7 @@
      */
     public boolean isDefaultNetworkActive() {
         try {
-            return getNetworkManagementService().isNetworkActive();
+            return mService.isDefaultNetworkActive();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -3167,16 +3101,6 @@
     }
 
     /**
-     * Calls VpnManager#updateLockdownVpn.
-     * @deprecated TODO: remove when callers have migrated to VpnManager.
-     * @hide
-     */
-    @Deprecated
-    public boolean updateLockdownVpn() {
-        return getVpnManager().updateLockdownVpn();
-    }
-
-    /**
      * Set sign in error notification to visible or invisible
      *
      * @hide
@@ -4537,8 +4461,6 @@
         try {
             mService.factoryReset();
             mTetheringManager.stopAllTethering();
-            // TODO: Migrate callers to VpnManager#factoryReset.
-            getVpnManager().factoryReset();
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -4606,7 +4528,7 @@
             // Set HTTP proxy system properties to match network.
             // TODO: Deprecate this static method and replace it with a non-static version.
             try {
-                Proxy.setHttpProxySystemProperty(getInstance().getDefaultProxy());
+                Proxy.setHttpProxyConfiguration(getInstance().getDefaultProxy());
             } catch (SecurityException e) {
                 // The process doesn't have ACCESS_NETWORK_STATE, so we can't fetch the proxy.
                 Log.e(TAG, "Can't set proxy properties", e);
@@ -4832,15 +4754,6 @@
         return new TestNetworkManager(ITestNetworkManager.Stub.asInterface(tnBinder));
     }
 
-    /**
-     * Temporary hack to shim calls from ConnectivityManager to VpnManager. We cannot store a
-     * private final mVpnManager because ConnectivityManager is initialized before VpnManager.
-     * @hide TODO: remove.
-     */
-    public VpnManager getVpnManager() {
-        return mContext.getSystemService(VpnManager.class);
-    }
-
     /** @hide */
     public ConnectivityDiagnosticsManager createDiagnosticsManager() {
         return new ConnectivityDiagnosticsManager(mContext, mService);
diff --git a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
index 6391802..160338d 100644
--- a/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
+++ b/packages/Connectivity/framework/src/android/net/IConnectivityManager.aidl
@@ -21,6 +21,7 @@
 import android.net.ConnectivityDiagnosticsManager;
 import android.net.IConnectivityDiagnosticsCallback;
 import android.net.IOnSetOemNetworkPreferenceListener;
+import android.net.INetworkActivityListener;
 import android.net.IQosCallback;
 import android.net.ISocketKeepaliveCallback;
 import android.net.LinkProperties;
@@ -36,7 +37,6 @@
 import android.net.QosSocketInfo;
 import android.os.Bundle;
 import android.os.IBinder;
-import android.os.INetworkActivityListener;
 import android.os.Messenger;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
diff --git a/core/java/android/os/INetworkActivityListener.aidl b/packages/Connectivity/framework/src/android/net/INetworkActivityListener.aidl
similarity index 96%
rename from core/java/android/os/INetworkActivityListener.aidl
rename to packages/Connectivity/framework/src/android/net/INetworkActivityListener.aidl
index 24e6e55..79687dd 100644
--- a/core/java/android/os/INetworkActivityListener.aidl
+++ b/packages/Connectivity/framework/src/android/net/INetworkActivityListener.aidl
@@ -13,7 +13,7 @@
 ** limitations under the License.
 */
 
-package android.os;
+package android.net;
 
 /**
  * @hide
diff --git a/packages/Connectivity/framework/src/android/net/IpPrefix.java b/packages/Connectivity/framework/src/android/net/IpPrefix.java
index bcb65fa..d2ee7d1 100644
--- a/packages/Connectivity/framework/src/android/net/IpPrefix.java
+++ b/packages/Connectivity/framework/src/android/net/IpPrefix.java
@@ -24,6 +24,8 @@
 import android.os.Parcelable;
 import android.util.Pair;
 
+import com.android.net.module.util.NetUtils;
+
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -59,7 +61,7 @@
             throw new IllegalArgumentException(
                     "IpPrefix has " + address.length + " bytes which is neither 4 nor 16");
         }
-        NetworkUtils.maskRawAddress(address, prefixLength);
+        NetUtils.maskRawAddress(address, prefixLength);
     }
 
     /**
@@ -190,7 +192,7 @@
         if (addrBytes == null || addrBytes.length != this.address.length) {
             return false;
         }
-        NetworkUtils.maskRawAddress(addrBytes, prefixLength);
+        NetUtils.maskRawAddress(addrBytes, prefixLength);
         return Arrays.equals(this.address, addrBytes);
     }
 
@@ -204,7 +206,7 @@
     public boolean containsPrefix(@NonNull IpPrefix otherPrefix) {
         if (otherPrefix.getPrefixLength() < prefixLength) return false;
         final byte[] otherAddress = otherPrefix.getRawAddress();
-        NetworkUtils.maskRawAddress(otherAddress, prefixLength);
+        NetUtils.maskRawAddress(otherAddress, prefixLength);
         return Arrays.equals(otherAddress, address);
     }
 
diff --git a/packages/Connectivity/framework/src/android/net/NetworkRequest.java b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
index 4e3085f..b4a651c 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkRequest.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkRequest.java
@@ -16,6 +16,22 @@
 
 package android.net;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
@@ -30,6 +46,8 @@
 import android.text.TextUtils;
 import android.util.proto.ProtoOutputStream;
 
+import java.util.Arrays;
+import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 
@@ -154,8 +172,30 @@
      * needed in terms of {@link NetworkCapabilities} features
      */
     public static class Builder {
+        /**
+         * Capabilities that are currently compatible with VCN networks.
+         */
+        private static final List<Integer> VCN_SUPPORTED_CAPABILITIES = Arrays.asList(
+                NET_CAPABILITY_CAPTIVE_PORTAL,
+                NET_CAPABILITY_DUN,
+                NET_CAPABILITY_FOREGROUND,
+                NET_CAPABILITY_INTERNET,
+                NET_CAPABILITY_NOT_CONGESTED,
+                NET_CAPABILITY_NOT_METERED,
+                NET_CAPABILITY_NOT_RESTRICTED,
+                NET_CAPABILITY_NOT_ROAMING,
+                NET_CAPABILITY_NOT_SUSPENDED,
+                NET_CAPABILITY_NOT_VPN,
+                NET_CAPABILITY_PARTIAL_CONNECTIVITY,
+                NET_CAPABILITY_TEMPORARILY_NOT_METERED,
+                NET_CAPABILITY_TRUSTED,
+                NET_CAPABILITY_VALIDATED);
+
         private final NetworkCapabilities mNetworkCapabilities;
 
+        // A boolean that represents the user modified NOT_VCN_MANAGED capability.
+        private boolean mModifiedNotVcnManaged = false;
+
         /**
          * Default constructor for Builder.
          */
@@ -177,6 +217,7 @@
             // maybeMarkCapabilitiesRestricted() doesn't add back.
             final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
             nc.maybeMarkCapabilitiesRestricted();
+            deduceNotVcnManagedCapability(nc);
             return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
                     ConnectivityManager.REQUEST_ID_UNSET, Type.NONE);
         }
@@ -193,6 +234,9 @@
          */
         public Builder addCapability(@NetworkCapabilities.NetCapability int capability) {
             mNetworkCapabilities.addCapability(capability);
+            if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) {
+                mModifiedNotVcnManaged = true;
+            }
             return this;
         }
 
@@ -204,6 +248,9 @@
          */
         public Builder removeCapability(@NetworkCapabilities.NetCapability int capability) {
             mNetworkCapabilities.removeCapability(capability);
+            if (capability == NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED) {
+                mModifiedNotVcnManaged = true;
+            }
             return this;
         }
 
@@ -261,6 +308,9 @@
         @NonNull
         public Builder clearCapabilities() {
             mNetworkCapabilities.clearAll();
+            // If the caller explicitly clear all capabilities, the NOT_VCN_MANAGED capabilities
+            // should not be add back later.
+            mModifiedNotVcnManaged = true;
             return this;
         }
 
@@ -380,6 +430,25 @@
             mNetworkCapabilities.setSignalStrength(signalStrength);
             return this;
         }
+
+        /**
+         * Deduce the NET_CAPABILITY_NOT_VCN_MANAGED capability from other capabilities
+         * and user intention, which includes:
+         *   1. For the requests that don't have anything besides
+         *      {@link #VCN_SUPPORTED_CAPABILITIES}, add the NET_CAPABILITY_NOT_VCN_MANAGED to
+         *      allow the callers automatically utilize VCN networks if available.
+         *   2. For the requests that explicitly add or remove NET_CAPABILITY_NOT_VCN_MANAGED,
+         *      do not alter them to allow user fire request that suits their need.
+         *
+         * @hide
+         */
+        private void deduceNotVcnManagedCapability(final NetworkCapabilities nc) {
+            if (mModifiedNotVcnManaged) return;
+            for (final int cap : nc.getCapabilities()) {
+                if (!VCN_SUPPORTED_CAPABILITIES.contains(cap)) return;
+            }
+            nc.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
+        }
     }
 
     // implement the Parcelable interface
diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
index 8be4af7..b5e8a61 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
@@ -29,7 +29,6 @@
 import java.net.Inet4Address;
 import java.net.InetAddress;
 import java.net.SocketException;
-import java.net.UnknownHostException;
 import java.util.Locale;
 import java.util.TreeSet;
 
@@ -92,7 +91,8 @@
      * this socket will go directly to the underlying network, so its traffic will not be
      * forwarded through the VPN.
      */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553,
+            publicAlternatives = "Use {@link android.net.VpnService#protect} instead.")
     public static native boolean protectFromVpn(FileDescriptor fd);
 
     /**
@@ -232,46 +232,6 @@
     }
 
     /**
-     *  Masks a raw IP address byte array with the specified prefix length.
-     */
-    public static void maskRawAddress(byte[] array, int prefixLength) {
-        if (prefixLength < 0 || prefixLength > array.length * 8) {
-            throw new RuntimeException("IP address with " + array.length +
-                    " bytes has invalid prefix length " + prefixLength);
-        }
-
-        int offset = prefixLength / 8;
-        int remainder = prefixLength % 8;
-        byte mask = (byte)(0xFF << (8 - remainder));
-
-        if (offset < array.length) array[offset] = (byte)(array[offset] & mask);
-
-        offset++;
-
-        for (; offset < array.length; offset++) {
-            array[offset] = 0;
-        }
-    }
-
-    /**
-     * Get InetAddress masked with prefixLength.  Will never return null.
-     * @param address the IP address to mask with
-     * @param prefixLength the prefixLength used to mask the IP
-     */
-    public static InetAddress getNetworkPart(InetAddress address, int prefixLength) {
-        byte[] array = address.getAddress();
-        maskRawAddress(array, prefixLength);
-
-        InetAddress netPart = null;
-        try {
-            netPart = InetAddress.getByAddress(array);
-        } catch (UnknownHostException e) {
-            throw new RuntimeException("getNetworkPart error - " + e.toString());
-        }
-        return netPart;
-    }
-
-    /**
      * Returns the implicit netmask of an IPv4 address, as was the custom before 1993.
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
diff --git a/packages/Connectivity/framework/src/android/net/Proxy.java b/packages/Connectivity/framework/src/android/net/Proxy.java
index 9cd7ab2..77c8a4f 100644
--- a/packages/Connectivity/framework/src/android/net/Proxy.java
+++ b/packages/Connectivity/framework/src/android/net/Proxy.java
@@ -16,8 +16,10 @@
 
 package android.net;
 
+import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
@@ -185,7 +187,19 @@
 
     /** @hide */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public static final void setHttpProxySystemProperty(ProxyInfo p) {
+    @Deprecated
+    public static void setHttpProxySystemProperty(ProxyInfo p) {
+        setHttpProxyConfiguration(p);
+    }
+
+    /**
+     * Set HTTP proxy configuration for the process to match the provided ProxyInfo.
+     *
+     * If the provided ProxyInfo is null, the proxy configuration will be cleared.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static void setHttpProxyConfiguration(@Nullable ProxyInfo p) {
         String host = null;
         String port = null;
         String exclList = null;
@@ -196,11 +210,11 @@
             exclList = ProxyUtils.exclusionListAsString(p.getExclusionList());
             pacFileUrl = p.getPacFileUrl();
         }
-        setHttpProxySystemProperty(host, port, exclList, pacFileUrl);
+        setHttpProxyConfiguration(host, port, exclList, pacFileUrl);
     }
 
     /** @hide */
-    public static final void setHttpProxySystemProperty(String host, String port, String exclList,
+    public static void setHttpProxyConfiguration(String host, String port, String exclList,
             Uri pacFileUrl) {
         if (exclList != null) exclList = exclList.replace(",", "|");
         if (false) Log.d(TAG, "setHttpProxySystemProperty :"+host+":"+port+" - "+exclList);
diff --git a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
index 0242ba0..340141b 100644
--- a/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
+++ b/packages/Connectivity/framework/src/android/net/VpnTransportInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
index 85e3fa3..43fffd7 100644
--- a/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
+++ b/packages/Connectivity/framework/src/android/net/util/MultinetworkPolicyTracker.java
@@ -40,6 +40,8 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
 
 /**
  * A class to encapsulate management of the "Smart Networking" capability of
@@ -73,6 +75,32 @@
     private volatile int mMeteredMultipathPreference;
     private int mActiveSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
+    // Mainline module can't use internal HandlerExecutor, so add an identical executor here.
+    private static class HandlerExecutor implements Executor {
+        @NonNull
+        private final Handler mHandler;
+
+        HandlerExecutor(@NonNull Handler handler) {
+            mHandler = handler;
+        }
+        @Override
+        public void execute(Runnable command) {
+            if (!mHandler.post(command)) {
+                throw new RejectedExecutionException(mHandler + " is shutting down");
+            }
+        }
+    }
+
+    @VisibleForTesting
+    protected class ActiveDataSubscriptionIdChangedListener extends PhoneStateListener
+            implements PhoneStateListener.ActiveDataSubscriptionIdChangedListener {
+        @Override
+        public void onActiveDataSubscriptionIdChanged(int subId) {
+            mActiveSubId = subId;
+            reevaluateInternal();
+        }
+    }
+
     public MultinetworkPolicyTracker(Context ctx, Handler handler) {
         this(ctx, handler, null);
     }
@@ -93,14 +121,8 @@
             }
         };
 
-        ctx.getSystemService(TelephonyManager.class).listen(
-                new PhoneStateListener(handler.getLooper()) {
-            @Override
-            public void onActiveDataSubscriptionIdChanged(int subId) {
-                mActiveSubId = subId;
-                reevaluateInternal();
-            }
-        }, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
+        ctx.getSystemService(TelephonyManager.class).registerPhoneStateListener(
+                new HandlerExecutor(handler), new ActiveDataSubscriptionIdChangedListener());
 
         updateAvoidBadWifi();
         updateMeteredMultipathPreference();
diff --git a/packages/InputDevices/OWNERS b/packages/InputDevices/OWNERS
index 0313a40..f0d6db8 100644
--- a/packages/InputDevices/OWNERS
+++ b/packages/InputDevices/OWNERS
@@ -1,2 +1 @@
-michaelwr@google.com
-svv@google.com
+include /services/core/java/com/android/server/input/OWNERS
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index c3fc019..cd7449a 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -336,6 +336,9 @@
     <!-- Permissions required for CTS test - AdbManagerTest -->
     <uses-permission android:name="android.permission.MANAGE_DEBUGGING" />
 
+    <!-- Permission required for CTS test - CtsTelephonyTestCases -->
+    <uses-permission android:name="android.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE" />
+
     <!-- Permission needed for CTS test - DisplayTest -->
     <uses-permission android:name="android.permission.OVERRIDE_DISPLAY_MODE_REQUESTS" />
 
diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS
index 34901f5..6d738f8 100644
--- a/packages/Shell/OWNERS
+++ b/packages/Shell/OWNERS
@@ -9,3 +9,4 @@
 toddke@google.com
 cbrubaker@google.com
 omakoto@google.com
+michaelwr@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
index e6f43c1..328cb8a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenMediaRecorder.java
@@ -187,12 +187,12 @@
      */
     void end() {
         mMediaRecorder.stop();
-        mMediaProjection.stop();
         mMediaRecorder.release();
-        mMediaRecorder = null;
-        mMediaProjection = null;
         mInputSurface.release();
         mVirtualDisplay.release();
+        mMediaProjection.stop();
+        mMediaRecorder = null;
+        mMediaProjection = null;
         stopInternalAudioRecording();
 
         Log.d(TAG, "end recording");
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS b/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
new file mode 100644
index 0000000..9b3e386
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
@@ -0,0 +1,12 @@
+# Scroll Capture (Long Screenshots)
+# Bug component: 801322
+#
+# Referenced by:
+#
+# core/java/src/android/view/OWNERS
+# core/java/src/com/android/internal/view/OWNERS
+# core/tests/coretests/src/android/view/OWNERS
+# core/tests/coretests/src/com/android/internal/view/OWNERS
+
+mrcasey@google.com
+mrenouf@google.com
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/AlwaysOnDisconnectedDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/AlwaysOnDisconnectedDialog.java
index 6dcad25..3502baa 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/AlwaysOnDisconnectedDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/AlwaysOnDisconnectedDialog.java
@@ -23,7 +23,7 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
+import android.net.VpnManager;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -42,7 +42,7 @@
 
     private static final String TAG = "VpnDisconnected";
 
-    private ConnectivityManager mService;
+    private VpnManager mService;
     private int mUserId;
     private String mVpnPackage;
 
@@ -51,8 +51,8 @@
         super.onCreate(savedInstanceState);
 
         mUserId = UserHandle.myUserId();
-        final ConnectivityManager cm = getSystemService(ConnectivityManager.class);
-        mVpnPackage = cm.getAlwaysOnVpnPackageForUser(mUserId);
+        final VpnManager vm = getSystemService(VpnManager.class);
+        mVpnPackage = vm.getAlwaysOnVpnPackageForUser(mUserId);
         if (mVpnPackage == null) {
             finish();
             return;
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
index aab01d0..fb23678 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java
@@ -21,7 +21,6 @@
 import android.content.DialogInterface;
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
-import android.net.ConnectivityManager;
 import android.net.VpnManager;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -45,7 +44,6 @@
 
     private String mPackage;
 
-    private ConnectivityManager mCm;  // TODO: switch entirely to VpnManager once VPN code moves
     private VpnManager mVm;
 
     public ConfirmDialog() {
@@ -60,7 +58,6 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mPackage = getCallingPackage();
-        mCm = getSystemService(ConnectivityManager.class);
         mVm = getSystemService(VpnManager.class);
 
         if (mVm.prepareVpn(mPackage, null, UserHandle.myUserId())) {
@@ -72,7 +69,7 @@
             finish();
             return;
         }
-        final String alwaysOnVpnPackage = mCm.getAlwaysOnVpnPackageForUser(UserHandle.myUserId());
+        final String alwaysOnVpnPackage = mVm.getAlwaysOnVpnPackageForUser(UserHandle.myUserId());
         // Can't prepare new vpn app when another vpn is always-on
         if (alwaysOnVpnPackage != null && !alwaysOnVpnPackage.equals(mPackage)) {
             finish();
diff --git a/services/Android.bp b/services/Android.bp
index 8369444..872b118 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -22,7 +22,7 @@
 }
 
 filegroup {
-    name: "services-all-sources",
+    name: "services-non-updatable-sources",
     srcs: [
         ":services.core-sources",
         ":services.accessibility-sources",
@@ -47,6 +47,14 @@
         ":services.usb-sources",
         ":services.voiceinteraction-sources",
         ":services.wifi-sources",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+filegroup {
+    name: "services-all-sources",
+    srcs: [
+        ":services-non-updatable-sources",
         ":service-permission-sources",
         ":service-statsd-sources",
     ],
@@ -127,9 +135,8 @@
 // API stub
 // =============================================================
 
-droidstubs {
-    name: "services-stubs.sources",
-    srcs: [":services-all-sources"],
+stubs_defaults {
+    name: "services-stubs-default",
     installable: false,
     args: " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\)" +
         " --hide-annotation android.annotation.Hide" +
@@ -139,7 +146,13 @@
         " --hide DeprecationMismatch" +
         " --hide HiddenTypedefConstant",
     visibility: ["//visibility:private"],
-    filter_packages: ["com.android."],
+    filter_packages: ["com.android."]
+}
+
+droidstubs {
+    name: "services-stubs.sources",
+    srcs: [":services-all-sources"],
+    defaults: ["services-stubs-default"],
     check_api: {
         current: {
             api_file: "api/current.txt",
@@ -185,3 +198,34 @@
         dir: "apistubs/android/system-server",
     },
 }
+
+droidstubs {
+    name: "services-non-updatable-stubs.sources",
+    srcs: [":services-non-updatable-sources"],
+    defaults: ["services-stubs-default"],
+    check_api: {
+        current: {
+            api_file: "api/non-updatable-current.txt",
+            removed_api_file: "api/non-updatable-removed.txt",
+        },
+        api_lint: {
+            enabled: true,
+            new_since: ":android-non-updatable.api.system-server.latest",
+            baseline_file: "api/non-updatable-lint-baseline.txt",
+        },
+    },
+    dists: [
+        {
+            targets: ["sdk", "win_sdk"],
+            dir: "apistubs/android/system-server/api",
+            dest: "android-non-updatable.txt",
+            tag: ".api.txt"
+        },
+        {
+            targets: ["sdk", "win_sdk"],
+            dir: "apistubs/android/system-server/api",
+            dest: "android-non-updatable-removed.tx",
+            tag: ".removed-api.txt",
+        },
+    ]
+}
\ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index fcf270b..ac2ce5c 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -766,6 +766,10 @@
             // performs the current profile parent resolution.
             final int resolvedUserId = mSecurityPolicy
                     .resolveCallingUserIdEnforcingPermissionsLocked(userId);
+
+            if (Binder.getCallingPid() == OWN_PROCESS_ID) {
+                return new ArrayList<>(getUserStateLocked(resolvedUserId).mInstalledServices);
+            }
             return getUserStateLocked(resolvedUserId).mInstalledServices;
         }
     }
diff --git a/services/api/Android.bp b/services/api/Android.bp
new file mode 100644
index 0000000..bbc8c72
--- /dev/null
+++ b/services/api/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2021 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_visibility: ["//visibility:private"],
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+    name: "non-updatable-system-server-current.txt",
+    srcs: ["non-updatable-current.txt"],
+    visibility: ["//frameworks/base/api"],
+}
+
+filegroup {
+    name: "non-updatable-system-server-removed.txt",
+    srcs: ["non-updatable-removed.txt"],
+    visibility: ["//frameworks/base/api"],
+}
diff --git a/services/api/current.txt b/services/api/current.txt
index 9bbb3ef..17ca369 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -46,6 +46,11 @@
 
 package com.android.server {
 
+  public final class LocalManagerRegistry {
+    method public static <T> void addManager(@NonNull Class<T>, @NonNull T);
+    method @Nullable public static <T> T getManager(@NonNull Class<T>);
+  }
+
   public abstract class SystemService {
     ctor public SystemService(@NonNull android.content.Context);
     method @NonNull public final android.content.Context getContext();
diff --git a/services/api/non-updatable-current.txt b/services/api/non-updatable-current.txt
new file mode 100644
index 0000000..647739f
--- /dev/null
+++ b/services/api/non-updatable-current.txt
@@ -0,0 +1,46 @@
+// Signature format: 2.0
+package com.android.server {
+
+  public final class LocalManagerRegistry {
+    method public static <T> void addManager(@NonNull Class<T>, @NonNull T);
+    method @Nullable public static <T> T getManager(@NonNull Class<T>);
+  }
+
+  public abstract class SystemService {
+    ctor public SystemService(@NonNull android.content.Context);
+    method @NonNull public final android.content.Context getContext();
+    method public boolean isUserSupported(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onBootPhase(int);
+    method public abstract void onStart();
+    method public void onUserStarting(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserStopped(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserStopping(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserSwitching(@Nullable com.android.server.SystemService.TargetUser, @NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserUnlocked(@NonNull com.android.server.SystemService.TargetUser);
+    method public void onUserUnlocking(@NonNull com.android.server.SystemService.TargetUser);
+    method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder);
+    method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder, boolean);
+    field public static final int PHASE_ACTIVITY_MANAGER_READY = 550; // 0x226
+    field public static final int PHASE_BOOT_COMPLETED = 1000; // 0x3e8
+    field public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520; // 0x208
+    field public static final int PHASE_LOCK_SETTINGS_READY = 480; // 0x1e0
+    field public static final int PHASE_SYSTEM_SERVICES_READY = 500; // 0x1f4
+    field public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; // 0x258
+    field public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // 0x64
+  }
+
+  public static final class SystemService.TargetUser {
+    method @NonNull public android.os.UserHandle getUserHandle();
+  }
+
+}
+
+package com.android.server.wifi {
+
+  public class SupplicantManager {
+    method public static void start();
+    method public static void stop();
+  }
+
+}
+
diff --git a/services/api/non-updatable-lint-baseline.txt b/services/api/non-updatable-lint-baseline.txt
new file mode 100644
index 0000000..b46d21e
--- /dev/null
+++ b/services/api/non-updatable-lint-baseline.txt
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+NotCloseable: com.android.server.wifi.SupplicantManager:
+    Classes that release resources (stop()) should implement AutoClosable and CloseGuard: class com.android.server.wifi.SupplicantManager
+
+
+ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder):
+    Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder)}
+ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder, boolean):
+    Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder,boolean)}
diff --git a/services/api/non-updatable-removed.txt b/services/api/non-updatable-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/services/api/non-updatable-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 66bbf66..cfbfe73 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -31,6 +31,8 @@
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
 import android.companion.Association;
 import android.companion.AssociationRequest;
 import android.companion.CompanionDeviceManager;
@@ -665,6 +667,12 @@
         }
     }
 
+    void onDeviceConnected(String address) {
+    }
+
+    void onDeviceDisconnected(String address) {
+    }
+
     private class ShellCmd extends ShellCommand {
         public static final String USAGE = "help\n"
                 + "list USER_ID\n"
@@ -709,4 +717,19 @@
         }
     }
 
+
+    private class BluetoothDeviceConnectedListener
+            extends BluetoothAdapter.BluetoothConnectionCallback {
+        @Override
+        public void onDeviceConnected(BluetoothDevice device) {
+            CompanionDeviceManagerService.this.onDeviceConnected(device.getAddress());
+        }
+
+        @Override
+        public void onDeviceDisconnected(BluetoothDevice device, @DisconnectReason int reason) {
+            Slog.d(LOG_TAG, device.getAddress() + " disconnected w/ reason: (" + reason + ") "
+                    + BluetoothAdapter.BluetoothConnectionCallback.disconnectReasonText(reason));
+            CompanionDeviceManagerService.this.onDeviceDisconnected(device.getAddress());
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 5077cc6..542d527 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -44,6 +44,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PAID;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE;
@@ -90,7 +91,7 @@
 import android.net.IConnectivityManager;
 import android.net.IDnsResolver;
 import android.net.INetd;
-import android.net.INetworkManagementEventObserver;
+import android.net.INetworkActivityListener;
 import android.net.INetworkMonitor;
 import android.net.INetworkMonitorCallbacks;
 import android.net.INetworkPolicyListener;
@@ -147,13 +148,13 @@
 import android.net.shared.PrivateDnsConfig;
 import android.net.util.MultinetworkPolicyTracker;
 import android.net.util.NetdService;
+import android.os.BatteryStatsManager;
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
-import android.os.INetworkActivityListener;
 import android.os.INetworkManagementService;
 import android.os.Looper;
 import android.os.Message;
@@ -163,6 +164,7 @@
 import android.os.PersistableBundle;
 import android.os.PowerManager;
 import android.os.Process;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.os.SystemClock;
@@ -172,6 +174,7 @@
 import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.LocalLog;
 import android.util.Log;
@@ -185,14 +188,17 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.logging.MetricsLogger;
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.BitUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.LocationPermissionChecker;
 import com.android.internal.util.MessageUtils;
 import com.android.modules.utils.BasicShellCommandHandler;
+import com.android.net.module.util.BaseNetdUnsolicitedEventListener;
+import com.android.net.module.util.CollectionUtils;
 import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
 import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
+import com.android.net.module.util.PermissionUtils;
 import com.android.server.am.BatteryStatsService;
 import com.android.server.connectivity.AutodestructReference;
 import com.android.server.connectivity.DataConnectionStats;
@@ -209,7 +215,6 @@
 import com.android.server.connectivity.PermissionMonitor;
 import com.android.server.connectivity.ProxyTracker;
 import com.android.server.connectivity.QosCallbackTracker;
-import com.android.server.net.BaseNetworkObserver;
 import com.android.server.net.NetworkPolicyManagerInternal;
 import com.android.server.utils.PriorityDump;
 
@@ -327,6 +332,7 @@
     private INetworkStatsService mStatsService;
     private NetworkPolicyManager mPolicyManager;
     private NetworkPolicyManagerInternal mPolicyManagerInternal;
+    private final NetdCallback mNetdCallback;
 
     /**
      * TestNetworkService (lazily) created upon first usage. Locked to prevent creation of multiple
@@ -559,6 +565,11 @@
     private static final int EVENT_SET_OEM_NETWORK_PREFERENCE = 48;
 
     /**
+     * Used to indicate the system default network becomes active.
+     */
+    private static final int EVENT_REPORT_NETWORK_ACTIVITY = 49;
+
+    /**
      * Argument for {@link #EVENT_PROVISIONING_NOTIFICATION} to indicate that the notification
      * should be shown.
      */
@@ -1192,7 +1203,14 @@
         mUserAllContext.registerReceiver(mIntentReceiver, intentFilter,
                 null /* broadcastPermission */, mHandler);
 
-        mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mNMS);
+        mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNMS, mNetd);
+
+        mNetdCallback = new NetdCallback();
+        try {
+            mNetd.registerUnsolicitedEventListener(mNetdCallback);
+        } catch (RemoteException | ServiceSpecificException e) {
+            loge("Error registering event listener :" + e);
+        }
 
         mSettingsObserver = new SettingsObserver(mContext, mHandler);
         registerSettingsCallbacks();
@@ -1231,6 +1249,7 @@
     private static NetworkCapabilities createDefaultNetworkCapabilitiesForUid(int uid) {
         final NetworkCapabilities netCap = new NetworkCapabilities();
         netCap.addCapability(NET_CAPABILITY_INTERNET);
+        netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         netCap.removeCapability(NET_CAPABILITY_NOT_VPN);
         netCap.setSingleUid(uid);
         return netCap;
@@ -1245,6 +1264,7 @@
             int transportType, NetworkRequest.Type type) {
         final NetworkCapabilities netCap = new NetworkCapabilities();
         netCap.addCapability(NET_CAPABILITY_INTERNET);
+        netCap.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName());
         if (transportType > TYPE_NONE) {
             netCap.addTransportType(transportType);
@@ -1502,7 +1522,7 @@
 
     @Override
     public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
-        NetworkStack.checkNetworkStackPermission(mContext);
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         return getActiveNetworkForUidInternal(uid, ignoreBlocked);
     }
 
@@ -1525,7 +1545,7 @@
 
     @Override
     public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
-        NetworkStack.checkNetworkStackPermission(mContext);
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         final NetworkState state = getUnfilteredActiveNetworkState(uid);
         filterNetworkStateForUid(state, uid, ignoreBlocked);
         return state.networkInfo;
@@ -1869,7 +1889,7 @@
     @Override
     public NetworkState[] getAllNetworkState() {
         // This contains IMSI details, so make sure the caller is privileged.
-        NetworkStack.checkNetworkStackPermission(mContext);
+        PermissionUtils.enforceNetworkStackPermission(mContext);
 
         final ArrayList<NetworkState> result = new ArrayList<>();
         for (Network network : getAllNetworks()) {
@@ -2293,7 +2313,7 @@
 
     // Public because it's used by mLockdownTracker.
     public void sendConnectedBroadcast(NetworkInfo info) {
-        NetworkStack.checkNetworkStackPermission(mContext);
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
     }
 
@@ -2404,7 +2424,7 @@
      */
     @Override
     public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
-        // TODO: Replace network activity listener registry in ConnectivityManager from NMS to here
+        mNetworkActivityTracker.registerNetworkActivityListener(l);
     }
 
     /**
@@ -2412,7 +2432,7 @@
      */
     @Override
     public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
-        // TODO: Replace network activity listener registry in ConnectivityManager from NMS to here
+        mNetworkActivityTracker.unregisterNetworkActivityListener(l);
     }
 
     /**
@@ -2420,8 +2440,7 @@
      */
     @Override
     public boolean isDefaultNetworkActive() {
-        // TODO: Replace isNetworkActive() in NMS.
-        return false;
+        return mNetworkActivityTracker.isDefaultNetworkActive();
     }
 
     /**
@@ -2558,13 +2577,13 @@
         if (!checkDumpPermission(mContext, TAG, pw)) return;
         if (asProto) return;
 
-        if (ArrayUtils.contains(args, DIAG_ARG)) {
+        if (CollectionUtils.contains(args, DIAG_ARG)) {
             dumpNetworkDiagnostics(pw);
             return;
-        } else if (ArrayUtils.contains(args, NETWORK_ARG)) {
+        } else if (CollectionUtils.contains(args, NETWORK_ARG)) {
             dumpNetworks(pw);
             return;
-        } else if (ArrayUtils.contains(args, REQUEST_ARG)) {
+        } else if (CollectionUtils.contains(args, REQUEST_ARG)) {
             dumpNetworkRequests(pw);
             return;
         }
@@ -2635,7 +2654,7 @@
 
         pw.println();
 
-        if (ArrayUtils.contains(args, SHORT_ARG) == false) {
+        if (!CollectionUtils.contains(args, SHORT_ARG)) {
             pw.println();
             pw.println("mNetworkRequestInfoLogs (most recent first):");
             pw.increaseIndent();
@@ -2686,6 +2705,12 @@
         pw.increaseIndent();
         mPermissionMonitor.dump(pw);
         pw.decreaseIndent();
+
+        pw.println();
+        pw.println("Legacy network activity:");
+        pw.increaseIndent();
+        mNetworkActivityTracker.dump(pw);
+        pw.decreaseIndent();
     }
 
     private void dumpNetworks(IndentingPrintWriter pw) {
@@ -4452,6 +4477,9 @@
                         loge("handleMessage.EVENT_SET_OEM_NETWORK_PREFERENCE failed", e);
                     }
                     break;
+                case EVENT_REPORT_NETWORK_ACTIVITY:
+                    mNetworkActivityTracker.handleReportNetworkActivity();
+                    break;
             }
         }
     }
@@ -4668,7 +4696,7 @@
 
     @Override
     public void setGlobalProxy(final ProxyInfo proxyProperties) {
-        NetworkStack.checkNetworkStackPermission(mContext);
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         mProxyTracker.setGlobalProxy(proxyProperties);
     }
 
@@ -4793,7 +4821,7 @@
             }
         }
 
-        if (ArrayUtils.isEmpty(underlyingNetworks)) return null;
+        if (CollectionUtils.isEmpty(underlyingNetworks)) return null;
 
         List<String> interfaces = new ArrayList<>();
         for (Network network : underlyingNetworks) {
@@ -4837,7 +4865,7 @@
         if (!nai.supportsUnderlyingNetworks()) return false;
         final Network[] underlying = underlyingNetworksOrDefault(
                 nai.networkCapabilities.getOwnerUid(), nai.declaredUnderlyingNetworks);
-        return ArrayUtils.contains(underlying, network);
+        return CollectionUtils.contains(underlying, network);
     }
 
     /**
@@ -4870,7 +4898,7 @@
 
     @Override
     public void setRequireVpnForUids(boolean requireVpn, UidRange[] ranges) {
-        NetworkStack.checkNetworkStackPermission(mContext);
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_REQUIRE_VPN_FOR_UIDS,
                 encodeBool(requireVpn), 0 /* arg2 */, ranges));
     }
@@ -5301,8 +5329,7 @@
                 }
             }
         }
-        // TODO: use NetworkStackUtils.convertToIntArray after moving it
-        return ArrayUtils.convertToIntArray(new ArrayList<>(thresholds));
+        return CollectionUtils.toIntArray(new ArrayList<>(thresholds));
     }
 
     private void updateSignalStrengthThresholds(
@@ -6421,7 +6448,7 @@
             @NonNull NetworkCapabilities agentCaps, @NonNull NetworkCapabilities newNc) {
         underlyingNetworks = underlyingNetworksOrDefault(
                 agentCaps.getOwnerUid(), underlyingNetworks);
-        int[] transportTypes = agentCaps.getTransportTypes();
+        long transportTypes = BitUtils.packBits(agentCaps.getTransportTypes());
         int downKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
         int upKbps = NetworkCapabilities.LINK_BANDWIDTH_UNSPECIFIED;
         // metered if any underlying is metered, or originally declared metered by the agent.
@@ -6440,7 +6467,7 @@
                 final NetworkCapabilities underlyingCaps = underlying.networkCapabilities;
                 hadUnderlyingNetworks = true;
                 for (int underlyingType : underlyingCaps.getTransportTypes()) {
-                    transportTypes = ArrayUtils.appendInt(transportTypes, underlyingType);
+                    transportTypes |= 1L << underlyingType;
                 }
 
                 // Merge capabilities of this underlying network. For bandwidth, assume the
@@ -6471,7 +6498,7 @@
             suspended = false;
         }
 
-        newNc.setTransportTypes(transportTypes);
+        newNc.setTransportTypes(BitUtils.unpackBits(transportTypes));
         newNc.setLinkDownstreamBandwidthKbps(downKbps);
         newNc.setLinkUpstreamBandwidthKbps(upKbps);
         newNc.setCapability(NET_CAPABILITY_NOT_METERED, !metered);
@@ -8536,14 +8563,14 @@
         for (NetworkAgentInfo virtual : mNetworkAgentInfos) {
             if (virtual.supportsUnderlyingNetworks()
                     && virtual.networkCapabilities.getOwnerUid() == callbackUid
-                    && ArrayUtils.contains(virtual.declaredUnderlyingNetworks, nai.network)) {
+                    && CollectionUtils.contains(virtual.declaredUnderlyingNetworks, nai.network)) {
                 return true;
             }
         }
 
         // Administrator UIDs also contains the Owner UID
         final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
-        return ArrayUtils.contains(administratorUids, callbackUid);
+        return CollectionUtils.contains(administratorUids, callbackUid);
     }
 
     @Override
@@ -8632,6 +8659,14 @@
         notifyDataStallSuspected(p, network.getNetId());
     }
 
+    private class NetdCallback extends BaseNetdUnsolicitedEventListener {
+        @Override
+        public void onInterfaceClassActivityChanged(boolean isActive, int timerLabel,
+                long timestampNs, int uid) {
+            mNetworkActivityTracker.setAndReportNetworkActive(isActive, timerLabel, timestampNs);
+        }
+    }
+
     private final LegacyNetworkActivityTracker mNetworkActivityTracker;
 
     /**
@@ -8639,30 +8674,78 @@
      * changes.
      */
     private static final class LegacyNetworkActivityTracker {
+        private static final int NO_UID = -1;
         private final Context mContext;
-        private final INetworkManagementService mNMS;
+        private final INetd mNetd;
+        private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
+                new RemoteCallbackList<>();
+        // Indicate the current system default network activity is active or not.
+        @GuardedBy("mActiveIdleTimers")
+        private boolean mNetworkActive;
+        @GuardedBy("mActiveIdleTimers")
+        private final ArrayMap<String, IdleTimerParams> mActiveIdleTimers = new ArrayMap();
+        private final Handler mHandler;
 
-        LegacyNetworkActivityTracker(@NonNull Context context,
-                @NonNull INetworkManagementService nms) {
-            mContext = context;
-            mNMS = nms;
-            try {
-                mNMS.registerObserver(mDataActivityObserver);
-            } catch (RemoteException e) {
-                loge("Error registering observer :" + e);
+        private class IdleTimerParams {
+            public final int timeout;
+            public final int transportType;
+
+            IdleTimerParams(int timeout, int transport) {
+                this.timeout = timeout;
+                this.transportType = transport;
             }
         }
 
-        // TODO: Migrate away the dependency with INetworkManagementEventObserver.
-        private final INetworkManagementEventObserver mDataActivityObserver =
-                new BaseNetworkObserver() {
-                    @Override
-                    public void interfaceClassDataActivityChanged(int transportType, boolean active,
-                            long tsNanos, int uid) {
-                        sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active,
-                                tsNanos);
+        LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler,
+                @NonNull INetworkManagementService nms, @NonNull INetd netd) {
+            mContext = context;
+            mNetd = netd;
+            mHandler = handler;
+        }
+
+        public void setAndReportNetworkActive(boolean active, int transportType, long tsNanos) {
+            sendDataActivityBroadcast(transportTypeToLegacyType(transportType), active, tsNanos);
+            synchronized (mActiveIdleTimers) {
+                mNetworkActive = active;
+                // If there are no idle timers, it means that system is not monitoring
+                // activity, so the system default network for those default network
+                // unspecified apps is always considered active.
+                //
+                // TODO: If the mActiveIdleTimers is empty, netd will actually not send
+                // any network activity change event. Whenever this event is received,
+                // the mActiveIdleTimers should be always not empty. The legacy behavior
+                // is no-op. Remove to refer to mNetworkActive only.
+                if (mNetworkActive || mActiveIdleTimers.isEmpty()) {
+                    mHandler.sendMessage(mHandler.obtainMessage(EVENT_REPORT_NETWORK_ACTIVITY));
+                }
+            }
+        }
+
+        // The network activity should only be updated from ConnectivityService handler thread
+        // when mActiveIdleTimers lock is held.
+        @GuardedBy("mActiveIdleTimers")
+        private void reportNetworkActive() {
+            final int length = mNetworkActivityListeners.beginBroadcast();
+            if (DDBG) log("reportNetworkActive, notify " + length + " listeners");
+            try {
+                for (int i = 0; i < length; i++) {
+                    try {
+                        mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
+                    } catch (RemoteException | RuntimeException e) {
+                        loge("Fail to send network activie to listener " + e);
                     }
-                };
+                }
+            } finally {
+                mNetworkActivityListeners.finishBroadcast();
+            }
+        }
+
+        @GuardedBy("mActiveIdleTimers")
+        public void handleReportNetworkActivity() {
+            synchronized (mActiveIdleTimers) {
+                reportNetworkActive();
+            }
+        }
 
         // This is deprecated and only to support legacy use cases.
         private int transportTypeToLegacyType(int type) {
@@ -8728,10 +8811,17 @@
                 return; // do not track any other networks
             }
 
+            updateRadioPowerState(true /* isActive */, type);
+
             if (timeout > 0 && iface != null) {
                 try {
-                    // TODO: Access INetd directly instead of NMS
-                    mNMS.addIdleTimer(iface, timeout, type);
+                    synchronized (mActiveIdleTimers) {
+                        // Networks start up.
+                        mNetworkActive = true;
+                        mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
+                        mNetd.idletimerAddInterface(iface, timeout, Integer.toString(type));
+                        reportNetworkActive();
+                    }
                 } catch (Exception e) {
                     // You shall not crash!
                     loge("Exception in setupDataActivityTracking " + e);
@@ -8746,16 +8836,28 @@
             final String iface = networkAgent.linkProperties.getInterfaceName();
             final NetworkCapabilities caps = networkAgent.networkCapabilities;
 
-            if (iface != null && (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
-                    || caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))) {
-                try {
-                    // the call fails silently if no idle timer setup for this interface
-                    // TODO: Access INetd directly instead of NMS
-                    mNMS.removeIdleTimer(iface);
-                } catch (Exception e) {
-                    // You shall not crash!
-                    loge("Exception in removeDataActivityTracking " + e);
+            if (iface == null) return;
+
+            final int type;
+            if (caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
+                type = NetworkCapabilities.TRANSPORT_CELLULAR;
+            } else if (caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+                type = NetworkCapabilities.TRANSPORT_WIFI;
+            } else {
+                return; // do not track any other networks
+            }
+
+            try {
+                updateRadioPowerState(false /* isActive */, type);
+                synchronized (mActiveIdleTimers) {
+                    final IdleTimerParams params = mActiveIdleTimers.remove(iface);
+                    // The call fails silently if no idle timer setup for this interface
+                    mNetd.idletimerRemoveInterface(iface, params.timeout,
+                            Integer.toString(params.transportType));
                 }
+            } catch (Exception e) {
+                // You shall not crash!
+                loge("Exception in removeDataActivityTracking " + e);
             }
         }
 
@@ -8771,6 +8873,53 @@
                 removeDataActivityTracking(oldNetwork);
             }
         }
+
+        private void updateRadioPowerState(boolean isActive, int transportType) {
+            final BatteryStatsManager bs = mContext.getSystemService(BatteryStatsManager.class);
+            switch (transportType) {
+                case NetworkCapabilities.TRANSPORT_CELLULAR:
+                    bs.reportMobileRadioPowerState(isActive, NO_UID);
+                    break;
+                case NetworkCapabilities.TRANSPORT_WIFI:
+                    bs.reportWifiRadioPowerState(isActive, NO_UID);
+                    break;
+                default:
+                    logw("Untracked transport type:" + transportType);
+            }
+        }
+
+        public boolean isDefaultNetworkActive() {
+            synchronized (mActiveIdleTimers) {
+                // If there are no idle timers, it means that system is not monitoring activity,
+                // so the default network is always considered active.
+                //
+                // TODO : Distinguish between the cases where mActiveIdleTimers is empty because
+                // tracking is disabled (negative idle timer value configured), or no active default
+                // network. In the latter case, this reports active but it should report inactive.
+                return mNetworkActive || mActiveIdleTimers.isEmpty();
+            }
+        }
+
+        public void registerNetworkActivityListener(@NonNull INetworkActivityListener l) {
+            mNetworkActivityListeners.register(l);
+        }
+
+        public void unregisterNetworkActivityListener(@NonNull INetworkActivityListener l) {
+            mNetworkActivityListeners.unregister(l);
+        }
+
+        public void dump(IndentingPrintWriter pw) {
+            synchronized (mActiveIdleTimers) {
+                pw.print("mNetworkActive="); pw.println(mNetworkActive);
+                pw.println("Idle timers:");
+                for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
+                    pw.print("  "); pw.print(ent.getKey()); pw.println(":");
+                    final IdleTimerParams params = ent.getValue();
+                    pw.print("    timeout="); pw.print(params.timeout);
+                    pw.print(" type="); pw.println(params.transportType);
+                }
+            }
+        }
     }
 
     /**
@@ -8888,7 +9037,8 @@
 
     private void updateDefaultNetworksForOemNetworkPreference(
             @NonNull final Set<NetworkRequestInfo> nris) {
-        handleRemoveNetworkRequests(mDefaultNetworkRequests);
+        // Pass in a defensive copy as this collection will be updated on remove.
+        handleRemoveNetworkRequests(new ArraySet<>(mDefaultNetworkRequests));
         addPerAppDefaultNetworkRequests(nris);
     }
 
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index 88ce220..e29e894 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -28,6 +28,7 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.image.IDynamicSystemService;
+import android.os.storage.DiskInfo;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 import android.util.Slog;
@@ -40,6 +41,7 @@
  */
 public class DynamicSystemService extends IDynamicSystemService.Stub {
     private static final String TAG = "DynamicSystemService";
+    private static final long MINIMUM_SD_MB = (30L << 10);
     private static final int GSID_ROUGH_TIMEOUT_MS = 8192;
     private static final String PATH_DEFAULT = "/data/gsi/";
     private Context mContext;
@@ -95,6 +97,13 @@
                 if (!volume.isMountedWritable()) {
                     continue;
                 }
+                DiskInfo disk = volume.getDisk();
+                long mega = disk.size >> 20;
+                Slog.i(TAG, volume.getPath() + ": " + mega + " MB");
+                if (mega < MINIMUM_SD_MB) {
+                    Slog.i(TAG, volume.getPath() + ": insufficient storage");
+                    continue;
+                }
                 File sd_internal = volume.getInternalPathForUser(userId);
                 if (sd_internal != null) {
                     path = new File(sd_internal, dsuSlot).getPath();
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index b48bc90..81d4b9d 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -48,7 +48,6 @@
 import android.net.util.NetdService;
 import android.os.Binder;
 import android.os.IBinder;
-import android.os.INetworkManagementService;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
@@ -64,6 +63,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
+import com.android.net.module.util.NetdUtils;
 
 import libcore.io.IoUtils;
 
@@ -117,9 +117,6 @@
     /* Binder context for this service */
     private final Context mContext;
 
-    /* NetworkManager instance */
-    private final INetworkManagementService mNetworkManager;
-
     /**
      * The next non-repeating global ID for tracking resources between users, this service, and
      * kernel data structures. Accessing this variable is not thread safe, so it is only read or
@@ -1014,13 +1011,13 @@
      *
      * @param context Binder context for this service
      */
-    private IpSecService(Context context, INetworkManagementService networkManager) {
-        this(context, networkManager, IpSecServiceConfiguration.GETSRVINSTANCE);
+    private IpSecService(Context context) {
+        this(context, IpSecServiceConfiguration.GETSRVINSTANCE);
     }
 
-    static IpSecService create(Context context, INetworkManagementService networkManager)
+    static IpSecService create(Context context)
             throws InterruptedException {
-        final IpSecService service = new IpSecService(context, networkManager);
+        final IpSecService service = new IpSecService(context);
         service.connectNativeNetdService();
         return service;
     }
@@ -1034,11 +1031,9 @@
 
     /** @hide */
     @VisibleForTesting
-    public IpSecService(Context context, INetworkManagementService networkManager,
-            IpSecServiceConfiguration config) {
+    public IpSecService(Context context, IpSecServiceConfiguration config) {
         this(
                 context,
-                networkManager,
                 config,
                 (fd, uid) -> {
                     try {
@@ -1052,10 +1047,9 @@
 
     /** @hide */
     @VisibleForTesting
-    public IpSecService(Context context, INetworkManagementService networkManager,
-            IpSecServiceConfiguration config, UidFdTagger uidFdTagger) {
+    public IpSecService(Context context, IpSecServiceConfiguration config,
+            UidFdTagger uidFdTagger) {
         mContext = context;
-        mNetworkManager = Objects.requireNonNull(networkManager);
         mSrvConfig = config;
         mUidFdTagger = uidFdTagger;
     }
@@ -1335,7 +1329,7 @@
             netd.ipSecAddTunnelInterface(intfName, localAddr, remoteAddr, ikey, okey, resourceId);
 
             Binder.withCleanCallingIdentity(() -> {
-                mNetworkManager.setInterfaceUp(intfName);
+                NetdUtils.setInterfaceUp(netd, intfName);
             });
 
             for (int selAddrFamily : ADDRESS_FAMILIES) {
diff --git a/services/core/java/com/android/server/LocalManagerRegistry.java b/services/core/java/com/android/server/LocalManagerRegistry.java
new file mode 100644
index 0000000..85795ff
--- /dev/null
+++ b/services/core/java/com/android/server/LocalManagerRegistry.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.util.ArrayMap;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * The registry for in-process module interfaces.
+ * <p>
+ * In-process module interfaces should be named with the suffix {@code ManagerLocal} for
+ * consistency.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+public final class LocalManagerRegistry {
+    private LocalManagerRegistry() {}
+
+    @NonNull
+    private static final Map<Class<?>, Object> sManagers = new ArrayMap<>();
+
+    /**
+     * Get a manager from the registry.
+     *
+     * @param managerClass the class that the manager implements
+     * @return the manager, or {@code null} if not found
+     */
+    @Nullable
+    @SuppressWarnings("unchecked")
+    public static <T> T getManager(@NonNull Class<T> managerClass) {
+        synchronized (sManagers) {
+            return (T) sManagers.get(managerClass);
+        }
+    }
+
+    /**
+     * Adds a manager to the registry.
+     *
+     * @param managerClass the class that the manager implements
+     * @param manager the manager
+     * @throws IllegalStateException if the manager class is already registered
+     */
+    public static <T> void addManager(@NonNull Class<T> managerClass, @NonNull T manager) {
+        Objects.requireNonNull(managerClass, "managerClass");
+        Objects.requireNonNull(manager, "manager");
+        synchronized (sManagers) {
+            if (sManagers.containsKey(managerClass)) {
+                throw new IllegalStateException(managerClass.getName() + " is already registered");
+            }
+            sManagers.put(managerClass, manager);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index d30a640..4405408 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -69,7 +69,6 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.INetworkActivityListener;
 import android.os.INetworkManagementService;
 import android.os.Process;
 import android.os.RemoteCallbackList;
@@ -80,7 +79,6 @@
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.Trace;
-import android.telephony.DataConnectionRealTimeInfo;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.Slog;
@@ -229,32 +227,9 @@
     @GuardedBy("mQuotaLock")
     private volatile boolean mDataSaverMode;
 
-    private final Object mIdleTimerLock = new Object();
-    /** Set of interfaces with active idle timers. */
-    private static class IdleTimerParams {
-        public final int timeout;
-        public final int type;
-        public int networkCount;
-
-        IdleTimerParams(int timeout, int type) {
-            this.timeout = timeout;
-            this.type = type;
-            this.networkCount = 1;
-        }
-    }
-    private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap();
-
     private volatile boolean mFirewallEnabled;
     private volatile boolean mStrictEnabled;
 
-    private boolean mMobileActivityFromRadio = false;
-    private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
-    private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
-
-    private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners =
-            new RemoteCallbackList<>();
-    private boolean mNetworkActive;
-
     /**
      * Constructs a new NetworkManagementService instance
      *
@@ -397,55 +372,8 @@
      */
     private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos,
             int uid) {
-        final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type);
-        int powerState = isActive
-                ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
-                : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
-        if (isMobile) {
-            if (mLastPowerStateFromRadio != powerState) {
-                mLastPowerStateFromRadio = powerState;
-                try {
-                    // TODO: The interface changes that comes from netd are handled by BSS itself.
-                    // There are still events caused by setting or removing idle timer, so keep
-                    // reporting from here until setting idler timer moved to CS.
-                    getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid);
-                } catch (RemoteException e) {
-                }
-            }
-        }
-
-        if (ConnectivityManager.isNetworkTypeWifi(type)) {
-            if (mLastPowerStateFromWifi != powerState) {
-                mLastPowerStateFromWifi = powerState;
-                try {
-                    // TODO: The interface changes that comes from netd are handled by BSS itself.
-                    // There are still events caused by setting or removing idle timer, so keep
-                    // reporting from here until setting idler timer moved to CS.
-                    getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid);
-                } catch (RemoteException e) {
-                }
-            }
-        }
-
-        final boolean active = isActive;
         invokeForAllObservers(o -> o.interfaceClassDataActivityChanged(
-                type, active, tsNanos, uid));
-
-        boolean report = false;
-        synchronized (mIdleTimerLock) {
-            if (mActiveIdleTimers.isEmpty()) {
-                // If there are no idle timers, we are not monitoring activity, so we
-                // are always considered active.
-                isActive = true;
-            }
-            if (mNetworkActive != isActive) {
-                mNetworkActive = isActive;
-                report = isActive;
-            }
-        }
-        if (report) {
-            reportNetworkActive();
-        }
+                type, isActive, tsNanos, uid));
     }
 
     @Override
@@ -1122,60 +1050,6 @@
     }
 
     @Override
-    public void addIdleTimer(String iface, int timeout, final int type) {
-        NetworkStack.checkNetworkStackPermission(mContext);
-
-        if (DBG) Slog.d(TAG, "Adding idletimer");
-
-        synchronized (mIdleTimerLock) {
-            IdleTimerParams params = mActiveIdleTimers.get(iface);
-            if (params != null) {
-                // the interface already has idletimer, update network count
-                params.networkCount++;
-                return;
-            }
-
-            try {
-                mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type));
-            } catch (RemoteException | ServiceSpecificException e) {
-                throw new IllegalStateException(e);
-            }
-            mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
-
-            // Networks start up.
-            if (ConnectivityManager.isNetworkTypeMobile(type)) {
-                mNetworkActive = false;
-            }
-            mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true,
-                    SystemClock.elapsedRealtimeNanos(), -1));
-        }
-    }
-
-    @Override
-    public void removeIdleTimer(String iface) {
-        NetworkStack.checkNetworkStackPermission(mContext);
-
-        if (DBG) Slog.d(TAG, "Removing idletimer");
-
-        synchronized (mIdleTimerLock) {
-            final IdleTimerParams params = mActiveIdleTimers.get(iface);
-            if (params == null || --(params.networkCount) > 0) {
-                return;
-            }
-
-            try {
-                mNetdService.idletimerRemoveInterface(iface,
-                        params.timeout, Integer.toString(params.type));
-            } catch (RemoteException | ServiceSpecificException e) {
-                throw new IllegalStateException(e);
-            }
-            mActiveIdleTimers.remove(iface);
-            mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false,
-                    SystemClock.elapsedRealtimeNanos(), -1));
-        }
-    }
-
-    @Override
     public void setInterfaceQuota(String iface, long quotaBytes) {
         NetworkStack.checkNetworkStackPermission(mContext);
 
@@ -1813,44 +1687,9 @@
     }
 
     @Override
-    public void registerNetworkActivityListener(INetworkActivityListener listener) {
-        mNetworkActivityListeners.register(listener);
-    }
-
-    @Override
-    public void unregisterNetworkActivityListener(INetworkActivityListener listener) {
-        mNetworkActivityListeners.unregister(listener);
-    }
-
-    @Override
-    public boolean isNetworkActive() {
-        synchronized (mNetworkActivityListeners) {
-            return mNetworkActive || mActiveIdleTimers.isEmpty();
-        }
-    }
-
-    private void reportNetworkActive() {
-        final int length = mNetworkActivityListeners.beginBroadcast();
-        try {
-            for (int i = 0; i < length; i++) {
-                try {
-                    mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive();
-                } catch (RemoteException | RuntimeException e) {
-                }
-            }
-        } finally {
-            mNetworkActivityListeners.finishBroadcast();
-        }
-    }
-
-    @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
-        pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio);
-                pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio);
-        pw.print("mNetworkActive="); pw.println(mNetworkActive);
-
         synchronized (mQuotaLock) {
             pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString());
             pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString());
@@ -1882,17 +1721,6 @@
                     mUidFirewallRestrictedRules);
         }
 
-        synchronized (mIdleTimerLock) {
-            pw.println("Idle timers:");
-            for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) {
-                pw.print("  "); pw.print(ent.getKey()); pw.println(":");
-                IdleTimerParams params = ent.getValue();
-                pw.print("    timeout="); pw.print(params.timeout);
-                pw.print(" type="); pw.print(params.type);
-                pw.print(" networkCount="); pw.println(params.networkCount);
-            }
-        }
-
         pw.print("Firewall enabled: "); pw.println(mFirewallEnabled);
         pw.print("Netd service status: " );
         if (mNetdService == null) {
diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING
index a927fa2..0ea88f4 100644
--- a/services/core/java/com/android/server/TEST_MAPPING
+++ b/services/core/java/com/android/server/TEST_MAPPING
@@ -36,7 +36,9 @@
                 }
             ],
             "file_patterns": ["NotificationManagerService\\.java"]
-        },
+        }
+    ],
+    "presubmit-large": [
         {
             "name": "CtsScopedStorageHostTest",
             "file_patterns": ["StorageManagerService\\.java"]
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 81d2b83..93f1432 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -312,9 +312,9 @@
 
     private List<PhysicalChannelConfig> mPhysicalChannelConfigs;
 
-    private boolean mIsDataEnabled = false;
+    private boolean[] mIsDataEnabled;
 
-    private int mDataEnabledReason;
+    private int[] mDataEnabledReason;
 
     /**
      * Per-phone map of precise data connection state. The key of the map is the pair of transport
@@ -521,6 +521,8 @@
         mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
         mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
         mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones);
+        mIsDataEnabled= copyOf(mIsDataEnabled, mNumPhones);
+        mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones);
 
         // ds -> ss switch.
         if (mNumPhones < oldNumPhones) {
@@ -563,6 +565,8 @@
             mBarringInfo.add(i, new BarringInfo());
             mTelephonyDisplayInfos[i] = null;
             mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build());
+            mIsDataEnabled[i] = false;
+            mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
         }
     }
 
@@ -622,6 +626,8 @@
         mBarringInfo = new ArrayList<>();
         mTelephonyDisplayInfos = new TelephonyDisplayInfo[numPhones];
         mPhysicalChannelConfigs = new ArrayList<>();
+        mIsDataEnabled = new boolean[numPhones];
+        mDataEnabledReason = new int[numPhones];
         for (int i = 0; i < numPhones; i++) {
             mCallState[i] =  TelephonyManager.CALL_STATE_IDLE;
             mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
@@ -652,6 +658,8 @@
             mBarringInfo.add(i, new BarringInfo());
             mTelephonyDisplayInfos[i] = null;
             mPhysicalChannelConfigs.add(i, new PhysicalChannelConfig.Builder().build());
+            mIsDataEnabled[i] = false;
+            mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
         }
 
         mAppOps = mContext.getSystemService(AppOpsManager.class);
@@ -1146,7 +1154,8 @@
                 if (events.contains(
                         PhoneStateListener.EVENT_DATA_ENABLED_CHANGED)) {
                     try {
-                        r.callback.onDataEnabledChanged(mIsDataEnabled, mDataEnabledReason);
+                        r.callback.onDataEnabledChanged(
+                                mIsDataEnabled[phoneId], mDataEnabledReason[phoneId]);
                     } catch (RemoteException ex) {
                         remove(r.binder);
                     }
@@ -2358,30 +2367,36 @@
     /**
      * Notify that the data enabled has changed.
      *
+     * @param phoneId the phone id.
+     * @param subId the subId.
      * @param enabled True if data is enabled, otherwise disabled.
      * @param reason  Reason for data enabled/disabled. See {@code DATA_*} in
      *                {@link TelephonyManager}.
      */
-    public void notifyDataEnabled(boolean enabled,
+    public void notifyDataEnabled(int phoneId, int subId, boolean enabled,
                                   @TelephonyManager.DataEnabledReason int reason) {
         if (!checkNotifyPermission("notifyDataEnabled()")) {
             return;
         }
 
         if (VDBG) {
-            log("notifyDataEnabled: enabled=" + enabled + " reason=" + reason);
+            log("notifyDataEnabled: PhoneId=" + phoneId + " subId=" + subId +
+                    " enabled=" + enabled + " reason=" + reason);
         }
 
-        mIsDataEnabled = enabled;
-        mDataEnabledReason = reason;
         synchronized (mRecords) {
-            for (Record r : mRecords) {
-                if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.EVENT_DATA_ENABLED_CHANGED)) {
-                    try {
-                        r.callback.onDataEnabledChanged(enabled, reason);
-                    } catch (RemoteException ex) {
-                        mRemoveList.add(r.binder);
+            if (validatePhoneId(phoneId)) {
+                mIsDataEnabled[phoneId] = enabled;
+                mDataEnabledReason[phoneId] = reason;
+                for (Record r : mRecords) {
+                    if (r.matchPhoneStateListenerEvent(
+                            PhoneStateListener.EVENT_DATA_ENABLED_CHANGED)
+                            && idMatch(r.subId, subId, phoneId)) {
+                        try {
+                            r.callback.onDataEnabledChanged(enabled, reason);
+                        } catch (RemoteException ex) {
+                            mRemoveList.add(r.binder);
+                        }
                     }
                 }
             }
@@ -2431,6 +2446,8 @@
                 pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]);
                 pw.println("mBarringInfo=" + mBarringInfo.get(i));
                 pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfos[i]);
+                pw.println("mIsDataEnabled=" + mIsDataEnabled);
+                pw.println("mDataEnabledReason=" + mDataEnabledReason);
                 pw.decreaseIndent();
             }
             pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState);
@@ -2441,8 +2458,6 @@
             pw.println("mDefaultPhoneId=" + mDefaultPhoneId);
             pw.println("mDefaultSubId=" + mDefaultSubId);
             pw.println("mPhysicalChannelConfigs=" + mPhysicalChannelConfigs);
-            pw.println("mIsDataEnabled=" + mIsDataEnabled);
-            pw.println("mDataEnabledReason=" + mDataEnabledReason);
 
             pw.decreaseIndent();
 
diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java
index 329ab99..8d5d3d9 100644
--- a/services/core/java/com/android/server/VcnManagementService.java
+++ b/services/core/java/com/android/server/VcnManagementService.java
@@ -16,6 +16,8 @@
 
 package com.android.server;
 
+import static android.net.vcn.VcnManager.VCN_STATUS_CODE_SAFE_MODE;
+
 import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import static com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionTrackerCallback;
 
@@ -837,7 +839,10 @@
                 // Notify all registered StatusCallbacks for this subGroup
                 for (VcnStatusCallbackInfo cbInfo : mRegisteredStatusCallbacks.values()) {
                     if (isCallbackPermissioned(cbInfo)) {
-                        Binder.withCleanCallingIdentity(() -> cbInfo.mCallback.onEnteredSafeMode());
+                        Binder.withCleanCallingIdentity(
+                                () ->
+                                        cbInfo.mCallback.onVcnStatusChanged(
+                                                VCN_STATUS_CODE_SAFE_MODE));
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 900871d..e4d2382 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -183,6 +183,7 @@
 import android.app.PendingIntent;
 import android.app.ProcessMemoryState;
 import android.app.ProfilerInfo;
+import android.app.PropertyInvalidatedCache;
 import android.app.WaitResult;
 import android.app.backup.IBackupManager;
 import android.app.usage.UsageEvents;
@@ -8213,11 +8214,20 @@
                 false /* mountExtStorageFull */, abiOverride, zygotePolicyFlags);
     }
 
-    // TODO: Move to ProcessList?
     @GuardedBy("this")
     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
             boolean disableHiddenApiChecks, boolean mountExtStorageFull, String abiOverride,
             int zygotePolicyFlags) {
+        return addAppLocked(info, customProcess, isolated, disableHiddenApiChecks,
+                false /* disableTestApiChecks */, mountExtStorageFull, abiOverride,
+                zygotePolicyFlags);
+    }
+
+    // TODO: Move to ProcessList?
+    @GuardedBy("this")
+    final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
+            boolean disableHiddenApiChecks, boolean disableTestApiChecks,
+            boolean mountExtStorageFull, String abiOverride, int zygotePolicyFlags) {
         ProcessRecord app;
         if (!isolated) {
             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
@@ -8252,7 +8262,8 @@
             mPersistentStartingProcesses.add(app);
             mProcessList.startProcessLocked(app, new HostingRecord("added application",
                     customProcess != null ? customProcess : app.processName),
-                    zygotePolicyFlags, disableHiddenApiChecks, mountExtStorageFull, abiOverride);
+                    zygotePolicyFlags, disableHiddenApiChecks, disableTestApiChecks,
+                    mountExtStorageFull, abiOverride);
         }
 
         return app;
@@ -12834,6 +12845,10 @@
             if (r.thread != null) {
                 pw.println("\n\n** Cache info for pid " + r.pid + " [" + r.processName + "] **");
                 pw.flush();
+                if (r.pid == MY_PID) {
+                    PropertyInvalidatedCache.dumpCacheInfo(fd, args);
+                    continue;
+                }
                 try {
                     TransferPipe tp = new TransferPipe();
                     try {
@@ -13371,6 +13386,8 @@
                     }
                     endTime = SystemClock.currentThreadTimeMillis();
                     hasSwapPss = mi.hasSwappedOutPss;
+                    memtrackGraphics = mi.getOtherPrivate(Debug.MemoryInfo.OTHER_GRAPHICS);
+                    memtrackGl = mi.getOtherPrivate(Debug.MemoryInfo.OTHER_GL);
                 } else {
                     reportType = ProcessStats.ADD_PSS_EXTERNAL;
                     startTime = SystemClock.currentThreadTimeMillis();
@@ -13524,6 +13541,8 @@
                             if (!Debug.getMemoryInfo(st.pid, mi)) {
                                 continue;
                             }
+                            memtrackGraphics = mi.getOtherPrivate(Debug.MemoryInfo.OTHER_GRAPHICS);
+                            memtrackGl = mi.getOtherPrivate(Debug.MemoryInfo.OTHER_GL);
                         } else {
                             long pss = Debug.getPss(st.pid, tmpLong, memtrackTmp);
                             if (pss == 0) {
@@ -14424,6 +14443,8 @@
             });
         }
         final int statsCount = stats.size();
+        long totalMemtrackGraphics = 0;
+        long totalMemtrackGl = 0;
         for (int i = 0; i < statsCount; i++) {
             ProcessCpuTracker.Stats st = stats.get(i);
             long pss = Debug.getPss(st.pid, swaptrackTmp, memtrackTmp);
@@ -14434,6 +14455,8 @@
                     mi.pss = pss;
                     mi.swapPss = swaptrackTmp[1];
                     mi.memtrack = memtrackTmp[0];
+                    totalMemtrackGraphics += memtrackTmp[1];
+                    totalMemtrackGl += memtrackTmp[2];
                     memInfos.add(mi);
                 }
             }
@@ -14442,20 +14465,18 @@
         long totalPss = 0;
         long totalSwapPss = 0;
         long totalMemtrack = 0;
-        long totalMemtrackGraphics = 0;
-        long totalMemtrackGl = 0;
         for (int i=0, N=memInfos.size(); i<N; i++) {
             ProcessMemInfo mi = memInfos.get(i);
             if (mi.pss == 0) {
                 mi.pss = Debug.getPss(mi.pid, swaptrackTmp, memtrackTmp);
                 mi.swapPss = swaptrackTmp[1];
                 mi.memtrack = memtrackTmp[0];
+                totalMemtrackGraphics += memtrackTmp[1];
+                totalMemtrackGl += memtrackTmp[2];
             }
             totalPss += mi.pss;
             totalSwapPss += mi.swapPss;
             totalMemtrack += mi.memtrack;
-            totalMemtrackGraphics += memtrackTmp[1];
-            totalMemtrackGl += memtrackTmp[2];
         }
         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
@@ -17058,12 +17079,11 @@
                     || (flags & INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
             boolean disableTestApiChecks = disableHiddenApiChecks
                     || (flags & INSTR_FLAG_DISABLE_TEST_API_CHECKS) != 0;
-
             if (disableHiddenApiChecks || disableTestApiChecks) {
                 enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS,
                         "disable hidden API checks");
 
-                enableTestApiAccess(ai.packageName);
+                enableTestApiAccess(ii.packageName);
             }
 
             // TODO(b/158750470): remove
@@ -17081,7 +17101,8 @@
             }
 
             ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
-                    mountExtStorageFull, abiOverride, ZYGOTE_POLICY_FLAG_EMPTY);
+                    disableTestApiChecks, mountExtStorageFull, abiOverride,
+                    ZYGOTE_POLICY_FLAG_EMPTY);
             app.setActiveInstrumentation(activeInstr);
             activeInstr.mFinished = false;
             activeInstr.mSourceUid = callingUid;
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index a2eea13..b7ecddc 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -809,7 +809,8 @@
                         r.resultExtras, r.ordered, r.initialSticky, r.userId);
                 // parallel broadcasts are fire-and-forget, not bookended by a call to
                 // finishReceiverLocked(), so we manage their activity-start token here
-                if (r.allowBackgroundActivityStarts && !r.ordered) {
+                if (filter.receiverList.app != null
+                        && r.allowBackgroundActivityStarts && !r.ordered) {
                     postActivityStartTokenRemoval(filter.receiverList.app, r);
                 }
             }
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index e2c020af..c5a6e7b 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -367,6 +367,13 @@
     private static final long NATIVE_MEMTAG_SYNC = 177438394; // This is a bug id.
 
     /**
+     * Enable automatic zero-initialization of native heap memory allocations.
+     */
+    @ChangeId
+    @Disabled
+    private static final long NATIVE_HEAP_ZERO_INIT = 178038272; // This is a bug id.
+
+    /**
      * Enable sampled memory bug detection in the app.
      * @see <a href="https://source.android.com/devices/tech/debug/gwp-asan">GWP-ASan</a>.
      */
@@ -1687,12 +1694,28 @@
         return gidArray;
     }
 
-    // Returns the memory tagging level to be enabled. If memory tagging isn't
-    // requested, returns zero.
-    private int getMemtagLevel(ProcessRecord app) {
-        // Ensure the hardware + kernel actually supports MTE.
-        if (!Zygote.nativeSupportsMemoryTagging()) {
-            return 0;
+    private int memtagModeToZygoteMemtagLevel(int memtagMode) {
+        switch (memtagMode) {
+            case ApplicationInfo.MEMTAG_ASYNC:
+                return Zygote.MEMORY_TAG_LEVEL_ASYNC;
+            case ApplicationInfo.MEMTAG_SYNC:
+                return Zygote.MEMORY_TAG_LEVEL_SYNC;
+            default:
+                return Zygote.MEMORY_TAG_LEVEL_NONE;
+        }
+    }
+
+    // Returns the requested memory tagging level.
+    private int getRequestedMemtagLevel(ProcessRecord app) {
+        // Look at the process attribute first.
+        if (app.processInfo != null
+                && app.processInfo.memtagMode != ApplicationInfo.MEMTAG_DEFAULT) {
+            return memtagModeToZygoteMemtagLevel(app.processInfo.memtagMode);
+        }
+
+        // Then at the application attribute.
+        if (app.info.getMemtagMode() != ApplicationInfo.MEMTAG_DEFAULT) {
+            return memtagModeToZygoteMemtagLevel(app.info.getMemtagMode());
         }
 
         if (mPlatformCompat.isChangeEnabled(NATIVE_MEMTAG_SYNC, app.info)) {
@@ -1703,40 +1726,43 @@
             return Zygote.MEMORY_TAG_LEVEL_ASYNC;
         }
 
-        return 0;
-    }
-
-    private boolean shouldEnableTaggedPointers(ProcessRecord app) {
-        // Ensure we have platform + kernel support for TBI.
-        if (!Zygote.nativeSupportsTaggedPointers()) {
-            return false;
-        }
-
         // Check to ensure the app hasn't explicitly opted-out of TBI via. the manifest attribute.
         if (!app.info.allowsNativeHeapPointerTagging()) {
-            return false;
+            return Zygote.MEMORY_TAG_LEVEL_NONE;
         }
 
         // Check to see that the compat feature for TBI is enabled.
-        if (!mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private int decideTaggingLevel(ProcessRecord app) {
-        // Check MTE support first, as it should take precedence over TBI.
-        int memtagLevel = getMemtagLevel(app);
-        if (memtagLevel != 0) {
-            return memtagLevel;
-        }
-
-        if (shouldEnableTaggedPointers(app)) {
+        if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_POINTER_TAGGING, app.info)) {
             return Zygote.MEMORY_TAG_LEVEL_TBI;
         }
 
-        return 0;
+        return Zygote.MEMORY_TAG_LEVEL_NONE;
+    }
+
+    private int decideTaggingLevel(ProcessRecord app) {
+        // Get the desired tagging level (app manifest + compat features).
+        int level = getRequestedMemtagLevel(app);
+
+        // Take into account the hardware capabilities.
+        if (Zygote.nativeSupportsMemoryTagging()) {
+            // MTE devices can not do TBI, because the Zygote process already has live MTE
+            // allocations. Downgrade TBI to NONE.
+            if (level == Zygote.MEMORY_TAG_LEVEL_TBI) {
+                level = Zygote.MEMORY_TAG_LEVEL_NONE;
+            }
+        } else if (Zygote.nativeSupportsTaggedPointers()) {
+            // TBI-but-not-MTE devices downgrade MTE modes to TBI.
+            // The idea is that if an app opts into full hardware tagging (MTE), it must be ok with
+            // the "fake" pointer tagging (TBI).
+            if (level == Zygote.MEMORY_TAG_LEVEL_ASYNC || level == Zygote.MEMORY_TAG_LEVEL_SYNC) {
+                level = Zygote.MEMORY_TAG_LEVEL_TBI;
+            }
+        } else {
+            // Otherwise disable all tagging.
+            level = Zygote.MEMORY_TAG_LEVEL_NONE;
+        }
+
+        return level;
     }
 
     private int decideGwpAsanLevel(ProcessRecord app) {
@@ -1747,7 +1773,7 @@
                     ? Zygote.GWP_ASAN_LEVEL_ALWAYS
                     : Zygote.GWP_ASAN_LEVEL_NEVER;
         }
-        // Then at the applicaton attribute.
+        // Then at the application attribute.
         if (app.info.getGwpAsanMode() != ApplicationInfo.GWP_ASAN_DEFAULT) {
             return app.info.getGwpAsanMode() == ApplicationInfo.GWP_ASAN_ALWAYS
                     ? Zygote.GWP_ASAN_LEVEL_ALWAYS
@@ -1764,13 +1790,29 @@
         return Zygote.GWP_ASAN_LEVEL_NEVER;
     }
 
+    private boolean enableNativeHeapZeroInit(ProcessRecord app) {
+        // Look at the process attribute first.
+        if (app.processInfo != null && app.processInfo.nativeHeapZeroInit != null) {
+            return app.processInfo.nativeHeapZeroInit;
+        }
+        // Then at the application attribute.
+        if (app.info.isNativeHeapZeroInit() != null) {
+            return app.info.isNativeHeapZeroInit();
+        }
+        // Compat feature last.
+        if (mPlatformCompat.isChangeEnabled(NATIVE_HEAP_ZERO_INIT, app.info)) {
+            return true;
+        }
+        return false;
+    }
+
     /**
      * @return {@code true} if process start is successful, false otherwise.
      */
     @GuardedBy("mService")
     boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
-            int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean mountExtStorageFull,
-            String abiOverride) {
+            int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
+            boolean mountExtStorageFull, String abiOverride) {
         if (app.pendingStart) {
             return true;
         }
@@ -1914,6 +1956,10 @@
                     throw new IllegalStateException("Invalid API policy: " + policy);
                 }
                 runtimeFlags |= policyBits;
+
+                if (disableTestApiChecks) {
+                    runtimeFlags |= Zygote.DISABLE_TEST_API_ENFORCEMENT_POLICY;
+                }
             }
 
             String useAppImageCache = SystemProperties.get(
@@ -1967,6 +2013,10 @@
                 runtimeFlags |= decideTaggingLevel(app);
             }
 
+            if (enableNativeHeapZeroInit(app)) {
+                runtimeFlags |= Zygote.NATIVE_HEAP_ZERO_INIT;
+            }
+
             // the per-user SELinux context must be set
             if (TextUtils.isEmpty(app.info.seInfoUser)) {
                 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
@@ -2356,7 +2406,8 @@
     final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
             int zygotePolicyFlags, String abiOverride) {
         return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
-                false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
+                false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
+                false /* mountExtStorageFull */, abiOverride);
     }
 
     @GuardedBy("mService")
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index c5152c0..4775541 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -388,6 +388,9 @@
             if (processInfo.gwpAsanMode != ApplicationInfo.GWP_ASAN_DEFAULT) {
                 pw.print(prefix); pw.println("  gwpAsanMode=" + processInfo.gwpAsanMode);
             }
+            if (processInfo.memtagMode != ApplicationInfo.MEMTAG_DEFAULT) {
+                pw.print(prefix); pw.println("  memtagMode=" + processInfo.memtagMode);
+            }
         }
         pw.print(prefix); pw.print("mRequiredAbi="); pw.print(mRequiredAbi);
                 pw.print(" instructionSet="); pw.println(instructionSet);
@@ -645,9 +648,12 @@
             if (processes != null) {
                 procInfo = processes.get(_processName);
                 if (procInfo != null && procInfo.deniedPermissions == null
-                        && procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT) {
+                        && procInfo.gwpAsanMode == ApplicationInfo.GWP_ASAN_DEFAULT
+                        && procInfo.memtagMode == ApplicationInfo.MEMTAG_DEFAULT
+                        && procInfo.nativeHeapZeroInit == null) {
                     // If this process hasn't asked for permissions to be denied, or for a
-                    // non-default GwpAsan mode, then we don't care about it.
+                    // non-default GwpAsan mode, or any other non-default setting, then we don't
+                    // care about it.
                     procInfo = null;
                 }
             }
diff --git a/services/core/java/com/android/server/apphibernation/AppHibernationService.java b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
index e97f0b4..32ae878 100644
--- a/services/core/java/com/android/server/apphibernation/AppHibernationService.java
+++ b/services/core/java/com/android/server/apphibernation/AppHibernationService.java
@@ -23,9 +23,12 @@
 import static android.content.pm.PackageManager.MATCH_ANY_USER;
 import static android.provider.DeviceConfig.NAMESPACE_APP_HIBERNATION;
 
+import static com.android.server.apphibernation.AppHibernationConstants.KEY_APP_HIBERNATION_ENABLED;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ActivityThread;
 import android.app.IActivityManager;
 import android.apphibernation.IAppHibernationService;
 import android.content.BroadcastReceiver;
@@ -45,6 +48,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.DeviceConfig;
+import android.provider.DeviceConfig.Properties;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
@@ -52,10 +57,13 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.SystemService;
 
 import java.io.File;
 import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -93,6 +101,9 @@
     private final HibernationStateDiskStore<GlobalLevelState> mGlobalLevelHibernationDiskStore;
     private final Injector mInjector;
 
+    @VisibleForTesting
+    boolean mIsServiceEnabled;
+
     /**
      * Initializes the system service.
      * <p>
@@ -139,6 +150,13 @@
                 initializeGlobalHibernationStates(states);
             }
         }
+        if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
+            mIsServiceEnabled = isAppHibernationEnabled();
+            DeviceConfig.addOnPropertiesChangedListener(
+                    NAMESPACE_APP_HIBERNATION,
+                    ActivityThread.currentApplication().getMainExecutor(),
+                    this::onDeviceConfigChanged);
+        }
     }
 
     /**
@@ -149,6 +167,10 @@
      * @return true if package is hibernating for the user
      */
     boolean isHibernatingForUser(String packageName, int userId) {
+        if (!checkHibernationEnabled("isHibernatingForUser")) {
+            return false;
+        }
+
         userId = handleIncomingUser(userId, "isHibernating");
         if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
             Slog.e(TAG, "Attempt to get hibernation state of stopped or nonexistent user "
@@ -174,6 +196,9 @@
      * @param packageName package to check
      */
     boolean isHibernatingGlobally(String packageName) {
+        if (!checkHibernationEnabled("isHibernatingGlobally")) {
+            return false;
+        }
         synchronized (mLock) {
             GlobalLevelState state = mGlobalHibernationStates.get(packageName);
             if (state == null) {
@@ -192,6 +217,9 @@
      * @param isHibernating new hibernation state
      */
     void setHibernatingForUser(String packageName, int userId, boolean isHibernating) {
+        if (!checkHibernationEnabled("setHibernatingForUser")) {
+            return;
+        }
         userId = handleIncomingUser(userId, "setHibernating");
         if (!mUserManager.isUserUnlockingOrUnlocked(userId)) {
             Slog.w(TAG, "Attempt to set hibernation state for a stopped or nonexistent user "
@@ -229,6 +257,9 @@
      * @param isHibernating new hibernation state
      */
     void setHibernatingGlobally(String packageName, boolean isHibernating) {
+        if (!checkHibernationEnabled("setHibernatingGlobally")) {
+            return;
+        }
         synchronized (mLock) {
             GlobalLevelState state = mGlobalHibernationStates.get(packageName);
             if (state == null) {
@@ -421,6 +452,9 @@
 
     private void onPackageAdded(@NonNull String packageName, int userId) {
         synchronized (mLock) {
+            if (!mUserStates.contains(userId)) {
+                return;
+            }
             UserLevelState userState = new UserLevelState();
             userState.packageName = packageName;
             mUserStates.get(userId).put(packageName, userState);
@@ -434,6 +468,9 @@
 
     private void onPackageRemoved(@NonNull String packageName, int userId) {
         synchronized (mLock) {
+            if (!mUserStates.contains(userId)) {
+                return;
+            }
             mUserStates.get(userId).remove(packageName);
         }
     }
@@ -444,6 +481,15 @@
         }
     }
 
+    private void onDeviceConfigChanged(Properties properties) {
+        for (String key : properties.getKeyset()) {
+            if (TextUtils.equals(KEY_APP_HIBERNATION_ENABLED, key)) {
+                mIsServiceEnabled = isAppHibernationEnabled();
+                break;
+            }
+        }
+    }
+
     /**
      * Private helper method to get the real user id and enforce permission checks.
      *
@@ -461,6 +507,44 @@
         }
     }
 
+    private boolean checkHibernationEnabled(String methodName) {
+        if (!mIsServiceEnabled) {
+            Slog.w(TAG, String.format("Attempted to call %s on unsupported device.", methodName));
+        }
+        return mIsServiceEnabled;
+    }
+
+    private void dump(PrintWriter pw) {
+        // Check usage stats permission since hibernation indirectly informs usage.
+        if (!DumpUtils.checkDumpAndUsageStatsPermission(getContext(), TAG, pw)) return;
+
+        IndentingPrintWriter idpw = new IndentingPrintWriter(pw, "  ");
+
+        synchronized (mLock) {
+            final int userCount = mUserStates.size();
+            for (int i = 0; i < userCount; i++) {
+                final int userId = mUserStates.keyAt(i);
+                idpw.print("User Level Hibernation States, ");
+                idpw.printPair("user", userId);
+                idpw.println();
+                Map<String, UserLevelState> stateMap = mUserStates.get(i);
+                idpw.increaseIndent();
+                for (UserLevelState state : stateMap.values()) {
+                    idpw.print(state);
+                    idpw.println();
+                }
+                idpw.decreaseIndent();
+            }
+            idpw.println();
+            idpw.print("Global Level Hibernation States");
+            idpw.println();
+            for (GlobalLevelState state : mGlobalHibernationStates.values()) {
+                idpw.print(state);
+                idpw.println();
+            }
+        }
+    }
+
     private final AppHibernationServiceStub mServiceStub = new AppHibernationServiceStub(this);
 
     static final class AppHibernationServiceStub extends IAppHibernationService.Stub {
@@ -497,6 +581,12 @@
             new AppHibernationShellCommand(mService).exec(this, in, out, err, args, callback,
                     resultReceiver);
         }
+
+        @Override
+        protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
+                @Nullable String[] args) {
+            mService.dump(fout);
+        }
     }
 
     // Broadcast receiver for package add/removal events
@@ -536,7 +626,7 @@
     public static boolean isAppHibernationEnabled() {
         return DeviceConfig.getBoolean(
                 NAMESPACE_APP_HIBERNATION,
-                AppHibernationConstants.KEY_APP_HIBERNATION_ENABLED,
+                KEY_APP_HIBERNATION_ENABLED,
                 false /* defaultValue */);
     }
 
diff --git a/services/core/java/com/android/server/apphibernation/GlobalLevelState.java b/services/core/java/com/android/server/apphibernation/GlobalLevelState.java
index 4f75675..baa84b7 100644
--- a/services/core/java/com/android/server/apphibernation/GlobalLevelState.java
+++ b/services/core/java/com/android/server/apphibernation/GlobalLevelState.java
@@ -22,4 +22,12 @@
 final class GlobalLevelState {
     public String packageName;
     public boolean hibernated;
+
+    @Override
+    public String toString() {
+        return "GlobalLevelState{"
+                + "packageName='" + packageName + '\''
+                + ", hibernated=" + hibernated
+                + '}';
+    }
 }
diff --git a/services/core/java/com/android/server/apphibernation/UserLevelState.java b/services/core/java/com/android/server/apphibernation/UserLevelState.java
index c66dad8..272d3d1 100644
--- a/services/core/java/com/android/server/apphibernation/UserLevelState.java
+++ b/services/core/java/com/android/server/apphibernation/UserLevelState.java
@@ -22,4 +22,12 @@
 final class UserLevelState {
     public String packageName;
     public boolean hibernated;
+
+    @Override
+    public String toString() {
+        return "UserLevelState{"
+                + "packageName='" + packageName + '\''
+                + ", hibernated=" + hibernated
+                + '}';
+    }
 }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 4c69704..e783229 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -6554,7 +6554,10 @@
     private void onSetVolumeIndexOnDevice(@NonNull DeviceVolumeUpdate update) {
         final VolumeStreamState streamState = mStreamStates[update.mStreamType];
         if (update.hasVolumeIndex()) {
-            final int index = update.getVolumeIndex();
+            int index = update.getVolumeIndex();
+            if (!checkSafeMediaVolume(update.mStreamType, index, update.mDevice)) {
+                index = safeMediaVolumeIndex(update.mDevice);
+            }
             streamState.setIndex(index, update.mDevice, update.mCaller,
                     // trusted as index is always validated before message is posted
                     true /*hasModifyAudioSettings*/);
@@ -8129,6 +8132,7 @@
         public void postDisplaySafeVolumeWarning(int flags) {
             if (mController == null)
                 return;
+            flags = flags | AudioManager.FLAG_SHOW_UI;
             try {
                 mController.displaySafeVolumeWarning(flags);
             } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 422991e..66a6520 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -50,6 +50,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
+import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -595,17 +596,23 @@
      * Rechecks all the existing overrides for a package.
      */
     void recheckOverrides(String packageName) {
+        // Local cache of compat changes. Holding a lock on mChanges for the whole duration of the
+        // method will cause a deadlock.
+        List<CompatChange> changes;
         synchronized (mChanges) {
-            boolean shouldInvalidateCache = false;
+            changes = new ArrayList<>(mChanges.size());
             for (int idx = 0; idx < mChanges.size(); ++idx) {
-                CompatChange c = mChanges.valueAt(idx);
-                OverrideAllowedState allowedState =
-                        mOverrideValidator.getOverrideAllowedState(c.getId(), packageName);
-                shouldInvalidateCache |= c.recheckOverride(packageName, allowedState, mContext);
+                changes.add(mChanges.valueAt(idx));
             }
-            if (shouldInvalidateCache) {
-                invalidateCache();
-            }
+        }
+        boolean shouldInvalidateCache = false;
+        for (CompatChange c: changes) {
+            OverrideAllowedState allowedState =
+                    mOverrideValidator.getOverrideAllowedState(c.getId(), packageName);
+            shouldInvalidateCache |= c.recheckOverride(packageName, allowedState, mContext);
+        }
+        if (shouldInvalidateCache) {
+            invalidateCache();
         }
     }
 
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 21ef356..4ecc759 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -26,6 +26,7 @@
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
+import static android.net.NetworkTemplate.OEM_MANAGED_ALL;
 import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
@@ -226,7 +227,7 @@
             mNetworkTemplate = new NetworkTemplate(
                     NetworkTemplate.MATCH_MOBILE, subscriberId, new String[] { subscriberId },
                     null, NetworkStats.METERED_ALL, NetworkStats.ROAMING_ALL,
-                    NetworkStats.DEFAULT_NETWORK_NO, NETWORK_TYPE_ALL);
+                    NetworkStats.DEFAULT_NETWORK_NO, NETWORK_TYPE_ALL, OEM_MANAGED_ALL);
             mUsageCallback = new UsageCallback() {
                 @Override
                 public void onThresholdReached(int networkType, String subscriberId) {
@@ -274,7 +275,8 @@
                     null /* networkId, unused for matching mobile networks */,
                     !nc.hasCapability(NET_CAPABILITY_NOT_ROAMING),
                     !nc.hasCapability(NET_CAPABILITY_NOT_METERED),
-                    false /* defaultNetwork, templates should have DEFAULT_NETWORK_ALL */);
+                    false /* defaultNetwork, templates should have DEFAULT_NETWORK_ALL */,
+                    OEM_MANAGED_ALL);
         }
 
         private long getRemainingDailyBudget(long limitBytes,
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 46c49e7..641287f 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -16,6 +16,8 @@
 
 package com.android.server.connectivity;
 
+import static com.android.net.module.util.CollectionUtils.contains;
+
 import android.annotation.NonNull;
 import android.net.ConnectivityManager;
 import android.net.IDnsResolver;
@@ -33,7 +35,6 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
 import com.android.net.module.util.NetworkStackConstants;
 import com.android.server.net.BaseNetworkObserver;
 
@@ -117,8 +118,8 @@
     @VisibleForTesting
     protected static boolean requiresClat(NetworkAgentInfo nai) {
         // TODO: migrate to NetworkCapabilities.TRANSPORT_*.
-        final boolean supported = ArrayUtils.contains(NETWORK_TYPES, nai.networkInfo.getType());
-        final boolean connected = ArrayUtils.contains(NETWORK_STATES, nai.networkInfo.getState());
+        final boolean supported = contains(NETWORK_TYPES, nai.networkInfo.getType());
+        final boolean connected = contains(NETWORK_STATES, nai.networkInfo.getState());
 
         // Only run clat on networks that have a global IPv6 address and don't have a native IPv4
         // address.
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index c05e253..4cf5274 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -899,7 +899,7 @@
                     ? networkAgentConfig.subscriberId : null;
             return new NetworkState(new NetworkInfo(networkInfo),
                     new LinkProperties(linkProperties),
-                    new NetworkCapabilities(networkCapabilities), network, subscriberId, null);
+                    new NetworkCapabilities(networkCapabilities), network, subscriberId);
         }
     }
 
diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
index 8bf1886..9411e33 100644
--- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java
+++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java
@@ -28,6 +28,8 @@
 import static android.os.Process.INVALID_UID;
 import static android.os.Process.SYSTEM_UID;
 
+import static com.android.net.module.util.CollectionUtils.toIntArray;
+
 import android.annotation.NonNull;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -40,23 +42,21 @@
 import android.os.Build;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
+import android.os.SystemConfigManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.system.OsConstants;
-import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.net.module.util.CollectionUtils;
 import com.android.server.LocalServices;
-import com.android.server.SystemConfig;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -80,6 +80,7 @@
 
     private final PackageManager mPackageManager;
     private final UserManager mUserManager;
+    private final SystemConfigManager mSystemConfigManager;
     private final INetd mNetd;
     private final Dependencies mDeps;
 
@@ -123,6 +124,7 @@
             @NonNull final Dependencies deps) {
         mPackageManager = context.getPackageManager();
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        mSystemConfigManager = context.getSystemService(SystemConfigManager.class);
         mNetd = netd;
         mDeps = deps;
     }
@@ -174,20 +176,18 @@
 
         mUsers.addAll(mUserManager.getUserHandles(true /* excludeDying */));
 
-        final SparseArray<ArraySet<String>> systemPermission =
-                SystemConfig.getInstance().getSystemPermissions();
-        for (int i = 0; i < systemPermission.size(); i++) {
-            ArraySet<String> perms = systemPermission.valueAt(i);
-            int uid = systemPermission.keyAt(i);
-            int netdPermission = 0;
-            // Get the uids of native services that have UPDATE_DEVICE_STATS or INTERNET permission.
-            if (perms != null) {
-                netdPermission |= perms.contains(UPDATE_DEVICE_STATS)
-                        ? INetd.PERMISSION_UPDATE_DEVICE_STATS : 0;
-                netdPermission |= perms.contains(INTERNET)
-                        ? INetd.PERMISSION_INTERNET : 0;
+        final SparseArray<String> netdPermToSystemPerm = new SparseArray<>();
+        netdPermToSystemPerm.put(INetd.PERMISSION_INTERNET, INTERNET);
+        netdPermToSystemPerm.put(INetd.PERMISSION_UPDATE_DEVICE_STATS, UPDATE_DEVICE_STATS);
+        for (int i = 0; i < netdPermToSystemPerm.size(); i++) {
+            final int netdPermission = netdPermToSystemPerm.keyAt(i);
+            final String systemPermission = netdPermToSystemPerm.valueAt(i);
+            final int[] hasPermissionUids =
+                    mSystemConfigManager.getSystemPermissionUids(systemPermission);
+            for (int j = 0; j < hasPermissionUids.length; j++) {
+                final int uid = hasPermissionUids[j];
+                netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
             }
-            netdPermsUids.put(uid, netdPermsUids.get(uid) | netdPermission);
         }
         log("Users: " + mUsers.size() + ", Apps: " + mApps.size());
         update(mUsers, mApps, true);
@@ -204,7 +204,7 @@
         if (app.requestedPermissions == null || app.requestedPermissionsFlags == null) {
             return false;
         }
-        final int index = ArrayUtils.indexOf(app.requestedPermissions, permission);
+        final int index = CollectionUtils.indexOf(app.requestedPermissions, permission);
         if (index < 0 || index >= app.requestedPermissionsFlags.length) return false;
         return (app.requestedPermissionsFlags[index] & REQUESTED_PERMISSION_GRANTED) != 0;
     }
@@ -246,15 +246,6 @@
         return mApps.containsKey(uid);
     }
 
-    private int[] toIntArray(Collection<Integer> list) {
-        int[] array = new int[list.size()];
-        int i = 0;
-        for (Integer item : list) {
-            array[i++] = item;
-        }
-        return array;
-    }
-
     private void update(Set<UserHandle> users, Map<Integer, Boolean> apps, boolean add) {
         List<Integer> network = new ArrayList<>();
         List<Integer> system = new ArrayList<>();
@@ -662,23 +653,23 @@
             if (allPermissionAppIds.size() != 0) {
                 mNetd.trafficSetNetPermForUids(
                         INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
-                        ArrayUtils.convertToIntArray(allPermissionAppIds));
+                        toIntArray(allPermissionAppIds));
             }
             if (internetPermissionAppIds.size() != 0) {
                 mNetd.trafficSetNetPermForUids(INetd.PERMISSION_INTERNET,
-                        ArrayUtils.convertToIntArray(internetPermissionAppIds));
+                        toIntArray(internetPermissionAppIds));
             }
             if (updateStatsPermissionAppIds.size() != 0) {
                 mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UPDATE_DEVICE_STATS,
-                        ArrayUtils.convertToIntArray(updateStatsPermissionAppIds));
+                        toIntArray(updateStatsPermissionAppIds));
             }
             if (noPermissionAppIds.size() != 0) {
                 mNetd.trafficSetNetPermForUids(INetd.PERMISSION_NONE,
-                        ArrayUtils.convertToIntArray(noPermissionAppIds));
+                        toIntArray(noPermissionAppIds));
             }
             if (uninstalledAppIds.size() != 0) {
                 mNetd.trafficSetNetPermForUids(INetd.PERMISSION_UNINSTALLED,
-                        ArrayUtils.convertToIntArray(uninstalledAppIds));
+                        toIntArray(uninstalledAppIds));
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Pass appId list of special permission failed." + e);
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index a769e88..01ac81fb 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -113,6 +113,7 @@
 import com.android.internal.net.LegacyVpnInfo;
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnProfile;
+import com.android.net.module.util.NetdUtils;
 import com.android.net.module.util.NetworkStackConstants;
 import com.android.server.DeviceIdleInternal;
 import com.android.server.LocalServices;
@@ -1509,7 +1510,7 @@
             if (start != -1) ranges.add(new UidRange(start, stop));
         } else if (disallowedApplications != null) {
             // Add all ranges for user skipping UIDs for disallowedApplications.
-            final UidRange userRange = UidRange.createForUser(userId);
+            final UidRange userRange = UidRange.createForUser(UserHandle.of(userId));
             int start = userRange.start;
             for (int uid : getAppsUids(disallowedApplications, userId)) {
                 if (uid == start) {
@@ -1522,7 +1523,7 @@
             if (start <= userRange.stop) ranges.add(new UidRange(start, userRange.stop));
         } else {
             // Add all UIDs for the user.
-            ranges.add(UidRange.createForUser(userId));
+            ranges.add(UidRange.createForUser(UserHandle.of(userId)));
         }
     }
 
@@ -1531,7 +1532,7 @@
     private static List<UidRange> uidRangesForUser(int userId, Set<UidRange> existingRanges) {
         // UidRange#createForUser returns the entire range of UIDs available to a macro-user.
         // This is something like 0-99999 ; {@see UserHandle#PER_USER_RANGE}
-        final UidRange userRange = UidRange.createForUser(userId);
+        final UidRange userRange = UidRange.createForUser(UserHandle.of(userId));
         final List<UidRange> ranges = new ArrayList<>();
         for (UidRange range : existingRanges) {
             if (userRange.containsRange(range)) {
@@ -2528,7 +2529,7 @@
                                     address /* unused */,
                                     address /* unused */,
                                     network);
-                    mNms.setInterfaceUp(mTunnelIface.getInterfaceName());
+                    NetdUtils.setInterfaceUp(mNetd, mTunnelIface.getInterfaceName());
 
                     mSession = mIkev2SessionCreator.createIkeSession(
                             mContext,
diff --git a/services/core/java/com/android/server/input/OWNERS b/services/core/java/com/android/server/input/OWNERS
index 0313a40..82c6ee1 100644
--- a/services/core/java/com/android/server/input/OWNERS
+++ b/services/core/java/com/android/server/input/OWNERS
@@ -1,2 +1,3 @@
+lzye@google.com
 michaelwr@google.com
 svv@google.com
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index a589fed..294d7e2 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -89,6 +89,7 @@
 import android.provider.Settings;
 import android.provider.Settings.Secure;
 import android.provider.Settings.SettingNotFoundException;
+import android.security.AndroidKeyStoreMaintenance;
 import android.security.Authorization;
 import android.security.KeyStore;
 import android.security.keystore.AndroidKeyStoreProvider;
@@ -225,7 +226,6 @@
     private final SyntheticPasswordManager mSpManager;
 
     private final KeyStore mKeyStore;
-
     private final RecoverableKeyStoreManager mRecoverableKeyStoreManager;
     private ManagedProfilePasswordCache mManagedProfilePasswordCache;
 
@@ -489,8 +489,8 @@
             return KeyStore.getInstance();
         }
 
-        public RecoverableKeyStoreManager getRecoverableKeyStoreManager(KeyStore keyStore) {
-            return RecoverableKeyStoreManager.getInstance(mContext, keyStore);
+        public RecoverableKeyStoreManager getRecoverableKeyStoreManager() {
+            return RecoverableKeyStoreManager.getInstance(mContext);
         }
 
         public IStorageManager getStorageManager() {
@@ -571,7 +571,7 @@
         mInjector = injector;
         mContext = injector.getContext();
         mKeyStore = injector.getKeyStore();
-        mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager(mKeyStore);
+        mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager();
         mHandler = injector.getHandler(injector.getServiceThread());
         mStrongAuth = injector.getStrongAuth();
         mActivityManager = injector.getActivityManager();
@@ -803,6 +803,7 @@
             if (Intent.ACTION_USER_ADDED.equals(intent.getAction())) {
                 // Notify keystore that a new user was added.
                 final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
+                AndroidKeyStoreMaintenance.onUserAdded(userHandle);
                 final KeyStore ks = KeyStore.getInstance();
                 final UserInfo parentInfo = mUserManager.getProfileParent(userHandle);
                 final int parentHandle = parentInfo != null ? parentInfo.id : -1;
@@ -1270,6 +1271,7 @@
     }
 
     private void setKeystorePassword(byte[] password, int userHandle) {
+        AndroidKeyStoreMaintenance.onUserPasswordChanged(userHandle, password);
         final KeyStore ks = KeyStore.getInstance();
         // TODO(b/120484642): Update keystore to accept byte[] passwords
         String passwordString = password == null ? null : new String(password);
@@ -1278,7 +1280,7 @@
 
     private void unlockKeystore(byte[] password, int userHandle) {
         if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle);
-        new Authorization().onLockScreenEvent(false, userHandle, password);
+        Authorization.onLockScreenEvent(false, userHandle, password);
         // TODO(b/120484642): Update keystore to accept byte[] passwords
         String passwordString = password == null ? null : new String(password);
         final KeyStore ks = KeyStore.getInstance();
@@ -2301,6 +2303,7 @@
         mSpManager.removeUser(userId);
         mStrongAuth.removeUser(userId);
 
+        AndroidKeyStoreMaintenance.onUserRemoved(userId);
         final KeyStore ks = KeyStore.getInstance();
         ks.onUserRemoved(userId);
         mManagedProfilePasswordCache.removePassword(userId);
diff --git a/services/core/java/com/android/server/locksettings/OWNERS b/services/core/java/com/android/server/locksettings/OWNERS
index 08b8a8c..7577ee5 100644
--- a/services/core/java/com/android/server/locksettings/OWNERS
+++ b/services/core/java/com/android/server/locksettings/OWNERS
@@ -1,3 +1,4 @@
 jaggies@google.com
 kchyn@google.com
 rubinxu@google.com
+xunchang@google.com
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
index 30ea555..7e00fd6 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java
@@ -194,7 +194,9 @@
         }
 
         public void reportMetric(boolean success) {
-            FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, success);
+            // TODO(b/179105110) design error code; and report the true value for other fields.
+            FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, 0, 1, 1,
+                    -1, 0);
         }
 
         public RebootEscrowEventLog getEventLog() {
diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java b/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java
index b3b4546..697bf08 100644
--- a/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java
+++ b/services/core/java/com/android/server/locksettings/RebootEscrowProviderServerBasedImpl.java
@@ -44,7 +44,7 @@
      * Use the default lifetime of 10 minutes. The lifetime covers the following activities:
      * Server wrap secret -> device reboot -> server unwrap blob.
      */
-    private static final long DEFAULT_SERVER_BLOB_LIFETIME_IN_MILLIS = 600_1000;
+    private static final long DEFAULT_SERVER_BLOB_LIFETIME_IN_MILLIS = 600_000;
 
     private final LockSettingsStorage mStorage;
 
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
index 6d420a9..35e6489 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordCrypto.java
@@ -18,7 +18,6 @@
 
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
-import android.security.keystore2.AndroidKeyStoreProvider;
 import android.util.Slog;
 
 import java.io.ByteArrayOutputStream;
@@ -141,19 +140,8 @@
         }
     }
 
-    /**
-     * TODO This function redirects keystore access to the legacy keystore during a transitional
-     *      phase during which not all calling code has been adjusted to use Keystore 2.0.
-     *      This can be reverted to a constant of "AndroidKeyStore" when b/171305684 is complete.
-     *      The specific bug for this component is b/171305115.
-     */
     static String androidKeystoreProviderName() {
-        if (AndroidKeyStoreProvider.isInstalled()) {
-            return "AndroidKeyStoreLegacy";
-        } else {
-            return "AndroidKeystore";
-        }
-
+        return "AndroidKeyStore";
     }
 
     public static byte[] decryptBlob(String keyAlias, byte[] blob, byte[] applicationId) {
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java
index 9857fb6..f594136 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/KeyStoreProxyImpl.java
@@ -16,8 +16,6 @@
 
 package com.android.server.locksettings.recoverablekeystore;
 
-import android.security.keystore2.AndroidKeyStoreProvider;
-
 import java.io.IOException;
 import java.security.Key;
 import java.security.KeyStore;
@@ -31,24 +29,11 @@
  */
 public class KeyStoreProxyImpl implements KeyStoreProxy {
 
+    public static final String ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore";
+
     private final KeyStore mKeyStore;
 
     /**
-     * TODO This function redirects keystore access to the legacy keystore during a transitional
-     *      phase during which not all calling code has been adjusted to use Keystore 2.0.
-     *      This can be reverted to a constant of "AndroidKeyStore" when b/171305684 is complete.
-     *      The specific bug for this component is b/171305545.
-     */
-    static String androidKeystoreProviderName() {
-        if (AndroidKeyStoreProvider.isInstalled()) {
-            return "AndroidKeyStoreLegacy";
-        } else {
-            return "AndroidKeyStore";
-        }
-
-    }
-
-    /**
      * A new instance, delegating to {@code keyStore}.
      */
     public KeyStoreProxyImpl(KeyStore keyStore) {
@@ -84,7 +69,7 @@
      * @throws KeyStoreException if there was a problem getting or initializing the key store.
      */
     public static KeyStore getAndLoadAndroidKeyStore() throws KeyStoreException {
-        KeyStore keyStore = KeyStore.getInstance(androidKeystoreProviderName());
+        KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER);
         try {
             keyStore.load(/*param=*/ null);
         } catch (CertificateException | IOException | NoSuchAlgorithmException e) {
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
index 569b709..202dfe7 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
@@ -484,7 +484,7 @@
      * @throws KeyStoreException if there was a problem getting or initializing the key store.
      */
     private static KeyStore getAndLoadAndroidKeyStore() throws KeyStoreException {
-        KeyStore keyStore = KeyStore.getInstance(KeyStoreProxyImpl.androidKeystoreProviderName());
+        KeyStore keyStore = KeyStore.getInstance(KeyStoreProxyImpl.ANDROID_KEY_STORE_PROVIDER);
         try {
             keyStore.load(/*param=*/ null);
         } catch (CertificateException | IOException | NoSuchAlgorithmException e) {
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index 6d97ed7..b49bced 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -34,7 +34,6 @@
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.os.UserHandle;
-import android.security.KeyStore;
 import android.security.keystore.recovery.KeyChainProtectionParams;
 import android.security.keystore.recovery.KeyChainSnapshot;
 import android.security.keystore.recovery.RecoveryCertPath;
@@ -110,14 +109,14 @@
      * @hide
      */
     public static synchronized RecoverableKeyStoreManager
-            getInstance(Context context, KeyStore keystore) {
+            getInstance(Context context) {
         if (mInstance == null) {
             RecoverableKeyStoreDb db = RecoverableKeyStoreDb.newInstance(context);
             PlatformKeyManager platformKeyManager;
             ApplicationKeyStorage applicationKeyStorage;
             try {
                 platformKeyManager = PlatformKeyManager.getInstance(context, db);
-                applicationKeyStorage = ApplicationKeyStorage.getInstance(keystore);
+                applicationKeyStorage = ApplicationKeyStorage.getInstance();
             } catch (NoSuchAlgorithmException e) {
                 // Impossible: all algorithms must be supported by AOSP
                 throw new RuntimeException(e);
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java
index 84ddbf7..2398f56 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/ApplicationKeyStorage.java
@@ -21,9 +21,13 @@
 import android.annotation.Nullable;
 import android.os.ServiceSpecificException;
 import android.security.Credentials;
+import android.security.KeyStore;
+import android.security.KeyStore2;
 import android.security.keystore.KeyProperties;
 import android.security.keystore.KeyProtection;
-import android.security.KeyStore;
+import android.system.keystore2.Domain;
+import android.system.keystore2.KeyDescriptor;
+import android.system.keystore2.KeyPermission;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -47,32 +51,37 @@
 
     private static final String APPLICATION_KEY_ALIAS_PREFIX =
             "com.android.server.locksettings.recoverablekeystore/application/";
+    private static final String APPLICATION_KEY_GRANT_PREFIX = "recoverable_key:";
 
     private final KeyStoreProxy mKeyStore;
-    private final KeyStore mKeystoreService;
 
-    public static ApplicationKeyStorage getInstance(KeyStore keystoreService)
+    /**
+     * Creates a new instance.
+     */
+    public static ApplicationKeyStorage getInstance()
             throws KeyStoreException {
         return new ApplicationKeyStorage(
-                new KeyStoreProxyImpl(KeyStoreProxyImpl.getAndLoadAndroidKeyStore()),
-                keystoreService);
+                new KeyStoreProxyImpl(KeyStoreProxyImpl.getAndLoadAndroidKeyStore()));
     }
 
     @VisibleForTesting
-    ApplicationKeyStorage(KeyStoreProxy keyStore, KeyStore keystoreService) {
+    ApplicationKeyStorage(KeyStoreProxy keyStore) {
         mKeyStore = keyStore;
-        mKeystoreService = keystoreService;
     }
 
     /**
-     * Returns grant alias, valid in Applications namespace.
+     * Returns String representation of {@code KeyDescriptor} valid in application's namespace.
      */
     public @Nullable String getGrantAlias(int userId, int uid, String alias) {
-        // Aliases used by {@link KeyStore} are different than used by public API.
-        // {@code USER_PRIVATE_KEY} prefix is used secret keys.
         Log.i(TAG, String.format(Locale.US, "Get %d/%d/%s", userId, uid, alias));
-        String keystoreAlias = Credentials.USER_PRIVATE_KEY + getInternalAlias(userId, uid, alias);
-        return mKeystoreService.grant(keystoreAlias, uid);
+        String keystoreAlias = getInternalAlias(userId, uid, alias);
+        if (useKeyStore2()) {
+            return makeKeystoreEngineGrantString(uid, keystoreAlias);
+        } else {
+            // Aliases used by {@link KeyStore} are different than used by public API.
+            // {@code USER_PRIVATE_KEY} prefix is used secret keys.
+            return KeyStore.getInstance().grant(Credentials.USER_PRIVATE_KEY + keystoreAlias, uid);
+        }
     }
 
     public void setSymmetricKeyEntry(int userId, int uid, String alias, byte[] secretKey)
@@ -117,4 +126,31 @@
     private String getInternalAlias(int userId, int uid, String alias) {
         return APPLICATION_KEY_ALIAS_PREFIX + userId + "/" + uid + "/" + alias;
     }
+
+    private String makeKeystoreEngineGrantString(int uid, String alias) {
+        if (alias == null) {
+            return null;
+        }
+
+        KeyDescriptor key = new KeyDescriptor();
+        key.domain = Domain.APP;
+        key.nspace = KeyProperties.NAMESPACE_APPLICATION;
+        key.alias = alias;
+        key.blob = null;
+
+        int grantAccessVector = KeyPermission.USE | KeyPermission.GET_INFO | KeyPermission.DELETE;
+
+        try {
+            key = KeyStore2.getInstance().grant(key, uid, grantAccessVector);
+        } catch (android.security.KeyStoreException e) {
+            Log.e(TAG, "Failed to get grant for KeyStore key.", e);
+            throw new ServiceSpecificException(ERROR_SERVICE_INTERNAL_ERROR, e.getMessage());
+        }
+        return String.format("%s%016X", APPLICATION_KEY_GRANT_PREFIX, key.nspace);
+    }
+
+    private static boolean useKeyStore2() {
+        return android.security.keystore2.AndroidKeyStoreProvider.isInstalled();
+    }
+
 }
diff --git a/services/core/java/com/android/server/net/NetworkIdentitySet.java b/services/core/java/com/android/server/net/NetworkIdentitySet.java
index bce8069..22ed781 100644
--- a/services/core/java/com/android/server/net/NetworkIdentitySet.java
+++ b/services/core/java/com/android/server/net/NetworkIdentitySet.java
@@ -40,6 +40,7 @@
     private static final int VERSION_ADD_NETWORK_ID = 3;
     private static final int VERSION_ADD_METERED = 4;
     private static final int VERSION_ADD_DEFAULT_NETWORK = 5;
+    private static final int VERSION_ADD_OEM_MANAGED_NETWORK = 6;
 
     public NetworkIdentitySet() {
     }
@@ -84,13 +85,20 @@
                 defaultNetwork = true;
             }
 
+            final int oemNetCapabilities;
+            if (version >= VERSION_ADD_OEM_MANAGED_NETWORK) {
+                oemNetCapabilities = in.readInt();
+            } else {
+                oemNetCapabilities = NetworkIdentity.OEM_NONE;
+            }
+
             add(new NetworkIdentity(type, subType, subscriberId, networkId, roaming, metered,
-                    defaultNetwork));
+                    defaultNetwork, oemNetCapabilities));
         }
     }
 
     public void writeToStream(DataOutput out) throws IOException {
-        out.writeInt(VERSION_ADD_DEFAULT_NETWORK);
+        out.writeInt(VERSION_ADD_OEM_MANAGED_NETWORK);
         out.writeInt(size());
         for (NetworkIdentity ident : this) {
             out.writeInt(ident.getType());
@@ -100,6 +108,7 @@
             out.writeBoolean(ident.getRoaming());
             out.writeBoolean(ident.getMetered());
             out.writeBoolean(ident.getDefaultNetwork());
+            out.writeInt(ident.getOemManaged());
         }
     }
 
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index b5c0f28..46ad457 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -52,6 +52,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkIdentity.OEM_NONE;
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.SNOOZE_NEVER;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
@@ -1383,7 +1384,11 @@
             final String subscriberId = mSubIdToSubscriberId.valueAt(i);
             final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
                     TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
-                    true);
+                    true, OEM_NONE);
+            /* While OEM_NONE indicates "any non OEM managed network", OEM_NONE is meant to be a
+             * placeholder value here. The probeIdent is matched against a NetworkTemplate which
+             * should have its OEM managed value set to OEM_MANAGED_ALL, which will cause the
+             * template to match probeIdent without regard to OEM managed status. */
             if (template.matches(probeIdent)) {
                 return subId;
             }
@@ -1613,7 +1618,8 @@
         // find and update the mobile NetworkPolicy for this subscriber id
         boolean policyUpdated = false;
         final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
-                TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true);
+                TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true,
+                OEM_NONE);
         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
             if (template.matches(probeIdent)) {
@@ -1842,7 +1848,7 @@
 
                     final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
                             TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true,
-                            true);
+                            true, OEM_NONE);
                     // Template is matched when subscriber id matches.
                     if (template.matches(probeIdent)) {
                         matchingSubIds.add(subId);
@@ -2157,7 +2163,8 @@
     private boolean ensureActiveMobilePolicyAL(int subId, String subscriberId) {
         // Poke around to see if we already have a policy
         final NetworkIdentity probeIdent = new NetworkIdentity(TYPE_MOBILE,
-                TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true);
+                TelephonyManager.NETWORK_TYPE_UNKNOWN, subscriberId, null, false, true, true,
+                OEM_NONE);
         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
             if (template.matches(probeIdent)) {
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 9706bce..5b9a11b 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -1319,7 +1319,7 @@
                     NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
                             ident.getSubType(), ident.getSubscriberId(), ident.getNetworkId(),
                             ident.getRoaming(), true /* metered */,
-                            true /* onDefaultNetwork */);
+                            true /* onDefaultNetwork */, ident.getOemManaged());
                     findOrCreateNetworkIdentitySet(mActiveIfaces, IFACE_VT).add(vtIdent);
                     findOrCreateNetworkIdentitySet(mActiveUidIfaces, IFACE_VT).add(vtIdent);
                 }
diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java
index 9984bfa..9c4c510 100644
--- a/services/core/java/com/android/server/os/NativeTombstoneManager.java
+++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java
@@ -42,6 +42,7 @@
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.proto.ProtoInputStream;
+import android.util.proto.ProtoParseException;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.BootReceiver;
@@ -424,7 +425,7 @@
                                 }
                             }
                             stream.end(token);
-
+                            break;
 
                         case (int) Tombstone.SELINUX_LABEL:
                             selinuxLabel = stream.readString(Tombstone.SELINUX_LABEL);
@@ -434,7 +435,7 @@
                             break;
                     }
                 }
-            } catch (IOException ex) {
+            } catch (IOException | ProtoParseException ex) {
                 Slog.e(TAG, "Failed to parse tombstone", ex);
                 return Optional.empty();
             }
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 4a2fb5d..b39a6b4 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -780,7 +780,8 @@
         return getOatDir(codePath).getAbsolutePath();
     }
 
-    static File getOatDir(File codePath) {
+    /** Returns the oat dir for the given code path */
+    public static File getOatDir(File codePath) {
         return new File(codePath, OAT_DIR_NAME);
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index febbfbc..4896fd9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -355,6 +355,7 @@
 import com.android.server.pm.Settings.DatabaseVersion;
 import com.android.server.pm.Settings.VersionInfo;
 import com.android.server.pm.dex.ArtManagerService;
+import com.android.server.pm.dex.ArtUtils;
 import com.android.server.pm.dex.DexManager;
 import com.android.server.pm.dex.DexoptOptions;
 import com.android.server.pm.dex.PackageDexUsage;
@@ -5350,6 +5351,23 @@
     }
 
     @Override
+    public int getTargetSdkVersion(String packageName)  {
+        synchronized (mLock) {
+            final AndroidPackage pkg = mPackages.get(packageName);
+            if (pkg == null) {
+                return -1;
+            }
+
+            final PackageSetting ps = getPackageSetting(pkg.getPackageName());
+            if (shouldFilterApplicationLocked(ps, Binder.getCallingUid(),
+                    UserHandle.getCallingUserId())) {
+                return -1;
+            }
+            return pkg.getTargetSdkVersion();
+        }
+    }
+
+    @Override
     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
         return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
     }
@@ -20581,7 +20599,7 @@
         }
         final Intent intent = getHomeIntent();
         final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
-                PackageManager.GET_META_DATA, userId);
+                MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId);
         final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
                 intent, null, 0, resolveInfos, 0, true, false, false, userId);
         final String packageName = preferredResolveInfo != null
@@ -24025,15 +24043,13 @@
         }
 
         @Override
-        public int getTargetSdkVersionForPackage(String packageName)
-                throws RemoteException {
-            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
-            ApplicationInfo info = getApplicationInfo(packageName, 0, callingUser);
-            if (info == null) {
-                throw new RemoteException(
-                        "Couldn't get ApplicationInfo for package " + packageName);
+        public int getTargetSdkVersionForPackage(String packageName) throws RemoteException {
+            int targetSdk = getTargetSdkVersion(packageName);
+            if (targetSdk != -1) {
+                return targetSdk;
             }
-            return info.targetSdkVersion;
+
+            throw new RemoteException("Couldn't get targetSdkVersion for package " + packageName);
         }
 
         @Override
@@ -25523,43 +25539,14 @@
         }
     }
 
-    private String getOatDir(AndroidPackage pkg, @NonNull PackageSetting pkgSetting) {
-        if (!AndroidPackageUtils.canHaveOatDir(pkg,
-                pkgSetting.getPkgState().isUpdatedSystemApp())) {
-            return null;
-        }
-        File codePath = new File(pkg.getCodePath());
-        if (codePath.isDirectory()) {
-            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
-        }
-        return null;
-    }
-
     void deleteOatArtifactsOfPackage(String packageName) {
-        final String[] instructionSets;
-        final List<String> codePaths;
-        final String oatDir;
         final AndroidPackage pkg;
         final PackageSetting pkgSetting;
         synchronized (mLock) {
             pkg = mPackages.get(packageName);
             pkgSetting = mSettings.getPackageLPr(packageName);
         }
-        instructionSets = getAppDexInstructionSets(
-                AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting),
-                AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting));
-        codePaths = AndroidPackageUtils.getAllCodePaths(pkg);
-        oatDir = getOatDir(pkg, pkgSetting);
-
-        for (String codePath : codePaths) {
-            for (String isa : instructionSets) {
-                try {
-                    mInstaller.deleteOdex(codePath, isa, oatDir);
-                } catch (InstallerException e) {
-                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
-                }
-            }
-        }
+        mDexManager.deleteOptimizedFiles(ArtUtils.createArtPackageInfo(pkg, pkgSetting));
     }
 
     Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
diff --git a/services/core/java/com/android/server/pm/dex/ArtPackageInfo.java b/services/core/java/com/android/server/pm/dex/ArtPackageInfo.java
new file mode 100644
index 0000000..50bf916
--- /dev/null
+++ b/services/core/java/com/android/server/pm/dex/ArtPackageInfo.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 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.pm.dex;
+
+import java.util.List;
+
+/**
+ * Holds package information relevant to ART use cases.
+ */
+public class ArtPackageInfo {
+    private final String mPackageName;
+    private final List<String> mInstructionSets;
+    private final List<String> mCodePaths;
+    // TODO: This should be computed on the fly in PackageDexOptimizer / DexManager, but the
+    // logic is too complicated to do it in a single re-factoring.
+    private final String mOatDir;
+
+    public ArtPackageInfo(
+            String packageName,
+            List<String> instructionSets,
+            List<String> codePaths,
+            String oatDir) {
+        mPackageName = packageName;
+        mInstructionSets = instructionSets;
+        mCodePaths = codePaths;
+        mOatDir = oatDir;
+    }
+
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    public List<String> getInstructionSets() {
+        return mInstructionSets;
+    }
+
+    public List<String> getCodePaths() {
+        return mCodePaths;
+    }
+
+    public String getOatDir() {
+        return mOatDir;
+    }
+}
diff --git a/services/core/java/com/android/server/pm/dex/ArtUtils.java b/services/core/java/com/android/server/pm/dex/ArtUtils.java
new file mode 100644
index 0000000..fe6ec0d
--- /dev/null
+++ b/services/core/java/com/android/server/pm/dex/ArtUtils.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 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.pm.dex;
+
+import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
+
+import android.annotation.NonNull;
+
+import com.android.server.pm.PackageDexOptimizer;
+import com.android.server.pm.PackageSetting;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
+
+import java.io.File;
+import java.util.Arrays;
+
+/**
+ * Utility class to interface between PM and ART tooling (e.g. DexManager).
+ */
+public final class ArtUtils {
+    private ArtUtils() {
+    }
+
+    /**
+     * Create the ART-representation of package info.
+     */
+    public static ArtPackageInfo createArtPackageInfo(
+            AndroidPackage pkg, PackageSetting pkgSetting) {
+        return new ArtPackageInfo(
+                pkg.getPackageName(),
+                Arrays.asList(getAppDexInstructionSets(
+                        AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting),
+                        AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting))),
+                AndroidPackageUtils.getAllCodePaths(pkg),
+                getOatDir(pkg, pkgSetting));
+    }
+
+    private static String getOatDir(AndroidPackage pkg, @NonNull PackageSetting pkgSetting) {
+        if (!AndroidPackageUtils.canHaveOatDir(pkg,
+                pkgSetting.getPkgState().isUpdatedSystemApp())) {
+            return null;
+        }
+        File codePath = new File(pkg.getCodePath());
+        if (codePath.isDirectory()) {
+            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
+        }
+        return null;
+    }
+
+}
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index cc6d80a..349561d 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -215,7 +215,7 @@
                         searchResult.mOutcome == DEX_SEARCH_FOUND_SPLIT;
 
                 if (primaryOrSplit && !isUsedByOtherApps
-                        && !PLATFORM_PACKAGE_NAME.equals(searchResult.mOwningPackageName)) {
+                        && !isPlatformPackage(searchResult.mOwningPackageName)) {
                     // If the dex file is the primary apk (or a split) and not isUsedByOtherApps
                     // do not record it. This case does not bring any new usable information
                     // and can be safely skipped.
@@ -232,15 +232,24 @@
                 }
 
                 String classLoaderContext = mapping.getValue();
+
+                // Overwrite the class loader context for system server (instead of merging it).
+                // We expect system server jars to only change contexts in between OTAs and to
+                // otherwise be stable.
+                // Instead of implementing a complex clear-context logic post OTA, it is much
+                // simpler to always override the context for system server. This way, the context
+                // will always be up to date and we will avoid merging which could lead to the
+                // the context being marked as variable and thus making dexopt non-optimal.
+                boolean overwriteCLC = isPlatformPackage(searchResult.mOwningPackageName);
+
                 if (classLoaderContext != null
                         && VMRuntime.isValidClassLoaderContext(classLoaderContext)) {
                     // Record dex file usage. If the current usage is a new pattern (e.g. new
                     // secondary, or UsedByOtherApps), record will return true and we trigger an
                     // async write to disk to make sure we don't loose the data in case of a reboot.
-
                     if (mPackageDexUsage.record(searchResult.mOwningPackageName,
                             dexPath, loaderUserId, loaderIsa, primaryOrSplit,
-                            loadingAppInfo.packageName, classLoaderContext)) {
+                            loadingAppInfo.packageName, classLoaderContext, overwriteCLC)) {
                         mPackageDexUsage.maybeWriteAsync();
                     }
                 }
@@ -474,7 +483,7 @@
      *         because they don't need to be compiled)..
      */
     public boolean dexoptSecondaryDex(DexoptOptions options) {
-        if (PLATFORM_PACKAGE_NAME.equals(options.getPackageName())) {
+        if (isPlatformPackage(options.getPackageName())) {
             // We could easily redirect to #dexoptSystemServer in this case. But there should be
             // no-one calling this method directly for system server.
             // As such we prefer to abort in this case.
@@ -534,7 +543,7 @@
      * <p>PackageDexOptimizer.DEX_OPT_PERFORMED if all dexopt operations succeeded.
      */
     public int dexoptSystemServer(DexoptOptions options) {
-        if (!PLATFORM_PACKAGE_NAME.equals(options.getPackageName())) {
+        if (!isPlatformPackage(options.getPackageName())) {
             Slog.wtf(TAG, "Non system server package used when trying to dexopt system server:"
                     + options.getPackageName());
             return PackageDexOptimizer.DEX_OPT_FAILED;
@@ -662,7 +671,7 @@
             // Special handle system server files.
             // We don't need an installd call because we have permissions to check if the file
             // exists.
-            if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
+            if (isPlatformPackage(packageName)) {
                 if (!Files.exists(Paths.get(dexPath))) {
                     if (DEBUG) {
                         Slog.w(TAG, "A dex file previously loaded by System Server does not exist "
@@ -739,7 +748,8 @@
             boolean newUpdate = mPackageDexUsage.record(searchResult.mOwningPackageName,
                     dexPath, userId, isa, /*primaryOrSplit*/ false,
                     loadingPackage,
-                    PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT);
+                    PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT,
+                    /*overwriteCLC*/ false);
             update |= newUpdate;
         }
         if (update) {
@@ -809,7 +819,7 @@
         // Note: We don't have any way to detect which code paths are actually
         // owned by system server. We can only assume that such paths are on
         // system partitions.
-        if (PLATFORM_PACKAGE_NAME.equals(loadingAppInfo.packageName)) {
+        if (isPlatformPackage(loadingAppInfo.packageName)) {
             if (isSystemServerDexPathSupportedForOdex(dexPath)) {
                 // We record system server dex files as secondary dex files.
                 // The reason is that we only record the class loader context for secondary dex
@@ -842,6 +852,11 @@
         return new DexSearchResult(null, DEX_SEARCH_NOT_FOUND);
     }
 
+    /** Returns true if this is the platform package .*/
+    private static boolean isPlatformPackage(String packageName) {
+        return PLATFORM_PACKAGE_NAME.equals(packageName);
+    }
+
     private static <K,V> V putIfAbsent(Map<K,V> map, K key, V newValue) {
         V existingValue = map.putIfAbsent(key, newValue);
         return existingValue == null ? newValue : existingValue;
@@ -1000,6 +1015,22 @@
         return isBtmCritical;
     }
 
+    /**
+     * Deletes all the optimizations files generated by ART.
+     * @param packageInfo the package information.
+     */
+    public void deleteOptimizedFiles(ArtPackageInfo packageInfo) {
+        for (String codePath : packageInfo.getCodePaths()) {
+            for (String isa : packageInfo.getInstructionSets()) {
+                try {
+                    mInstaller.deleteOdex(codePath, isa, packageInfo.getOatDir());
+                } catch (InstallerException e) {
+                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
+                }
+            }
+        }
+    }
+
     public static class RegisterDexModuleResult {
         public RegisterDexModuleResult() {
             this(false, null);
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index 10760f5..3d63b75 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -111,17 +111,18 @@
      * @param dexPath the path of the dex files being loaded
      * @param ownerUserId the user id which runs the code loading the dex files
      * @param loaderIsa the ISA of the app loading the dex files
-     * @param isUsedByOtherApps whether or not this dex file was not loaded by its owning package
      * @param primaryOrSplit whether or not the dex file is a primary/split dex. True indicates
      *        the file is either primary or a split. False indicates the file is secondary dex.
      * @param loadingPackageName the package performing the load. Recorded only if it is different
      *        than {@param owningPackageName}.
+     * @param overwriteCLC if true, the class loader context will be overwritten instead of being
+     *        merged
      * @return true if the dex load constitutes new information, or false if this information
      *         has been seen before.
      */
     /* package */ boolean record(String owningPackageName, String dexPath, int ownerUserId,
             String loaderIsa, boolean primaryOrSplit,
-            String loadingPackageName, String classLoaderContext) {
+            String loadingPackageName, String classLoaderContext, boolean overwriteCLC) {
         if (!PackageManagerServiceUtils.checkISA(loaderIsa)) {
             throw new IllegalArgumentException("loaderIsa " + loaderIsa + " is unsupported");
         }
@@ -193,7 +194,7 @@
                         }
                         // Merge the information into the existing data.
                         // Returns true if there was an update.
-                        return existingData.merge(newData) || updateLoadingPackages;
+                        return existingData.merge(newData, overwriteCLC) || updateLoadingPackages;
                     }
                 }
             }
@@ -809,14 +810,16 @@
             mLoadingPackages = new HashSet<>(other.mLoadingPackages);
         }
 
-        private boolean merge(DexUseInfo dexUseInfo) {
+        private boolean merge(DexUseInfo dexUseInfo, boolean overwriteCLC) {
             boolean oldIsUsedByOtherApps = mIsUsedByOtherApps;
             mIsUsedByOtherApps = mIsUsedByOtherApps || dexUseInfo.mIsUsedByOtherApps;
             boolean updateIsas = mLoaderIsas.addAll(dexUseInfo.mLoaderIsas);
             boolean updateLoadingPackages = mLoadingPackages.addAll(dexUseInfo.mLoadingPackages);
 
             String oldClassLoaderContext = mClassLoaderContext;
-            if (isUnsupportedContext(mClassLoaderContext)) {
+            if (overwriteCLC) {
+                mClassLoaderContext = dexUseInfo.mClassLoaderContext;
+            } else if (isUnsupportedContext(mClassLoaderContext)) {
                 mClassLoaderContext = dexUseInfo.mClassLoaderContext;
             } else if (!Objects.equals(mClassLoaderContext, dexUseInfo.mClassLoaderContext)) {
                 // We detected a context change.
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 09b4f89..64fa708 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -399,7 +399,8 @@
             ParsedProcess proc = procs.get(key);
             retProcs.put(proc.getName(),
                     new ProcessInfo(proc.getName(), new ArraySet<>(proc.getDeniedPermissions()),
-                            proc.getGwpAsanMode()));
+                            proc.getGwpAsanMode(), proc.getMemtagMode(),
+                            proc.getNativeHeapZeroInit()));
         }
         return retProcs;
     }
diff --git a/services/core/java/com/android/server/pm/verify/domain/OWNERS b/services/core/java/com/android/server/pm/verify/domain/OWNERS
new file mode 100644
index 0000000..c669112
--- /dev/null
+++ b/services/core/java/com/android/server/pm/verify/domain/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 36137
+
+chiuwinson@google.com
+patb@google.com
+toddke@google.com
\ No newline at end of file
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 75277d1..afcf81f 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -700,7 +700,7 @@
         if (changed) {
             dispatchDeviceLocked(userId, locked);
 
-            mAuthorizationService.onLockScreenEvent(locked, userId, null);
+            Authorization.onLockScreenEvent(locked, userId, null);
             KeyStore.getInstance().onUserLockedStateChanged(userId, locked);
             // Also update the user's profiles who have unified challenge, since they
             // share the same unlocked state (see {@link #isDeviceLocked(int)})
@@ -1258,7 +1258,7 @@
                         mDeviceLockedForUser.put(userId, locked);
                     }
 
-                    mAuthorizationService.onLockScreenEvent(locked, userId, null);
+                    Authorization.onLockScreenEvent(locked, userId, null);
                     KeyStore.getInstance().onUserLockedStateChanged(userId, locked);
 
                     if (locked) {
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index 9ee072e..06748a3 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -969,7 +969,7 @@
             mGatewayStatusCallback.onGatewayConnectionError(
                     mConnectionConfig.getRequiredUnderlyingCapabilities(),
                     VCN_ERROR_CODE_INTERNAL_ERROR,
-                    "java.lang.RuntimeException",
+                    RuntimeException.class.getName(),
                     "Received "
                             + exception.getClass().getSimpleName()
                             + " with message: "
@@ -991,11 +991,11 @@
         } else if (exception instanceof IkeInternalException
                 && exception.getCause() instanceof IOException) {
             errorCode = VCN_ERROR_CODE_NETWORK_ERROR;
-            exceptionClass = "java.io.IOException";
+            exceptionClass = IOException.class.getName();
             exceptionMessage = exception.getCause().getMessage();
         } else {
             errorCode = VCN_ERROR_CODE_INTERNAL_ERROR;
-            exceptionClass = "java.lang.RuntimeException";
+            exceptionClass = RuntimeException.class.getName();
             exceptionMessage =
                     "Received "
                             + exception.getClass().getSimpleName()
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 7565fe10..032e1495 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -197,6 +197,7 @@
 import android.net.IIpConnectivityMetrics;
 import android.net.ProxyInfo;
 import android.net.Uri;
+import android.net.VpnManager;
 import android.net.metrics.IpConnectivityLog;
 import android.net.wifi.WifiManager;
 import android.os.Binder;
@@ -308,6 +309,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
@@ -317,6 +319,9 @@
 import java.io.PrintWriter;
 import java.lang.reflect.Constructor;
 import java.nio.charset.StandardCharsets;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
 import java.text.DateFormat;
 import java.time.LocalDate;
 import java.util.ArrayList;
@@ -2245,6 +2250,10 @@
             return mContext.getSystemService(ConnectivityManager.class);
         }
 
+        VpnManager getVpnManager() {
+            return mContext.getSystemService(VpnManager.class);
+        }
+
         LocationManager getLocationManager() {
             return mContext.getSystemService(LocationManager.class);
         }
@@ -6482,7 +6491,7 @@
             enforceCanManageScope(who, callerPackage, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER,
                     DELEGATION_CERT_INSTALL);
         }
-        final KeyGenParameterSpec keySpec = parcelableKeySpec.getSpec();
+        KeyGenParameterSpec keySpec = parcelableKeySpec.getSpec();
         final String alias = keySpec.getKeystoreAlias();
         if (TextUtils.isEmpty(alias)) {
             throw new IllegalArgumentException("Empty alias provided.");
@@ -6494,9 +6503,15 @@
             return false;
         }
 
-        if (deviceIdAttestationRequired && (keySpec.getAttestationChallenge() == null)) {
-            throw new IllegalArgumentException(
-                    "Requested Device ID attestation but challenge is empty.");
+        if (deviceIdAttestationRequired) {
+            if (keySpec.getAttestationChallenge() == null) {
+                throw new IllegalArgumentException(
+                        "Requested Device ID attestation but challenge is empty.");
+            }
+            KeyGenParameterSpec.Builder specBuilder = new KeyGenParameterSpec.Builder(keySpec);
+            specBuilder.setAttestationIds(attestationUtilsFlags);
+            specBuilder.setDevicePropertiesAttestationIncluded(true);
+            keySpec = specBuilder.build();
         }
 
         final UserHandle userHandle = mInjector.binderGetCallingUserHandle();
@@ -6506,15 +6521,8 @@
                     KeyChain.bindAsUser(mContext, userHandle)) {
                 IKeyChainService keyChain = keyChainConnection.getService();
 
-                // Copy the provided keySpec, excluding the attestation challenge, which will be
-                // used later for requesting key attestation record.
-                final KeyGenParameterSpec noAttestationSpec =
-                    new KeyGenParameterSpec.Builder(keySpec)
-                        .setAttestationChallenge(null)
-                        .build();
-
                 final int generationResult = keyChain.generateKeyPair(algorithm,
-                    new ParcelableKeyGenParameterSpec(noAttestationSpec));
+                        new ParcelableKeyGenParameterSpec(keySpec));
                 if (generationResult != KeyChain.KEY_GEN_SUCCESS) {
                     Log.e(LOG_TAG, String.format(
                             "KeyChain failed to generate a keypair, error %d.", generationResult));
@@ -6523,6 +6531,9 @@
                             throw new ServiceSpecificException(
                                     DevicePolicyManager.KEY_GEN_STRONGBOX_UNAVAILABLE,
                                     String.format("KeyChain error: %d", generationResult));
+                        case KeyChain.KEY_ATTESTATION_CANNOT_ATTEST_IDS:
+                            throw new UnsupportedOperationException(
+                                "Device does not support Device ID attestation.");
                         default:
                             return false;
                     }
@@ -6535,22 +6546,26 @@
                 // that UID.
                 keyChain.setGrant(callingUid, alias, true);
 
-                final byte[] attestationChallenge = keySpec.getAttestationChallenge();
-                if (attestationChallenge != null) {
-                    final int attestationResult = keyChain.attestKey(
-                            alias, attestationChallenge, attestationUtilsFlags, attestationChain);
-                    if (attestationResult != KeyChain.KEY_ATTESTATION_SUCCESS) {
-                        Log.e(LOG_TAG, String.format(
-                                "Attestation for %s failed (rc=%d), deleting key.",
-                                alias, attestationResult));
-                        keyChain.removeKeyPair(alias);
-                        if (attestationResult == KeyChain.KEY_ATTESTATION_CANNOT_ATTEST_IDS) {
-                            throw new UnsupportedOperationException(
-                                    "Device does not support Device ID attestation.");
+                try {
+                    final List<byte[]> encodedCerts = new ArrayList();
+                    final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+                    final byte[] certChainBytes = keyChain.getCaCertificates(alias);
+                    encodedCerts.add(keyChain.getCertificate(alias));
+                    if (certChainBytes != null) {
+                        final Collection<X509Certificate> certs =
+                                (Collection<X509Certificate>) certFactory.generateCertificates(
+                                    new ByteArrayInputStream(certChainBytes));
+                        for (X509Certificate cert : certs) {
+                            encodedCerts.add(cert.getEncoded());
                         }
-                        return false;
                     }
+
+                    attestationChain.shallowCopyFrom(new KeymasterCertificateChain(encodedCerts));
+                } catch (CertificateException e) {
+                    Log.e(LOG_TAG, "While retrieving certificate chain.", e);
+                    return false;
                 }
+
                 final boolean isDelegate = (who == null);
                 DevicePolicyEventLogger
                         .createEvent(DevicePolicyEnums.GENERATE_KEY_PAIR)
@@ -7090,7 +7105,7 @@
                 }
             }
             // If some package is uninstalled after the check above, it will be ignored by CM.
-            if (!mInjector.getConnectivityManager().setAlwaysOnVpnPackageForUser(
+            if (!mInjector.getVpnManager().setAlwaysOnVpnPackageForUser(
                     userId, vpnPackage, lockdown, lockdownAllowlist)) {
                 throw new UnsupportedOperationException();
             }
@@ -7121,7 +7136,7 @@
 
         final int userId = mInjector.userHandleGetCallingUserId();
         return mInjector.binderWithCleanCallingIdentity(
-                () -> mInjector.getConnectivityManager().getAlwaysOnVpnPackageForUser(userId));
+                () -> mInjector.getVpnManager().getAlwaysOnVpnPackageForUser(userId));
     }
 
     @Override
@@ -7139,7 +7154,7 @@
 
         final int userId = mInjector.userHandleGetCallingUserId();
         return mInjector.binderWithCleanCallingIdentity(
-                () -> mInjector.getConnectivityManager().isVpnLockdownEnabled(userId));
+                () -> mInjector.getVpnManager().isVpnLockdownEnabled(userId));
     }
 
     @Override
@@ -7158,7 +7173,7 @@
 
         final int userId = mInjector.userHandleGetCallingUserId();
         return mInjector.binderWithCleanCallingIdentity(
-                () -> mInjector.getConnectivityManager().getVpnLockdownAllowlist(userId));
+                () -> mInjector.getVpnManager().getVpnLockdownAllowlist(userId));
     }
 
     private void forceWipeDeviceNoLock(boolean wipeExtRequested, String reason, boolean wipeEuicc) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c665ca3..18c7e12 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -97,7 +97,6 @@
 import com.android.internal.widget.ILockSettings;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.appbinding.AppBindingService;
-import com.android.server.apphibernation.AppHibernationService;
 import com.android.server.attention.AttentionManagerService;
 import com.android.server.audio.AudioService;
 import com.android.server.biometrics.AuthService;
@@ -1534,7 +1533,7 @@
 
             t.traceBegin("StartIpSecService");
             try {
-                ipSecService = IpSecService.create(context, networkManagement);
+                ipSecService = IpSecService.create(context);
                 ServiceManager.addService(Context.IPSEC_SERVICE, ipSecService);
             } catch (Throwable e) {
                 reportWtf("starting IpSec Service", e);
@@ -1883,11 +1882,9 @@
             mSystemServiceManager.startService(VOICE_RECOGNITION_MANAGER_SERVICE_CLASS);
             t.traceEnd();
 
-            if (AppHibernationService.isAppHibernationEnabled()) {
-                t.traceBegin("StartAppHibernationService");
-                mSystemServiceManager.startService(APP_HIBERNATION_SERVICE_CLASS);
-                t.traceEnd();
-            }
+            t.traceBegin("StartAppHibernationService");
+            mSystemServiceManager.startService(APP_HIBERNATION_SERVICE_CLASS);
+            t.traceEnd();
 
             if (GestureLauncherService.isGestureLauncherEnabled(context.getResources())) {
                 t.traceBegin("StartGestureLauncher");
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 93aa461..b09a66e 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -52,6 +52,7 @@
     libs: [
         "unsupportedappusage",
         "framework-wifi-util-lib",
+        "framework-connectivity"
     ],
     static_libs: [
         // All the classes in netd_aidl_interface must be jarjar so they do not conflict with the
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 7f86faa..d4e4caa 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -19,6 +19,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 
@@ -626,6 +627,7 @@
 
     private static NetworkCapabilities createCapabilities() {
         return new NetworkCapabilities().addCapability(NET_CAPABILITY_INTERNET)
+                .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
                 .addCapability(NET_CAPABILITY_VALIDATED);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
index 1328b91..07f6732 100644
--- a/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/apphibernation/AppHibernationServiceTest.java
@@ -110,6 +110,8 @@
         UserInfo userInfo = addUser(USER_ID_1);
         mAppHibernationService.onUserUnlocking(new SystemService.TargetUser(userInfo));
         doReturn(true).when(mUserManager).isUserUnlockingOrUnlocked(USER_ID_1);
+
+        mAppHibernationService.mIsServiceEnabled = true;
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 4e1454b..1db5fcc 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -150,7 +150,7 @@
         }
 
         @Override
-        public RecoverableKeyStoreManager getRecoverableKeyStoreManager(KeyStore keyStore) {
+        public RecoverableKeyStoreManager getRecoverableKeyStoreManager() {
             return mRecoverableKeyStoreManager;
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 3ebe4ef..7d7af03 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -2043,7 +2043,7 @@
         final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
         networkCapabilities.addTransportType(TRANSPORT_WIFI);
         networkCapabilities.setSSID(TEST_SSID);
-        return new NetworkState(TYPE_WIFI, prop, networkCapabilities, null, null, TEST_SSID);
+        return new NetworkState(TYPE_WIFI, prop, networkCapabilities, null, null);
     }
 
     private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception {
@@ -2067,7 +2067,7 @@
                 new NetworkState(TYPE_MOBILE,
                         buildLinkProperties(TEST_IFACE),
                         buildNetworkCapabilities(TEST_SUB_ID, roaming),
-                        new Network(TEST_NET_ID), TEST_IMSI, null)
+                        new Network(TEST_NET_ID), TEST_IMSI)
         });
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/OWNERS b/services/tests/servicestests/src/com/android/server/pm/OWNERS
index d825dfd..e15b5f5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/pm/OWNERS
@@ -1 +1,3 @@
 include /services/core/java/com/android/server/pm/OWNERS
+
+per-file *Shortcut* = file:/core/java/android/content/pm/SHORTCUT_OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index ff43da6..ee0a16a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -86,6 +86,7 @@
     private TestData mBarUser0DelegateLastClassLoader;
 
     private TestData mSystemServerJar;
+    private TestData mSystemServerJarUpdatedContext;
     private TestData mSystemServerJarInvalid;
 
     private int mUser0;
@@ -113,6 +114,8 @@
 
         mSystemServerJar = new TestData("android", isa, mUser0, PATH_CLASS_LOADER_NAME);
         mSystemServerJarInvalid = new TestData("android", isa, mUser0, PATH_CLASS_LOADER_NAME);
+        mSystemServerJarUpdatedContext = new TestData("android", isa, mUser0,
+                DELEGATE_LAST_CLASS_LOADER_NAME);
 
         mDexManager = new DexManager(/*Context*/ null, mPM, /*PackageDexOptimizer*/ null,
                 mInstaller, mInstallLock);
@@ -522,6 +525,24 @@
     }
 
     @Test
+    public void testSystemServerOverwritesContext() {
+        // Record bar secondaries with the default PathClassLoader.
+        List<String> secondaries = mSystemServerJar.getSecondaryDexPaths();
+
+        notifyDexLoad(mSystemServerJar, secondaries, mUser0);
+        PackageUseInfo pui = getPackageUseInfo(mSystemServerJar);
+        assertSecondaryUse(mSystemServerJar, pui, secondaries, /*isUsedByOtherApps*/false, mUser0);
+
+        // Record bar secondaries again with a different class loader. This will change the context.
+        notifyDexLoad(mSystemServerJarUpdatedContext, secondaries, mUser0);
+
+        pui = getPackageUseInfo(mSystemServerJar);
+        // We expect that all the contexts to be updated according to the last notify.
+        assertSecondaryUse(mSystemServerJarUpdatedContext, pui, secondaries,
+                /*isUsedByOtherApps*/false, mUser0);
+    }
+
+    @Test
     public void testNotifyUnsupportedClassLoaderDoesNotChangeExisting() {
         List<String> secondaries = mBarUser0.getSecondaryDexPaths();
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/OWNERS b/services/tests/servicestests/src/com/android/server/pm/dex/OWNERS
new file mode 100644
index 0000000..66ef75d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/OWNERS
@@ -0,0 +1 @@
+include /services/core/java/com/android/server/pm/dex/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
index adf4551..3450710 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
@@ -451,7 +451,7 @@
                 "PCL[new_context.dex]");
         assertTrue(record(fooSecondary1User0NewContext));
 
-        // Not check that the context was switch to variable.
+        // Now check that the context was switch to variable.
         TestData expectedContext = mFooSecondary1User0.updateClassLoaderContext(
                 PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT);
 
@@ -461,6 +461,22 @@
     }
 
     @Test
+    public void testRecordClassLoaderContextOverwritten() {
+        // Record a secondary dex file.
+        assertTrue(record(mFooSecondary1User0));
+        // Now update its context.
+        TestData fooSecondary1User0NewContext = mFooSecondary1User0.updateClassLoaderContext(
+                "PCL[new_context.dex]", true);
+        assertTrue(record(fooSecondary1User0NewContext));
+
+        // Now check that the context was overwritten.
+        TestData expectedContext = mFooSecondary1User0.updateClassLoaderContext(
+                "PCL[new_context.dex]", true);
+
+        assertPackageDexUsage(null, expectedContext);
+    }
+
+    @Test
     public void testDexUsageClassLoaderContext() {
         final boolean isUsedByOtherApps = false;
         final int userId = 0;
@@ -642,8 +658,9 @@
 
     private boolean record(TestData testData) {
         return mPackageDexUsage.record(testData.mPackageName, testData.mDexFile,
-               testData.mOwnerUserId, testData.mLoaderIsa,
-               testData.mPrimaryOrSplit, testData.mUsedBy, testData.mClassLoaderContext);
+                testData.mOwnerUserId, testData.mLoaderIsa,
+                testData.mPrimaryOrSplit, testData.mUsedBy, testData.mClassLoaderContext,
+                testData.mOverwriteCLC);
     }
 
     private boolean record(PackageDexUsage packageDexUsage, TestData testData, Set<String> users) {
@@ -651,7 +668,8 @@
         for (String user : users) {
             result = result && packageDexUsage.record(testData.mPackageName, testData.mDexFile,
                     testData.mOwnerUserId, testData.mLoaderIsa,
-                    testData.mPrimaryOrSplit, user, testData.mClassLoaderContext);
+                    testData.mPrimaryOrSplit, user, testData.mClassLoaderContext,
+                    testData.mOverwriteCLC);
         }
         return result;
     }
@@ -682,15 +700,16 @@
         private final boolean mPrimaryOrSplit;
         private final String mUsedBy;
         private final String mClassLoaderContext;
+        private final boolean mOverwriteCLC;
 
         private TestData(String packageName, String dexFile, int ownerUserId,
                 String loaderIsa, boolean primaryOrSplit, String usedBy) {
             this(packageName, dexFile, ownerUserId, loaderIsa, primaryOrSplit,
-                    usedBy, "PCL[" + dexFile + "]");
+                    usedBy, "PCL[" + dexFile + "]", false);
         }
         private TestData(String packageName, String dexFile, int ownerUserId,
                 String loaderIsa, boolean primaryOrSplit, String usedBy,
-                String classLoaderContext) {
+                String classLoaderContext, boolean overwriteCLC) {
             mPackageName = packageName;
             mDexFile = dexFile;
             mOwnerUserId = ownerUserId;
@@ -698,16 +717,21 @@
             mPrimaryOrSplit = primaryOrSplit;
             mUsedBy = usedBy;
             mClassLoaderContext = classLoaderContext;
+            mOverwriteCLC = overwriteCLC;
         }
 
         private TestData updateClassLoaderContext(String newContext) {
+            return updateClassLoaderContext(newContext, mOverwriteCLC);
+        }
+
+        private TestData updateClassLoaderContext(String newContext, boolean overwriteCLC) {
             return new TestData(mPackageName, mDexFile, mOwnerUserId, mLoaderIsa,
-                    mPrimaryOrSplit, mUsedBy, newContext);
+                    mPrimaryOrSplit, mUsedBy, newContext, overwriteCLC);
         }
 
         private TestData updateUsedBy(String newUsedBy) {
             return new TestData(mPackageName, mDexFile, mOwnerUserId, mLoaderIsa,
-                mPrimaryOrSplit, newUsedBy, mClassLoaderContext);
+                mPrimaryOrSplit, newUsedBy, mClassLoaderContext, mOverwriteCLC);
         }
 
         private boolean isUsedByOtherApps() {
diff --git a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS
index 816bc6b..e21b66e 100644
--- a/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS
+++ b/services/tests/servicestests/src/com/android/server/soundtrigger_middleware/OWNERS
@@ -1 +1 @@
-include /core/java/android/media/soundtrigger/OWNERS
+include /media/java/android/media/soundtrigger_middleware/OWNERS
diff --git a/telecomm/java/android/telecom/InCallService.java b/telecomm/java/android/telecom/InCallService.java
index 07de617..0ff288b 100644
--- a/telecomm/java/android/telecom/InCallService.java
+++ b/telecomm/java/android/telecom/InCallService.java
@@ -138,6 +138,24 @@
  *     }
  * }
  * }
+ *
+ * </pre>
+ * <p id="companionInCallService">
+ * <h3>Access to InCallService for Wearable Devices</h3>
+ * <ol>
+ * If your app is a third-party companion app and wants to access InCallService APIs, what your
+ * app could do are:
+ * <p>
+ *   <ol>
+ *     <li> Declare MANAGE_ONGOING_CALLS permission in your manifest
+ *     <li> Associate with a physical wearable device via the
+ *          {@link android.companion.CompanionDeviceManager} API as a companion app. See:
+ *          https://developer.android.com/guide/topics/connectivity/companion-device-pairing
+ *     <li> Implement this InCallService with BIND_INCALL_SERVICE permission
+ *   </ol>
+ * </ol>
+ * <p>
+ *
  * </pre>
  * <p id="incomingCallNotification">
  * <h3>Showing the Incoming Call Notification</h3>
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 3f8b683..b0b5ba7 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1649,24 +1649,25 @@
     }
 
     /**
-     * Returns whether the caller has {@link InCallService} access for companion apps.
-     *
-     * A companion app is an app associated with a physical wearable device via the
-     * {@link android.companion.CompanionDeviceManager} API.
+     * Returns whether the caller has {@link android.Manifest.permission#MANAGE_ONGOING_CALLS}
+     * permission. The permission can be obtained by associating with a physical wearable device
+     * via the {@link android.companion.CompanionDeviceManager} API as a companion app. If the
+     * caller app has the permission, it has {@link InCallService} access to manage ongoing calls.
      *
      * @return {@code true} if the caller has {@link InCallService} access for
      *      companion app; {@code false} otherwise.
      */
-    public boolean hasCompanionInCallServiceAccess() {
-        try {
-            if (isServiceConnected()) {
-                return getTelecomService().hasCompanionInCallServiceAccess(
+    public boolean hasManageOngoingCallsPermission() {
+        ITelecomService service = getTelecomService();
+        if (service != null) {
+            try {
+                return service.hasManageOngoingCallsPermission(
                         mContext.getOpPackageName());
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException calling hasCompanionInCallServiceAccess().", e);
-            if (!isSystemProcess()) {
-                e.rethrowAsRuntimeException();
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException calling hasManageOngoingCallsPermission().", e);
+                if (!isSystemProcess()) {
+                    e.rethrowAsRuntimeException();
+                }
             }
         }
         return false;
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 6dc096d..5afac2e 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -179,9 +179,9 @@
     boolean isInCall(String callingPackage, String callingFeatureId);
 
     /**
-     * @see TelecomServiceImpl#hasCompanionInCallServiceAccess
+     * @see TelecomServiceImpl#hasManageOngoingCallsPermission
      */
-    boolean hasCompanionInCallServiceAccess(String callingPackage);
+    boolean hasManageOngoingCallsPermission(String callingPackage);
 
     /**
      * @see TelecomServiceImpl#isInManagedCall
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 3b46371..04e8f63 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4147,6 +4147,31 @@
     public static final String KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL =
             "network_temp_not_metered_supported_bool";
 
+    /**
+     * Indicates the allowed APN types that can be used for LTE initial attach. The order of APN
+     * types in the configuration is the order of APN types that will be used for initial attach.
+     * Empty list indicates that no APN types are allowed for initial attach.
+     *
+     * @hide
+     */
+    public static final String KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY =
+            "allowed_initial_attach_apn_types_string_array";
+
+    /**
+     * Boolean indicating whether the SIM PIN can be stored and verified
+     * seamlessly after an unattended reboot.
+     *
+     * The device configuration value {@code config_allow_pin_storage_for_unattended_reboot}
+     * ultimately controls whether this carrier configuration option is used.  Where
+     * {@code config_allow_pin_storage_for_unattended_reboot} is false, the value of the
+     * {@link #KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL} carrier configuration option is
+     * ignored.
+     *
+     * @hide
+     */
+    public static final String KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL =
+            "store_sim_pin_for_unattended_reboot_bool";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -4698,6 +4723,9 @@
         sDefaults.putBoolean(KEY_USE_ACS_FOR_RCS_BOOL, false);
         sDefaults.putBoolean(KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL, false);
         sDefaults.putInt(KEY_DEFAULT_RTT_MODE_INT, 0);
+        sDefaults.putStringArray(KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY,
+                new String[]{"ia", "default", "ims", "mms", "dun", "emergency"});
+        sDefaults.putBoolean(KEY_STORE_SIM_PIN_FOR_UNATTENDED_REBOOT_BOOL, true);
     }
 
     /**
diff --git a/telephony/java/android/telephony/RadioInterfaceCapabilities.java b/telephony/java/android/telephony/RadioInterfaceCapabilities.java
deleted file mode 100644
index 7c7eb9f..0000000
--- a/telephony/java/android/telephony/RadioInterfaceCapabilities.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2020 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.telephony;
-
-import android.util.ArraySet;
-
-/**
- * Contains the set of supported capabilities that the Radio Interface supports on this device.
- *
- * @hide
- */
-public class RadioInterfaceCapabilities {
-
-    private final ArraySet<String> mSupportedCapabilities;
-
-
-    public RadioInterfaceCapabilities() {
-        mSupportedCapabilities = new ArraySet<>();
-    }
-
-    /**
-     * Marks a capability as supported
-     *
-     * @param capabilityName the name of the capability
-     */
-    public void addSupportedCapability(
-            @TelephonyManager.RadioInterfaceCapability String capabilityName) {
-        mSupportedCapabilities.add(capabilityName);
-    }
-
-    /**
-     * Whether the capability is supported
-     *
-     * @param capabilityName the name of the capability
-     */
-    public boolean isSupported(String capabilityName) {
-        return mSupportedCapabilities.contains(capabilityName);
-    }
-}
diff --git a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
index af67ed2..fe7e5976 100644
--- a/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
+++ b/telephony/java/android/telephony/SignalStrengthUpdateRequest.java
@@ -187,7 +187,7 @@
         return mIsSystemThresholdReportingRequestedWhileIdle;
     }
 
-    /*
+    /**
      * @return the live token of the request
      *
      * @hide
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e8ace34..403d1d0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -28,6 +28,7 @@
 import android.annotation.LongDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
@@ -121,12 +122,10 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
@@ -8127,6 +8126,11 @@
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <p>
+     * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported}
+     * ({@link TelephonyManager#CAPABILITY_ALLOWED_NETWORK_TYPES_USED}) returns true, then
+     * setAllowedNetworkTypesBitmap is used on the radio interface.  Otherwise,
+     * setPreferredNetworkTypesBitmap is used instead.
      *
      * @param subId the id of the subscription to set the preferred network type for.
      * @param networkType the preferred network type
@@ -8158,6 +8162,11 @@
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <p>
+     * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported}
+     * ({@link TelephonyManager#CAPABILITY_ALLOWED_NETWORK_TYPES_USED}) returns true, then
+     * setAllowedNetworkTypesBitmap is used on the radio interface.  Otherwise,
+     * setPreferredNetworkTypesBitmap is used instead.
      *
      * @param networkTypeBitmask The bitmask of preferred network types.
      * @return true on success; false on any failure.
@@ -8183,12 +8192,20 @@
      * Set the allowed network types of the device. This is for carrier or privileged apps to
      * enable/disable certain network types on the device. The user preferred network types should
      * be set through {@link #setPreferredNetworkTypeBitmask}.
+     * <p>
+     * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported}
+     * ({@link TelephonyManager#CAPABILITY_ALLOWED_NETWORK_TYPES_USED}) returns true, then
+     * setAllowedNetworkTypesBitmap is used on the radio interface.  Otherwise,
+     * setPreferredNetworkTypesBitmap is used instead.
      *
      * @param allowedNetworkTypes The bitmask of allowed network types.
      * @return true on success; false on any failure.
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED)
     @SystemApi
     public boolean setAllowedNetworkTypes(@NetworkTypeBitMask long allowedNetworkTypes) {
         try {
@@ -8227,12 +8244,12 @@
      * {@link #ALLOWED_NETWORK_TYPES_REASON_POWER}
      * </ol>
      * This API will result in allowing an intersection of allowed network types for all reasons,
-     * including the configuration done through {@link setAllowedNetworkTypes}.
-     * While this API and {@link setAllowedNetworkTypes} is controlling allowed network types
-     * on device, user preference will still be set through {@link #setPreferredNetworkTypeBitmask}.
-     * Thus resultant network type configured on modem will be an intersection of the network types
-     * from setAllowedNetworkTypesForReason, {@link setAllowedNetworkTypes}
-     * and {@link #setPreferredNetworkTypeBitmask}.
+     * including the configuration done through other reasons.
+     * <p>
+     * If {@link android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported}
+     * ({@link TelephonyManager#CAPABILITY_ALLOWED_NETWORK_TYPES_USED}) returns true, then
+     * setAllowedNetworkTypesBitmap is used on the radio interface.  Otherwise,
+     * setPreferredNetworkTypesBitmap is used instead.
      *
      * @param reason the reason the allowed network type change is taking place
      * @param allowedNetworkTypes The bitmask of allowed network types.
@@ -8241,6 +8258,9 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED)
     public void setAllowedNetworkTypesForReason(@AllowedNetworkTypesReason int reason,
             @NetworkTypeBitMask long allowedNetworkTypes) {
         if (reason != ALLOWED_NETWORK_TYPES_REASON_POWER) {
@@ -8278,6 +8298,9 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresFeature(
+            enforcement = "android.telephony.TelephonyManager#isRadioInterfaceCapabilitySupported",
+            value = TelephonyManager.CAPABILITY_ALLOWED_NETWORK_TYPES_USED)
     public @NetworkTypeBitMask long getAllowedNetworkTypesForReason(
             @AllowedNetworkTypesReason int reason) {
         if (reason != ALLOWED_NETWORK_TYPES_REASON_POWER) {
@@ -14356,10 +14379,24 @@
     public static final String CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE =
             "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE";
 
+    /**
+     * Indicates whether {@link #setPreferredNetworkType}, {@link
+     * #setPreferredNetworkTypeBitmask}, {@link #setAllowedNetworkTypes} and
+     * {@link #setAllowedNetworkTypesForReason} rely on
+     * setAllowedNetworkTypesBitmap instead of setPreferredNetworkTypesBitmap on the radio
+     * interface.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final String CAPABILITY_ALLOWED_NETWORK_TYPES_USED =
+            "CAPABILITY_ALLOWED_NETWORK_TYPES_USED";
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @StringDef(prefix = "CAPABILITY_", value = {
             CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE,
+            CAPABILITY_ALLOWED_NETWORK_TYPES_USED,
     })
     public @interface RadioInterfaceCapability {}
 
@@ -14824,4 +14861,66 @@
             Log.e(TAG, "Error calling ITelephony#clearSignalStrengthUpdateRequest", e);
         }
     }
+
+    /**
+     * The unattended reboot was prepared successfully.
+     * @hide
+     */
+    @SystemApi
+    public static final int PREPARE_UNATTENDED_REBOOT_SUCCESS = 0;
+
+    /**
+     * The unattended reboot was prepared, but the user will need to manually
+     * enter the PIN code of at least one SIM card present in the device.
+     * @hide
+     */
+    @SystemApi
+    public static final int PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED = 1;
+
+    /**
+     * The unattended reboot was not prepared due to generic error.
+     * @hide
+     */
+    @SystemApi
+    public static final int PREPARE_UNATTENDED_REBOOT_ERROR = 2;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"PREPARE_UNATTENDED_REBOOT_"},
+            value = {
+                    PREPARE_UNATTENDED_REBOOT_SUCCESS,
+                    PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED,
+                    PREPARE_UNATTENDED_REBOOT_ERROR
+            })
+    public @interface PrepareUnattendedRebootResult {}
+
+    /**
+     * Prepare TelephonyManager for an unattended reboot. The reboot is required to be done
+     * shortly (e.g. within 15 seconds) after the API is invoked.
+     *
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#REBOOT}
+     *
+     * @return {@link #PREPARE_UNATTENDED_REBOOT_SUCCESS} in case of success.
+     * {@link #PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED} if the device contains
+     * at least one SIM card for which the user needs to manually enter the PIN
+     * code after the reboot. {@link #PREPARE_UNATTENDED_REBOOT_ERROR} in case
+     * of error.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.REBOOT)
+    @PrepareUnattendedRebootResult
+    public int prepareForUnattendedReboot() {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.prepareForUnattendedReboot();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Telephony#prepareForUnattendedReboot RemoteException", e);
+            e.rethrowFromSystemServer();
+        }
+        return PREPARE_UNATTENDED_REBOOT_ERROR;
+    }
 }
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index 46ec4a3..46940dc 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.net.LinkAddress;
+import android.net.LinkProperties;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Annotation.DataFailureCause;
@@ -274,9 +275,11 @@
     }
 
     /**
-     * @return The network suggested data retry duration in milliseconds. {@code Long.MAX_VALUE}
-     * indicates data retry should not occur. {@link #RETRY_DURATION_UNDEFINED} indicates network
-     * did not suggest any retry duration.
+     * @return The network suggested data retry duration in milliseconds as specified in
+     * 3GPP TS 24.302 section 8.2.9.1.  The APN associated to this data call will be throttled for
+     * the specified duration unless {@link DataServiceCallback#onApnUnthrottled} is called.
+     * {@code Long.MAX_VALUE} indicates data retry should not occur.
+     * {@link #RETRY_DURATION_UNDEFINED} indicates network did not suggest any retry duration.
      */
     public long getRetryDurationMillis() {
         return mSuggestedRetryTime;
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index 52bf15f..f56c19b 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -250,7 +250,11 @@
     }
 
     /**
-     * Indicates that the specified APN is no longer throttled.
+     * The APN is throttled for the duration specified in
+     * {@link DataCallResponse#getRetryDurationMillis}.  Calling this method unthrottles that
+     * APN.
+     * <p/>
+     * see: {@link DataCallResponse#getRetryDurationMillis}
      *
      * @param apn Access Point Name defined by the carrier.
      */
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 070fd799..ce8bd7d 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -467,7 +467,7 @@
      * poll on the network unless there are contacts being queried with stale information.
      * <p>
      * Be sure to check the availability of this feature using
-     * {@link ImsRcsManager#isAvailable(int)} and ensuring
+     * {@link ImsRcsManager#isAvailable(int, int)} and ensuring
      * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
      * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is enabled or else
      * this operation will fail with {@link #ERROR_NOT_AVAILABLE} or {@link #ERROR_NOT_ENABLED}.
@@ -484,7 +484,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
+            Manifest.permission.READ_CONTACTS})
     public void requestCapabilities(@NonNull List<Uri> contactNumbers,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull CapabilitiesCallback c) throws ImsException {
@@ -557,7 +558,7 @@
      *
      * <p>
      * Be sure to check the availability of this feature using
-     * {@link ImsRcsManager#isAvailable(int)} and ensuring
+     * {@link ImsRcsManager#isAvailable(int, int)} and ensuring
      * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_OPTIONS_UCE} or
      * {@link RcsFeature.RcsImsCapabilities#CAPABILITY_TYPE_PRESENCE_UCE} is
      * enabled or else this operation will fail with
@@ -571,7 +572,8 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    @RequiresPermission(allOf = {Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE,
+            Manifest.permission.READ_CONTACTS})
     public void requestAvailability(@NonNull Uri contactNumber,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull CapabilitiesCallback c) throws ImsException {
diff --git a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
index 4967e5d..6295548 100644
--- a/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
+++ b/telephony/java/android/telephony/ims/stub/CapabilityExchangeEventListener.java
@@ -25,7 +25,6 @@
 import android.telephony.ims.RcsUceAdapter;
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.RcsFeature;
-import android.util.Log;
 
 import java.util.List;
 
@@ -44,30 +43,12 @@
          * Respond to a remote capability request from the contact specified with the
          * capabilities of this device.
          * @param ownCapabilities The capabilities of this device.
-         * @hide
-         */
-        default void onRespondToCapabilityRequest(
-                @NonNull RcsContactUceCapability ownCapabilities) {}
-
-        /**
-         * Respond to a remote capability request from the contact specified with the
-         * capabilities of this device.
-         * @param ownCapabilities The capabilities of this device.
          * @param isBlocked Whether or not the user has blocked the number requesting the
          *         capabilities of this device. If true, the device should respond to the OPTIONS
          *         request with a 200 OK response and no capabilities.
          */
-        default void onRespondToCapabilityRequest(@NonNull RcsContactUceCapability ownCapabilities,
-                boolean isBlocked) {
-            Log.w("CapabilityExchangeEventListener", "implement "
-                    + "onRespondToCapabilityRequest(RcsContactUceCapability, boolean) instead!");
-            // Fall back to old implementation
-            if (isBlocked) {
-                onRespondToCapabilityRequestWithError(200, "OK");
-            } else {
-                onRespondToCapabilityRequest(ownCapabilities);
-            }
-        }
+        void onRespondToCapabilityRequest(@NonNull RcsContactUceCapability ownCapabilities,
+                boolean isBlocked);
 
         /**
          * Respond to a remote capability request from the contact specified with the
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 77d46f4..e270b8d 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2414,4 +2414,18 @@
      */
     void clearSignalStrengthUpdateRequest(int subId, in SignalStrengthUpdateRequest request,
             String callingPackage);
+
+    /**
+     * Prepare TelephonyManager for an unattended reboot. The reboot is
+     * required to be done shortly after the API is invoked.
+     *
+     * Requires system privileges.
+     *
+     * @return {@link #PREPARE_UNATTENDED_REBOOT_SUCCESS} in case of success.
+     * {@link #PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED} if the device contains
+     * at least one SIM card for which the user needs to manually enter the PIN
+     * code after the reboot. {@link #PREPARE_UNATTENDED_REBOOT_ERROR} in case
+     * of error.
+     */
+    int prepareForUnattendedReboot();
 }
diff --git a/test-base/Android.bp b/test-base/Android.bp
index 0b7a398..9bd639b 100644
--- a/test-base/Android.bp
+++ b/test-base/Android.bp
@@ -49,6 +49,12 @@
 
     compile_dex: true,
     default_to_stubs: true,
+
+    // Additional hiddenapi annotations are provided in a separate module.
+    // TODO(b/180295980) - investigate whether this can be removed
+    hiddenapi_additional_annotations: [
+        "android.test.base-hiddenapi-annotations",
+    ],
 }
 
 // Build the android.test.base_static library
@@ -91,8 +97,9 @@
 // ===============================================
 // This contains the android.test classes from android.test.base plus
 // the com.android.internal.util.Predicate[s] classes. This is only
-// intended for inclusion in android.test.legacy and must not be used
-// elsewhere.
+// intended for inclusion in android.test.legacy and in
+// android.test.base-hiddenapi-annotations to avoid a dependency cycle and must
+// not be used elsewhere.
 java_library_static {
     name: "android.test.base-minus-junit",
 
diff --git a/test-base/hiddenapi/Android.bp b/test-base/hiddenapi/Android.bp
index d4f52d0..1466590 100644
--- a/test-base/hiddenapi/Android.bp
+++ b/test-base/hiddenapi/Android.bp
@@ -14,11 +14,6 @@
 // limitations under the License.
 //
 
-// Provided solely to contribute information about which hidden parts of the android.test.base
-// library are used by apps. The source files are stubs of the actual files in ../src which use the
-// UnsupportedAppUsage annotation to tag those methods that are accessible via the hiddenapi.
-// Relies on the convention that modules with name <x>-hiddenapi provide hiddenapi information for
-// module <x> that is on the bootclasspath.
 package {
     // See: http://go/android-license-faq
     // A large-scale-change added 'default_applicable_licenses' to import
@@ -28,14 +23,20 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
+// Provided solely to contribute information about which hidden parts of the android.test.base
+// library are used by apps. The source files are stubs of the actual files in ../src which use the
+// UnsupportedAppUsage annotation to tag those methods that are accessible via the hiddenapi.
 java_library {
-    name: "android.test.base-hiddenapi",
+    name: "android.test.base-hiddenapi-annotations",
     compile_dex: true,
 
     srcs: ["src/**/*.java"],
 
     libs: [
-        "android.test.base",
+        // Use this instead of `android.test.base` to avoid a dependency cycle
+        // as `android.test.base` depends on this.
+        "android.test.base-minus-junit",
+        "junit",
         "unsupportedappusage",
     ],
 }
diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp
index 025ac42..f7dda57 100644
--- a/tests/RollbackTest/Android.bp
+++ b/tests/RollbackTest/Android.bp
@@ -104,6 +104,7 @@
   key: "com.android.apex.apkrollback.test.key",
   apps: ["TestAppAv1"],
   installable: false,
+  updatable: false,
 }
 
 apex {
@@ -114,6 +115,7 @@
   key: "com.android.apex.apkrollback.test.key",
   apps: ["TestAppAv2"],
   installable: false,
+  updatable: false,
 }
 
 apex {
@@ -124,4 +126,5 @@
   key: "com.android.apex.apkrollback.test.key",
   apps: ["TestAppACrashingV2"],
   installable: false,
+  updatable: false,
 }
diff --git a/tests/net/common/java/android/net/CaptivePortalDataTest.kt b/tests/net/common/java/android/net/CaptivePortalDataTest.kt
index ad5bbf2..18a9331 100644
--- a/tests/net/common/java/android/net/CaptivePortalDataTest.kt
+++ b/tests/net/common/java/android/net/CaptivePortalDataTest.kt
@@ -55,14 +55,14 @@
             .build()
 
     private val dataFromPasspoint = CaptivePortalData.Builder()
-            .setUserPortalUrl(Uri.parse("https://tc.example.com/passpoint"),
-                    CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
-            .setVenueInfoUrl(Uri.parse("https://venue.example.com/passpoint"),
-                    CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
             .setCaptive(true)
             .apply {
                 if (SdkLevel.isAtLeastS()) {
                     setVenueFriendlyName("venue friendly name")
+                    setUserPortalUrl(Uri.parse("https://tc.example.com/passpoint"),
+                            CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
+                    setVenueInfoUrl(Uri.parse("https://venue.example.com/passpoint"),
+                            CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT)
                 }
             }
             .build()
@@ -96,28 +96,28 @@
         if (SdkLevel.isAtLeastS()) {
             assertNotEqualsAfterChange { it.setVenueFriendlyName("another friendly name") }
             assertNotEqualsAfterChange { it.setVenueFriendlyName(null) }
-        }
 
-        assertEquals(dataFromPasspoint, CaptivePortalData.Builder(dataFromPasspoint).build())
-        assertNotEqualsAfterChange { it.setUserPortalUrl(
-                Uri.parse("https://tc.example.com/passpoint")) }
-        assertNotEqualsAfterChange { it.setUserPortalUrl(
-                Uri.parse("https://tc.example.com/passpoint"),
-                CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
-        assertNotEqualsAfterChange { it.setUserPortalUrl(
-                Uri.parse("https://tc.example.com/other"),
-                CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
-        assertNotEqualsAfterChange { it.setUserPortalUrl(
-                Uri.parse("https://tc.example.com/passpoint"),
-                CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
-        assertNotEqualsAfterChange { it.setVenueInfoUrl(
-                Uri.parse("https://venue.example.com/passpoint")) }
-        assertNotEqualsAfterChange { it.setVenueInfoUrl(
-                Uri.parse("https://venue.example.com/other"),
-                CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
-        assertNotEqualsAfterChange { it.setVenueInfoUrl(
-                Uri.parse("https://venue.example.com/passpoint"),
-                CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
+            assertEquals(dataFromPasspoint, CaptivePortalData.Builder(dataFromPasspoint).build())
+            assertNotEqualsAfterChange { it.setUserPortalUrl(
+                    Uri.parse("https://tc.example.com/passpoint")) }
+            assertNotEqualsAfterChange { it.setUserPortalUrl(
+                    Uri.parse("https://tc.example.com/passpoint"),
+                    CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
+            assertNotEqualsAfterChange { it.setUserPortalUrl(
+                    Uri.parse("https://tc.example.com/other"),
+                    CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
+            assertNotEqualsAfterChange { it.setUserPortalUrl(
+                    Uri.parse("https://tc.example.com/passpoint"),
+                    CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
+            assertNotEqualsAfterChange { it.setVenueInfoUrl(
+                    Uri.parse("https://venue.example.com/passpoint")) }
+            assertNotEqualsAfterChange { it.setVenueInfoUrl(
+                    Uri.parse("https://venue.example.com/other"),
+                    CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_PASSPOINT) }
+            assertNotEqualsAfterChange { it.setVenueInfoUrl(
+                    Uri.parse("https://venue.example.com/passpoint"),
+                    CaptivePortalData.CAPTIVE_PORTAL_DATA_SOURCE_OTHER) }
+        }
     }
 
     @Test
diff --git a/tests/net/common/java/android/net/NetworkStackTest.java b/tests/net/common/java/android/net/NetworkStackTest.java
index a99aa01..f8f9c72 100644
--- a/tests/net/common/java/android/net/NetworkStackTest.java
+++ b/tests/net/common/java/android/net/NetworkStackTest.java
@@ -15,20 +15,8 @@
  */
 package android.net;
 
-import static android.Manifest.permission.NETWORK_STACK;
-import static android.content.pm.PackageManager.PERMISSION_DENIED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
-import static android.net.NetworkStack.checkNetworkStackPermission;
-import static android.net.NetworkStack.checkNetworkStackPermissionOr;
-
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.when;
 
-import android.content.Context;
 import android.os.Build;
 import android.os.IBinder;
 
@@ -46,44 +34,15 @@
 
 @RunWith(AndroidJUnit4.class)
 public class NetworkStackTest {
-    private static final String [] OTHER_PERMISSION = {"otherpermission1", "otherpermission2"};
-
     @Rule
     public DevSdkIgnoreRule mDevSdkIgnoreRule = new DevSdkIgnoreRule();
 
-    @Mock Context mCtx;
     @Mock private IBinder mConnectorBinder;
 
     @Before public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
     }
 
-    @Test
-    public void testCheckNetworkStackPermission() throws Exception {
-        when(mCtx.checkCallingOrSelfPermission(eq(NETWORK_STACK))).thenReturn(PERMISSION_GRANTED);
-        when(mCtx.checkCallingOrSelfPermission(eq(PERMISSION_MAINLINE_NETWORK_STACK)))
-                .thenReturn(PERMISSION_DENIED);
-        checkNetworkStackPermission(mCtx);
-        checkNetworkStackPermissionOr(mCtx, OTHER_PERMISSION);
-
-        when(mCtx.checkCallingOrSelfPermission(eq(NETWORK_STACK))).thenReturn(PERMISSION_DENIED);
-        when(mCtx.checkCallingOrSelfPermission(eq(PERMISSION_MAINLINE_NETWORK_STACK)))
-                .thenReturn(PERMISSION_GRANTED);
-        checkNetworkStackPermission(mCtx);
-        checkNetworkStackPermissionOr(mCtx, OTHER_PERMISSION);
-
-        when(mCtx.checkCallingOrSelfPermission(any())).thenReturn(PERMISSION_DENIED);
-
-        try {
-            checkNetworkStackPermissionOr(mCtx, OTHER_PERMISSION);
-        } catch (SecurityException e) {
-            // Expect to get a SecurityException
-            return;
-        }
-
-        fail("Expect fail but permission granted.");
-    }
-
     @Test @IgnoreUpTo(Build.VERSION_CODES.Q)
     public void testGetService() {
         NetworkStack.setServiceForTest(mConnectorBinder);
diff --git a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
new file mode 100644
index 0000000..56b56ef
--- /dev/null
+++ b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 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.net
+
+import android.net.ConnectivityManager.TYPE_NONE
+import android.net.ConnectivityManager.TYPE_WIFI
+import android.net.InetAddresses.parseNumericAddress
+import android.net.NetworkCapabilities.TRANSPORT_WIFI
+import android.os.Build
+import androidx.test.filters.SmallTest
+import com.android.testutils.DevSdkIgnoreRule
+import com.android.testutils.DevSdkIgnoreRunner
+import com.android.testutils.assertParcelSane
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.net.Inet4Address
+import java.net.Inet6Address
+
+private const val TEST_IMSI = "imsi1"
+private const val TEST_SSID = "SSID1"
+private const val TEST_NETID = 123
+
+private val TEST_IPV4_GATEWAY = parseNumericAddress("192.168.222.3") as Inet4Address
+private val TEST_IPV6_GATEWAY = parseNumericAddress("2001:db8::1") as Inet6Address
+private val TEST_IPV4_LINKADDR = LinkAddress("192.168.222.123/24")
+private val TEST_IPV6_LINKADDR = LinkAddress("2001:db8::123/64")
+private val TEST_IFACE = "fake0"
+private val TEST_LINK_PROPERTIES = LinkProperties().apply {
+    interfaceName = TEST_IFACE
+    addLinkAddress(TEST_IPV4_LINKADDR)
+    addLinkAddress(TEST_IPV6_LINKADDR)
+
+    // Add default routes
+    addRoute(RouteInfo(IpPrefix(parseNumericAddress("0.0.0.0"), 0), TEST_IPV4_GATEWAY))
+    addRoute(RouteInfo(IpPrefix(parseNumericAddress("::"), 0), TEST_IPV6_GATEWAY))
+}
+
+private val TEST_CAPABILITIES = NetworkCapabilities().apply {
+    addTransportType(TRANSPORT_WIFI)
+    setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false)
+    setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true)
+    setSSID(TEST_SSID)
+}
+
+@SmallTest
+@RunWith(DevSdkIgnoreRunner::class)
+@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R)
+class NetworkStateSnapshotTest {
+
+    @Test
+    fun testParcelUnparcel() {
+        val emptySnapshot = NetworkStateSnapshot(LinkProperties(), NetworkCapabilities(),
+                Network(TEST_NETID), null, TYPE_NONE)
+        val snapshot = NetworkStateSnapshot(
+                TEST_LINK_PROPERTIES, TEST_CAPABILITIES, Network(TEST_NETID), TEST_IMSI, TYPE_WIFI)
+        assertParcelSane(emptySnapshot, 5)
+        assertParcelSane(snapshot, 5)
+    }
+}
diff --git a/tests/net/integration/Android.bp b/tests/net/integration/Android.bp
index 4d1e337..56f9df7 100644
--- a/tests/net/integration/Android.bp
+++ b/tests/net/integration/Android.bp
@@ -35,7 +35,7 @@
         "android.test.mock",
     ],
     static_libs: [
-        "TestNetworkStackLib",
+        "NetworkStackApiStableLib",
         "androidx.test.ext.junit",
         "frameworks-net-integration-testutils",
         "kotlin-reflect",
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 083c8c8..9ed55f0 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -38,6 +38,7 @@
 import android.os.ConditionVariable
 import android.os.IBinder
 import android.os.INetworkManagementService
+import android.os.SystemConfigManager
 import android.os.UserHandle
 import android.testing.TestableContext
 import android.util.Log
@@ -57,6 +58,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.AdditionalAnswers
+import org.mockito.ArgumentMatchers.anyString
 import org.mockito.Mock
 import org.mockito.Mockito.any
 import org.mockito.Mockito.anyInt
@@ -94,6 +96,8 @@
     private lateinit var netd: INetd
     @Mock
     private lateinit var dnsResolver: IDnsResolver
+    @Mock
+    private lateinit var systemConfigManager: SystemConfigManager
     @Spy
     private var context = TestableContext(realContext)
 
@@ -151,6 +155,11 @@
         doReturn(UserHandle.ALL).`when`(asUserCtx).user
         doReturn(asUserCtx).`when`(context).createContextAsUser(eq(UserHandle.ALL), anyInt())
         doNothing().`when`(context).sendStickyBroadcast(any(), any())
+        doReturn(Context.SYSTEM_CONFIG_SERVICE).`when`(context)
+                .getSystemServiceName(SystemConfigManager::class.java)
+        doReturn(systemConfigManager).`when`(context)
+                .getSystemService(Context.SYSTEM_CONFIG_SERVICE)
+        doReturn(IntArray(0)).`when`(systemConfigManager).getSystemPermissionUids(anyString())
 
         networkStackClient = TestNetworkStackClient(realContext)
         networkStackClient.init()
diff --git a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
index dc9e587..e1da3d0 100644
--- a/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
+++ b/tests/net/integration/util/com/android/server/NetworkAgentWrapper.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
@@ -84,6 +85,7 @@
         final String typeName = ConnectivityManager.getNetworkTypeName(type);
         mNetworkCapabilities = (ncTemplate != null) ? ncTemplate : new NetworkCapabilities();
         mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_SUSPENDED);
+        mNetworkCapabilities.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         mNetworkCapabilities.addTransportType(transport);
         switch (transport) {
             case TRANSPORT_ETHERNET:
diff --git a/tests/net/java/android/net/NetworkIdentityTest.kt b/tests/net/java/android/net/NetworkIdentityTest.kt
new file mode 100644
index 0000000..eb2b85c
--- /dev/null
+++ b/tests/net/java/android/net/NetworkIdentityTest.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 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.net
+
+import android.net.NetworkIdentity.OEM_NONE
+import android.net.NetworkIdentity.OEM_PAID
+import android.net.NetworkIdentity.OEM_PRIVATE
+import android.net.NetworkIdentity.getOemBitfield
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import kotlin.test.assertEquals
+
+@RunWith(JUnit4::class)
+class NetworkIdentityTest {
+    @Test
+    fun testGetOemBitfield() {
+        val oemNone = NetworkCapabilities().apply {
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false)
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false)
+        }
+        val oemPaid = NetworkCapabilities().apply {
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true)
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, false)
+        }
+        val oemPrivate = NetworkCapabilities().apply {
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, false)
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true)
+        }
+        val oemAll = NetworkCapabilities().apply {
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID, true)
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE, true)
+        }
+
+        assertEquals(getOemBitfield(oemNone), OEM_NONE)
+        assertEquals(getOemBitfield(oemPaid), OEM_PAID)
+        assertEquals(getOemBitfield(oemPrivate), OEM_PRIVATE)
+        assertEquals(getOemBitfield(oemAll), OEM_PAID or OEM_PRIVATE)
+    }
+}
diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt
index 1f8f6f3..27224c2 100644
--- a/tests/net/java/android/net/NetworkTemplateTest.kt
+++ b/tests/net/java/android/net/NetworkTemplateTest.kt
@@ -20,14 +20,23 @@
 import android.net.ConnectivityManager.TYPE_MOBILE
 import android.net.ConnectivityManager.TYPE_WIFI
 import android.net.NetworkIdentity.SUBTYPE_COMBINED
+import android.net.NetworkIdentity.OEM_NONE;
+import android.net.NetworkIdentity.OEM_PAID;
+import android.net.NetworkIdentity.OEM_PRIVATE;
 import android.net.NetworkIdentity.buildNetworkIdentity
 import android.net.NetworkStats.DEFAULT_NETWORK_ALL
 import android.net.NetworkStats.METERED_ALL
 import android.net.NetworkStats.ROAMING_ALL
+import android.net.NetworkTemplate.MATCH_ETHERNET
 import android.net.NetworkTemplate.MATCH_MOBILE
+import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
 import android.net.NetworkTemplate.MATCH_WIFI
+import android.net.NetworkTemplate.MATCH_WIFI_WILDCARD
 import android.net.NetworkTemplate.NETWORK_TYPE_5G_NSA
 import android.net.NetworkTemplate.NETWORK_TYPE_ALL
+import android.net.NetworkTemplate.OEM_MANAGED_ALL
+import android.net.NetworkTemplate.OEM_MANAGED_NO
+import android.net.NetworkTemplate.OEM_MANAGED_YES
 import android.net.NetworkTemplate.buildTemplateMobileWithRatType
 import android.telephony.TelephonyManager
 import com.android.testutils.assertParcelSane
@@ -37,9 +46,11 @@
 import org.junit.runners.JUnit4
 import org.mockito.Mockito.mock
 import org.mockito.MockitoAnnotations
+import kotlin.test.assertEquals
 import kotlin.test.assertFalse
 import kotlin.test.assertNotEquals
 import kotlin.test.assertTrue
+import kotlin.test.fail
 
 private const val TEST_IMSI1 = "imsi1"
 private const val TEST_IMSI2 = "imsi2"
@@ -57,15 +68,20 @@
     private fun buildNetworkState(
         type: Int,
         subscriberId: String? = null,
-        ssid: String? = null
+        ssid: String? = null,
+        oemManaged: Int = OEM_NONE,
     ): NetworkState {
         val lp = LinkProperties()
         val caps = NetworkCapabilities().apply {
             setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false)
             setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true)
             setSSID(ssid)
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PAID,
+                    (oemManaged and OEM_PAID) == OEM_PAID)
+            setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
+                    (oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
         }
-        return NetworkState(type, lp, caps, mock(Network::class.java), subscriberId, ssid)
+        return NetworkState(type, lp, caps, mock(Network::class.java), subscriberId)
     }
 
     private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) =
@@ -136,11 +152,15 @@
     @Test
     fun testParcelUnparcel() {
         val templateMobile = NetworkTemplate(MATCH_MOBILE, TEST_IMSI1, null, null, METERED_ALL,
-                ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE)
+                ROAMING_ALL, DEFAULT_NETWORK_ALL, TelephonyManager.NETWORK_TYPE_LTE,
+                OEM_MANAGED_ALL)
         val templateWifi = NetworkTemplate(MATCH_WIFI, null, null, TEST_SSID1, METERED_ALL,
-                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0)
-        assertParcelSane(templateMobile, 8)
-        assertParcelSane(templateWifi, 8)
+                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_ALL)
+        val templateOem = NetworkTemplate(MATCH_MOBILE, null, null, null, METERED_ALL,
+                ROAMING_ALL, DEFAULT_NETWORK_ALL, 0, OEM_MANAGED_YES)
+        assertParcelSane(templateMobile, 9)
+        assertParcelSane(templateWifi, 9)
+        assertParcelSane(templateOem, 9)
     }
 
     // Verify NETWORK_TYPE_* constants in NetworkTemplate do not conflict with
@@ -152,4 +172,81 @@
             assertNotEquals(NETWORK_TYPE_5G_NSA, ratType)
         }
     }
+
+    @Test
+    fun testOemNetworkConstants() {
+        val constantValues = arrayOf(OEM_MANAGED_YES, OEM_MANAGED_ALL, OEM_MANAGED_NO,
+                OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
+
+        // Verify that "not OEM managed network" constants are equal.
+        assertEquals(OEM_MANAGED_NO, OEM_NONE);
+
+        // Verify the constants don't conflict.
+        assertEquals(constantValues.size, constantValues.distinct().count())
+    }
+
+    /**
+     * Helper to enumerate and assert OEM managed wifi and mobile {@code NetworkTemplate}s match
+     * their the appropriate OEM managed {@code NetworkIdentity}s.
+     *
+     * @param networkType {@code TYPE_MOBILE} or {@code TYPE_WIFI}
+     * @param matchType A match rule from {@code NetworkTemplate.MATCH_*} corresponding to the
+     *         networkType.
+     * @param subscriberId To be populated with {@code TEST_IMSI*} only if networkType is
+     *         {@code TYPE_MOBILE}. May be left as null when matchType is
+     *         {@link NetworkTemplate.MATCH_MOBILE_WILDCARD}.
+     * @param templateSsid Top be populated with {@code TEST_SSID*} only if networkType is
+     *         {@code TYPE_WIFI}. May be left as null when matchType is
+     *         {@link NetworkTemplate.MATCH_WIFI_WILDCARD}.
+     * @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide
+     *         one of {@code TEST_SSID*}.
+     */
+    private fun matchOemManagedIdent(networkType: Int, matchType:Int, subscriberId: String? = null,
+            templateSsid: String? = null, identSsid: String? = null) {
+        val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
+        // A null subscriberId needs a null matchSubscriberIds argument as well.
+        val matchSubscriberIds = if (subscriberId == null) null else arrayOf(subscriberId)
+
+        val templateOemYes = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
+                templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                OEM_MANAGED_YES)
+        val templateOemAll = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
+                templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                OEM_MANAGED_ALL)
+
+        for (identityOemManagedState in oemManagedStates) {
+            val ident = buildNetworkIdentity(mockContext, buildNetworkState(networkType,
+                    subscriberId, identSsid, identityOemManagedState), /*defaultNetwork=*/false,
+                    /*subType=*/0)
+
+            // Create a template with each OEM managed type and match it against the NetworkIdentity
+            for (templateOemManagedState in oemManagedStates) {
+                val template = NetworkTemplate(matchType, subscriberId, matchSubscriberIds,
+                        templateSsid, METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL,
+                        NETWORK_TYPE_ALL, templateOemManagedState)
+                if (identityOemManagedState == templateOemManagedState) {
+                    template.assertMatches(ident)
+                } else {
+                    template.assertDoesNotMatch(ident)
+                }
+            }
+            // OEM_MANAGED_ALL ignores OEM state.
+            templateOemAll.assertMatches(ident)
+            if (identityOemManagedState == OEM_NONE) {
+                // OEM_MANAGED_YES matches everything except OEM_NONE.
+                templateOemYes.assertDoesNotMatch(ident)
+            } else {
+                templateOemYes.assertMatches(ident)
+            }
+        }
+    }
+
+    @Test
+    fun testOemManagedMatchesIdent() {
+        matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE, subscriberId = TEST_IMSI1)
+        matchOemManagedIdent(TYPE_MOBILE, MATCH_MOBILE_WILDCARD)
+        matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI, templateSsid = TEST_SSID1,
+                identSsid = TEST_SSID1)
+        matchOemManagedIdent(TYPE_WIFI, MATCH_WIFI_WILDCARD, identSsid = TEST_SSID1)
+    }
 }
diff --git a/tests/net/java/android/net/VpnTransportInfoTest.java b/tests/net/java/android/net/VpnTransportInfoTest.java
index 866f38c..d04c87b 100644
--- a/tests/net/java/android/net/VpnTransportInfoTest.java
+++ b/tests/net/java/android/net/VpnTransportInfoTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2021 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.
diff --git a/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
new file mode 100644
index 0000000..9b0cfa9
--- /dev/null
+++ b/tests/net/java/android/net/util/MultinetworkPolicyTrackerTest.kt
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2021 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.net.util
+
+import android.content.Context
+import android.content.res.Resources
+import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_HANDOVER
+import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_PERFORMANCE
+import android.net.ConnectivityManager.MULTIPATH_PREFERENCE_RELIABILITY
+import android.net.util.MultinetworkPolicyTracker.ActiveDataSubscriptionIdChangedListener
+import android.provider.Settings
+import android.provider.Settings.Global.NETWORK_AVOID_BAD_WIFI
+import android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE
+import android.telephony.SubscriptionInfo
+import android.telephony.SubscriptionManager
+import android.telephony.TelephonyManager
+import android.test.mock.MockContentResolver
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import com.android.internal.R
+import com.android.internal.util.test.FakeSettingsProvider
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
+import org.mockito.ArgumentMatchers.argThat
+import org.mockito.Mockito.any
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+
+/**
+ * Tests for [MultinetworkPolicyTracker].
+ *
+ * Build, install and run with:
+ * atest android.net.util.MultinetworkPolicyTrackerTest
+ */
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class MultinetworkPolicyTrackerTest {
+    private val resources = mock(Resources::class.java).also {
+        doReturn(0).`when`(it).getInteger(R.integer.config_networkAvoidBadWifi)
+    }
+    private val telephonyManager = mock(TelephonyManager::class.java)
+    private val subscriptionManager = mock(SubscriptionManager::class.java).also {
+        doReturn(null).`when`(it).getActiveSubscriptionInfo(anyInt())
+    }
+    private val resolver = MockContentResolver().apply {
+        addProvider(Settings.AUTHORITY, FakeSettingsProvider()) }
+    private val context = mock(Context::class.java).also {
+        doReturn(Context.TELEPHONY_SERVICE).`when`(it)
+                .getSystemServiceName(TelephonyManager::class.java)
+        doReturn(telephonyManager).`when`(it).getSystemService(Context.TELEPHONY_SERVICE)
+        doReturn(subscriptionManager).`when`(it)
+                .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE)
+        doReturn(resolver).`when`(it).contentResolver
+        doReturn(resources).`when`(it).resources
+        doReturn(it).`when`(it).createConfigurationContext(any())
+        Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "1")
+    }
+    private val tracker = MultinetworkPolicyTracker(context, null /* handler */)
+
+    private fun assertMultipathPreference(preference: Int) {
+        Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+                preference.toString())
+        tracker.updateMeteredMultipathPreference()
+        assertEquals(preference, tracker.meteredMultipathPreference)
+    }
+
+    @Test
+    fun testUpdateMeteredMultipathPreference() {
+        assertMultipathPreference(MULTIPATH_PREFERENCE_HANDOVER)
+        assertMultipathPreference(MULTIPATH_PREFERENCE_RELIABILITY)
+        assertMultipathPreference(MULTIPATH_PREFERENCE_PERFORMANCE)
+    }
+
+    @Test
+    fun testUpdateAvoidBadWifi() {
+        Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0")
+        assertTrue(tracker.updateAvoidBadWifi())
+        assertFalse(tracker.avoidBadWifi)
+
+        doReturn(1).`when`(resources).getInteger(R.integer.config_networkAvoidBadWifi)
+        assertTrue(tracker.updateAvoidBadWifi())
+        assertTrue(tracker.avoidBadWifi)
+    }
+
+    @Test
+    fun testOnActiveDataSubscriptionIdChanged() {
+        val testSubId = 1000
+        val subscriptionInfo = SubscriptionInfo(testSubId, ""/* iccId */, 1/* iccId */,
+                "TMO"/* displayName */, "TMO"/* carrierName */, 1/* nameSource */, 1/* iconTint */,
+                "123"/* number */, 1/* roaming */, null/* icon */, "310"/* mcc */, "210"/* mnc */,
+                ""/* countryIso */, false/* isEmbedded */, null/* nativeAccessRules */,
+                "1"/* cardString */)
+        doReturn(subscriptionInfo).`when`(subscriptionManager).getActiveSubscriptionInfo(testSubId)
+
+        // Modify avoidBadWifi and meteredMultipathPreference settings value and local variables in
+        // MultinetworkPolicyTracker should be also updated after subId changed.
+        Settings.Global.putString(resolver, NETWORK_AVOID_BAD_WIFI, "0")
+        Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
+                MULTIPATH_PREFERENCE_PERFORMANCE.toString())
+
+        val listenerCaptor = ArgumentCaptor.forClass(
+                ActiveDataSubscriptionIdChangedListener::class.java)
+        verify(telephonyManager, times(1))
+                .registerPhoneStateListener(any(), listenerCaptor.capture())
+        val listener = listenerCaptor.value
+        listener.onActiveDataSubscriptionIdChanged(testSubId)
+
+        // Check it get resource value with test sub id.
+        verify(subscriptionManager, times(1)).getActiveSubscriptionInfo(testSubId)
+        verify(context).createConfigurationContext(argThat { it.mcc == 310 && it.mnc == 210 })
+
+        // Check if avoidBadWifi and meteredMultipathPreference values have been updated.
+        assertFalse(tracker.avoidBadWifi)
+        assertEquals(MULTIPATH_PREFERENCE_PERFORMANCE, tracker.meteredMultipathPreference)
+    }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 182897e..bb822d8 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -84,6 +84,11 @@
 import static android.net.NetworkPolicyManager.RULE_NONE;
 import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED;
 import static android.net.RouteInfo.RTN_UNREACHABLE;
 import static android.os.Process.INVALID_UID;
 import static android.system.OsConstants.IPPROTO_TCP;
@@ -233,6 +238,7 @@
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.os.SystemClock;
+import android.os.SystemConfigManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -355,6 +361,7 @@
     private static final long TIMESTAMP = 1234L;
 
     private static final int NET_ID = 110;
+    private static final int OEM_PREF_ANY_NET_ID = -1;
     // Set a non-zero value to verify the flow to set tcp init rwnd value.
     private static final int TEST_TCP_INIT_RWND = 60;
 
@@ -399,6 +406,8 @@
     private QosCallbackMockHelper mQosCallbackMockHelper;
     private QosCallbackTracker mQosCallbackTracker;
     private VpnManagerService mVpnManagerService;
+    private TestNetworkCallback mDefaultNetworkCallback;
+    private TestNetworkCallback mSystemDefaultNetworkCallback;
 
     // State variables required to emulate NetworkPolicyManagerService behaviour.
     private int mUidRules = RULE_NONE;
@@ -424,7 +433,7 @@
     @Mock EthernetManager mEthernetManager;
     @Mock NetworkPolicyManager mNetworkPolicyManager;
     @Mock KeyStore mKeyStore;
-    @Mock IOnSetOemNetworkPreferenceListener mOnSetOemNetworkPreferenceListener;
+    @Mock SystemConfigManager mSystemConfigManager;
 
     private ArgumentCaptor<ResolverParamsParcel> mResolverParamsParcelCaptor =
             ArgumentCaptor.forClass(ResolverParamsParcel.class);
@@ -521,6 +530,7 @@
             if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager;
             if (Context.ETHERNET_SERVICE.equals(name)) return mEthernetManager;
             if (Context.NETWORK_POLICY_SERVICE.equals(name)) return mNetworkPolicyManager;
+            if (Context.SYSTEM_CONFIG_SERVICE.equals(name)) return mSystemConfigManager;
             return super.getSystemService(name);
         }
 
@@ -994,10 +1004,12 @@
         // Used to collect the networks requests managed by this factory. This is a duplicate of
         // the internal information stored in the NetworkFactory (which is private).
         private SparseArray<NetworkRequest> mNetworkRequests = new SparseArray<>();
+        private final HandlerThread mHandlerSendingRequests;
 
         public MockNetworkFactory(Looper looper, Context context, String logTag,
-                NetworkCapabilities filter) {
+                NetworkCapabilities filter, HandlerThread threadSendingRequests) {
             super(looper, context, logTag, filter);
+            mHandlerSendingRequests = threadSendingRequests;
         }
 
         public int getMyRequestCount() {
@@ -1051,7 +1063,8 @@
         public void terminate() {
             super.terminate();
             // Make sure there are no remaining requests unaccounted for.
-            assertNull(mRequestHistory.poll(TIMEOUT_MS, r -> true));
+            HandlerUtils.waitForIdle(mHandlerSendingRequests, TIMEOUT_MS);
+            assertNull(mRequestHistory.poll(0, r -> true));
         }
 
         // Trigger releasing the request as unfulfillable
@@ -1424,6 +1437,7 @@
         applicationInfo.targetSdkVersion = Build.VERSION_CODES.Q;
         when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any()))
                 .thenReturn(applicationInfo);
+        when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
 
         // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
         // http://b/25897652 .
@@ -1534,6 +1548,7 @@
 
     @After
     public void tearDown() throws Exception {
+        unregisterDefaultNetworkCallbacks();
         setAlwaysOnNetworks(false);
         if (mCellNetworkAgent != null) {
             mCellNetworkAgent.disconnect();
@@ -1609,10 +1624,13 @@
         }
         switch (transport) {
             case TRANSPORT_WIFI:
-                assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork());
+                assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
                 break;
             case TRANSPORT_CELLULAR:
-                assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork());
+                assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
+                break;
+            case TRANSPORT_ETHERNET:
+                assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
                 break;
             default:
                 break;
@@ -1621,6 +1639,7 @@
         assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork()));
         assertEquals(transportToLegacyType(transport),
                 mCm.getNetworkInfo(mCm.getActiveNetwork()).getType());
+        assertNotNull(mCm.getActiveNetworkInfoForUid(Process.myUid()));
         // Test getNetworkCapabilities(Network)
         assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork()));
         assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport));
@@ -2158,6 +2177,24 @@
         }
     }
 
+    static void expectOnLost(TestNetworkAgentWrapper network, TestNetworkCallback ... callbacks) {
+        for (TestNetworkCallback c : callbacks) {
+            c.expectCallback(CallbackEntry.LOST, network);
+        }
+    }
+
+    static void expectAvailableCallbacksUnvalidatedWithSpecifier(TestNetworkAgentWrapper network,
+            NetworkSpecifier specifier, TestNetworkCallback ... callbacks) {
+        for (TestNetworkCallback c : callbacks) {
+            c.expectCallback(CallbackEntry.AVAILABLE, network);
+            c.expectCapabilitiesThat(network, (nc) ->
+                    !nc.hasCapability(NET_CAPABILITY_VALIDATED)
+                            && Objects.equals(specifier, nc.getNetworkSpecifier()));
+            c.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, network);
+            c.expectCallback(CallbackEntry.BLOCKED_STATUS, network);
+        }
+    }
+
     @Test
     public void testStateChangeNetworkCallbacks() throws Exception {
         final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
@@ -2761,10 +2798,14 @@
 
         NetworkCapabilities filter = new NetworkCapabilities();
         filter.addCapability(capability);
+        // Add NOT_VCN_MANAGED capability into filter unconditionally since some request will add
+        // NOT_VCN_MANAGED automatically but not for NetworkCapabilities,
+        // see {@code NetworkCapabilities#deduceNotVcnManagedCapability} for more details.
+        filter.addCapability(NET_CAPABILITY_NOT_VCN_MANAGED);
         final HandlerThread handlerThread = new HandlerThread("testNetworkFactoryRequests");
         handlerThread.start();
         final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
-                mServiceContext, "testFactory", filter);
+                mServiceContext, "testFactory", filter, mCsHandlerThread);
         testFactory.setScoreFilter(40);
         ConditionVariable cv = testFactory.getNetworkStartedCV();
         testFactory.register();
@@ -2872,7 +2913,7 @@
         // does not crash.
         for (int i = 0; i < 100; i++) {
             final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
-                    mServiceContext, "testFactory", filter);
+                    mServiceContext, "testFactory", filter, mCsHandlerThread);
             // Register the factory and don't be surprised when the default request arrives.
             testFactory.register();
             testFactory.expectRequestAdd();
@@ -3521,11 +3562,9 @@
     /**
      * Verify request matching behavior with network specifiers.
      *
-     * Note: this test is somewhat problematic since it involves removing capabilities from
-     * agents - i.e. agents rejecting requests which they previously accepted. This is flagged
-     * as a WTF bug in
-     * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)} but
-     * does work.
+     * This test does not check updating the specifier on a live network because the specifier is
+     * immutable and this triggers a WTF in
+     * {@link ConnectivityService#mixInCapabilities(NetworkAgentInfo, NetworkCapabilities)}.
      */
     @Test
     public void testNetworkSpecifier() throws Exception {
@@ -3610,60 +3649,49 @@
 
         mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
-        cEmpty1.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        cEmpty2.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        cEmpty3.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        cEmpty4.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
+        expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */,
+                cEmpty1, cEmpty2, cEmpty3, cEmpty4);
         assertNoCallbacks(cFoo, cBar);
 
+        mWiFiNetworkAgent.disconnect();
+        expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4);
+
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
         mWiFiNetworkAgent.setNetworkSpecifier(nsFoo);
-        cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        for (TestNetworkCallback c: emptyCallbacks) {
-            c.expectCapabilitiesThat(mWiFiNetworkAgent,
-                    (caps) -> caps.getNetworkSpecifier().equals(nsFoo));
-        }
-        cFoo.expectCapabilitiesThat(mWiFiNetworkAgent,
-                (caps) -> caps.getNetworkSpecifier().equals(nsFoo));
+        mWiFiNetworkAgent.connect(false);
+        expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsFoo,
+                cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo);
+        cBar.assertNoCallback();
         assertEquals(nsFoo,
                 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
-        cFoo.assertNoCallback();
+        assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo);
 
+        mWiFiNetworkAgent.disconnect();
+        expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo);
+
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
         mWiFiNetworkAgent.setNetworkSpecifier(nsBar);
-        cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
-        cBar.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        for (TestNetworkCallback c: emptyCallbacks) {
-            c.expectCapabilitiesThat(mWiFiNetworkAgent,
-                    (caps) -> caps.getNetworkSpecifier().equals(nsBar));
-        }
-        cBar.expectCapabilitiesThat(mWiFiNetworkAgent,
-                (caps) -> caps.getNetworkSpecifier().equals(nsBar));
+        mWiFiNetworkAgent.connect(false);
+        expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, nsBar,
+                cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar);
+        cFoo.assertNoCallback();
         assertEquals(nsBar,
                 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
-        cBar.assertNoCallback();
 
+        mWiFiNetworkAgent.disconnect();
+        expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cBar);
+        cFoo.assertNoCallback();
+
+        mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
         mWiFiNetworkAgent.setNetworkSpecifier(new ConfidentialMatchAllNetworkSpecifier());
-        cFoo.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
-        for (TestNetworkCallback c : emptyCallbacks) {
-            c.expectCapabilitiesThat(mWiFiNetworkAgent,
-                    (caps) -> caps.getNetworkSpecifier() == null);
-        }
-        cFoo.expectCapabilitiesThat(mWiFiNetworkAgent,
-                (caps) -> caps.getNetworkSpecifier() == null);
-        cBar.expectCapabilitiesThat(mWiFiNetworkAgent,
-                (caps) -> caps.getNetworkSpecifier() == null);
+        mWiFiNetworkAgent.connect(false);
+        expectAvailableCallbacksUnvalidatedWithSpecifier(mWiFiNetworkAgent, null /* specifier */,
+                cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
         assertNull(
                 mCm.getNetworkCapabilities(mWiFiNetworkAgent.getNetwork()).getNetworkSpecifier());
-        cFoo.assertNoCallback();
-        cBar.assertNoCallback();
 
-        mWiFiNetworkAgent.setNetworkSpecifier(null);
-        cFoo.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
-        cBar.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
-        for (TestNetworkCallback c: emptyCallbacks) {
-            c.expectCallback(CallbackEntry.NETWORK_CAPS_UPDATED, mWiFiNetworkAgent);
-        }
-
-        assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
+        mWiFiNetworkAgent.disconnect();
+        expectOnLost(mWiFiNetworkAgent, cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
     }
 
     /**
@@ -4120,9 +4148,10 @@
         handlerThread.start();
         NetworkCapabilities filter = new NetworkCapabilities()
                 .addTransportType(TRANSPORT_CELLULAR)
+                .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
                 .addCapability(NET_CAPABILITY_INTERNET);
         final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
-                mServiceContext, "testFactory", filter);
+                mServiceContext, "testFactory", filter, mCsHandlerThread);
         testFactory.setScoreFilter(40);
 
         // Register the factory and expect it to start looking for a network.
@@ -4170,6 +4199,7 @@
             // ...  and cell data to be torn down after nascent network timeout.
             cellNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent,
                     mService.mNascentDelayMs + TEST_CALLBACK_TIMEOUT_MS);
+            waitForIdle();
             assertLength(1, mCm.getAllNetworks());
         } finally {
             testFactory.terminate();
@@ -4469,7 +4499,7 @@
                 .addTransportType(TRANSPORT_WIFI)
                 .addCapability(NET_CAPABILITY_INTERNET);
         final MockNetworkFactory testFactory = new MockNetworkFactory(handlerThread.getLooper(),
-                mServiceContext, "testFactory", filter);
+                mServiceContext, "testFactory", filter, mCsHandlerThread);
         testFactory.setScoreFilter(40);
 
         // Register the factory and expect it to receive the default request.
@@ -6023,6 +6053,7 @@
                 .addTransportType(TRANSPORT_CELLULAR)
                 .addCapability(NET_CAPABILITY_INTERNET)
                 .addCapability(NET_CAPABILITY_NOT_CONGESTED)
+                .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
                 .setLinkDownstreamBandwidthKbps(10);
         final NetworkCapabilities wifiNc = new NetworkCapabilities()
                 .addTransportType(TRANSPORT_WIFI)
@@ -6031,6 +6062,7 @@
                 .addCapability(NET_CAPABILITY_NOT_ROAMING)
                 .addCapability(NET_CAPABILITY_NOT_CONGESTED)
                 .addCapability(NET_CAPABILITY_NOT_SUSPENDED)
+                .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED)
                 .setLinkUpstreamBandwidthKbps(20);
         mCellNetworkAgent.setNetworkCapabilities(cellNc, true /* sendToConnectivityService */);
         mWiFiNetworkAgent.setNetworkCapabilities(wifiNc, true /* sendToConnectivityService */);
@@ -6818,6 +6850,7 @@
                 .thenReturn(UserHandle.getUid(RESTRICTED_USER, VPN_UID));
 
         final Intent addedIntent = new Intent(ACTION_USER_ADDED);
+        addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER));
         addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
 
         // Send a USER_ADDED broadcast for it.
@@ -6828,7 +6861,7 @@
         callback.expectCapabilitiesThat(mMockVpn, (caps)
                 -> caps.getUids().size() == 2
                 && caps.getUids().contains(new UidRange(uid, uid))
-                && caps.getUids().contains(UidRange.createForUser(RESTRICTED_USER))
+                && caps.getUids().contains(createUidRange(RESTRICTED_USER))
                 && caps.hasTransport(TRANSPORT_VPN)
                 && caps.hasTransport(TRANSPORT_WIFI));
 
@@ -6838,12 +6871,13 @@
         callback.expectCapabilitiesThat(mMockVpn, (caps)
                 -> caps.getUids().size() == 2
                 && caps.getUids().contains(new UidRange(uid, uid))
-                && caps.getUids().contains(UidRange.createForUser(RESTRICTED_USER))
+                && caps.getUids().contains(createUidRange(RESTRICTED_USER))
                 && caps.hasTransport(TRANSPORT_VPN)
                 && !caps.hasTransport(TRANSPORT_WIFI));
 
         // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
         final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
+        removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER));
         removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
         processBroadcastForVpn(removedIntent);
 
@@ -6901,6 +6935,7 @@
                 RESTRICTED_USER_INFO));
         // TODO: check that VPN app within restricted profile still has access, etc.
         final Intent addedIntent = new Intent(ACTION_USER_ADDED);
+        addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER));
         addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
         processBroadcastForVpn(addedIntent);
         assertNull(mCm.getActiveNetworkForUid(uid));
@@ -6911,6 +6946,7 @@
 
         // Send a USER_REMOVED broadcast and expect to lose the UID range for the restricted user.
         final Intent removedIntent = new Intent(ACTION_USER_REMOVED);
+        removedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(RESTRICTED_USER));
         removedIntent.putExtra(Intent.EXTRA_USER_HANDLE, RESTRICTED_USER);
         processBroadcastForVpn(removedIntent);
         assertNull(mCm.getActiveNetworkForUid(uid));
@@ -7469,7 +7505,7 @@
         assertNotNull(underlying);
         mMockVpn.setVpnType(VpnManager.TYPE_VPN_LEGACY);
         // The legacy lockdown VPN only supports userId 0.
-        final Set<UidRange> ranges = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+        final Set<UidRange> ranges = Collections.singleton(createUidRange(PRIMARY_USER));
         mMockVpn.registerAgent(ranges);
         mMockVpn.setUnderlyingNetworks(new Network[]{underlying});
         mMockVpn.connect(true);
@@ -7505,6 +7541,7 @@
         // Send a USER_UNLOCKED broadcast so CS starts LockdownVpnTracker.
         final int userId = UserHandle.getUserId(Process.myUid());
         final Intent addedIntent = new Intent(ACTION_USER_UNLOCKED);
+        addedIntent.putExtra(Intent.EXTRA_USER, UserHandle.of(userId));
         addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
         processBroadcastForVpn(addedIntent);
 
@@ -7718,19 +7755,13 @@
             mWiFiNetworkAgent.removeCapability(testCap);
             callbackWithCap.expectAvailableCallbacksValidated(mCellNetworkAgent);
             callbackWithoutCap.expectCapabilitiesWithout(testCap, mWiFiNetworkAgent);
-            // TODO: Test default network changes for NOT_VCN_MANAGED once the default request has
-            //  it.
-            if (testCap == NET_CAPABILITY_TRUSTED) {
-                verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId));
-                reset(mMockNetd);
-            }
+            verify(mMockNetd).networkSetDefault(eq(mCellNetworkAgent.getNetwork().netId));
+            reset(mMockNetd);
 
             mCellNetworkAgent.removeCapability(testCap);
             callbackWithCap.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
             callbackWithoutCap.assertNoCallback();
-            if (testCap == NET_CAPABILITY_TRUSTED) {
-                verify(mMockNetd).networkClearDefault();
-            }
+            verify(mMockNetd).networkClearDefault();
 
             mCm.unregisterNetworkCallback(callbackWithCap);
             mCm.unregisterNetworkCallback(callbackWithoutCap);
@@ -8205,8 +8236,8 @@
         reset(mNetworkManagementService);
         mCellNetworkAgent.connect(true);
         networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
-        verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
-                eq(NetworkCapabilities.TRANSPORT_CELLULAR));
+        verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
+                eq(Integer.toString(TRANSPORT_CELLULAR)));
 
         mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
         final LinkProperties wifiLp = new LinkProperties();
@@ -8214,25 +8245,27 @@
         mWiFiNetworkAgent.sendLinkProperties(wifiLp);
 
         // Network switch
-        reset(mNetworkManagementService);
         mWiFiNetworkAgent.connect(true);
         networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
         networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
-        verify(mNetworkManagementService, times(1)).addIdleTimer(eq(WIFI_IFNAME), anyInt(),
-                eq(NetworkCapabilities.TRANSPORT_WIFI));
-        verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(MOBILE_IFNAME));
+        verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
+                eq(Integer.toString(TRANSPORT_WIFI)));
+        verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
+                eq(Integer.toString(TRANSPORT_CELLULAR)));
 
         // Disconnect wifi and switch back to cell
-        reset(mNetworkManagementService);
+        reset(mMockNetd);
         mWiFiNetworkAgent.disconnect();
         networkCallback.expectCallback(CallbackEntry.LOST, mWiFiNetworkAgent);
         assertNoCallbacks(networkCallback);
-        verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
-        verify(mNetworkManagementService, times(1)).addIdleTimer(eq(MOBILE_IFNAME), anyInt(),
-                eq(NetworkCapabilities.TRANSPORT_CELLULAR));
+        verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(),
+                eq(Integer.toString(TRANSPORT_WIFI)));
+        verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
+                eq(Integer.toString(TRANSPORT_CELLULAR)));
 
         // reconnect wifi
+        reset(mMockNetd);
         mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
         wifiLp.setInterfaceName(WIFI_IFNAME);
         mWiFiNetworkAgent.sendLinkProperties(wifiLp);
@@ -8240,9 +8273,12 @@
         networkCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
         networkCallback.expectCallback(CallbackEntry.LOSING, mCellNetworkAgent);
         networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        verify(mMockNetd, times(1)).idletimerAddInterface(eq(WIFI_IFNAME), anyInt(),
+                eq(Integer.toString(TRANSPORT_WIFI)));
+        verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
+                eq(Integer.toString(TRANSPORT_CELLULAR)));
 
         // Disconnect cell
-        reset(mNetworkManagementService);
         reset(mMockNetd);
         mCellNetworkAgent.disconnect();
         networkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
@@ -8250,17 +8286,18 @@
         // sent as network being switched. Ensure rule removal for cell will not be triggered
         // unexpectedly before network being removed.
         waitForIdle();
-        verify(mNetworkManagementService, times(0)).removeIdleTimer(eq(MOBILE_IFNAME));
+        verify(mMockNetd, times(0)).idletimerRemoveInterface(eq(MOBILE_IFNAME), anyInt(),
+                eq(Integer.toString(TRANSPORT_CELLULAR)));
         verify(mMockNetd, times(1)).networkDestroy(eq(mCellNetworkAgent.getNetwork().netId));
         verify(mMockDnsResolver, times(1))
                 .destroyNetworkCache(eq(mCellNetworkAgent.getNetwork().netId));
 
         // Disconnect wifi
         ExpectedBroadcast b = expectConnectivityAction(TYPE_WIFI, DetailedState.DISCONNECTED);
-        reset(mNetworkManagementService);
         mWiFiNetworkAgent.disconnect();
         b.expectBroadcast();
-        verify(mNetworkManagementService, times(1)).removeIdleTimer(eq(WIFI_IFNAME));
+        verify(mMockNetd, times(1)).idletimerRemoveInterface(eq(WIFI_IFNAME), anyInt(),
+                eq(Integer.toString(TRANSPORT_WIFI)));
 
         // Clean up
         mCm.unregisterNetworkCallback(networkCallback);
@@ -8381,7 +8418,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
         // The uid range needs to cover the test app so the network is visible to it.
-        final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
         mMockVpn.establish(lp, VPN_UID, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
 
@@ -8409,7 +8446,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
         // The uid range needs to cover the test app so the network is visible to it.
-        final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
         mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
 
@@ -8425,7 +8462,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix("192.0.2.0/24"), null, "tun0"));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), RTN_UNREACHABLE));
         // The uid range needs to cover the test app so the network is visible to it.
-        final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
         mMockVpn.establish(lp, Process.SYSTEM_UID, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, Process.SYSTEM_UID);
 
@@ -8440,7 +8477,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
         // The uid range needs to cover the test app so the network is visible to it.
-        final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
         mMockVpn.establish(lp, VPN_UID, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, VPN_UID);
 
@@ -8492,7 +8529,7 @@
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), RTN_UNREACHABLE));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
         // The uid range needs to cover the test app so the network is visible to it.
-        final UidRange vpnRange = UidRange.createForUser(PRIMARY_USER);
+        final UidRange vpnRange = createUidRange(PRIMARY_USER);
         final Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
         mMockVpn.establish(lp, VPN_UID, vpnRanges);
         assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
@@ -8691,7 +8728,7 @@
 
     private void setupConnectionOwnerUid(int vpnOwnerUid, @VpnManager.VpnType int vpnType)
             throws Exception {
-        final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(PRIMARY_USER));
+        final Set<UidRange> vpnRange = Collections.singleton(createUidRange(PRIMARY_USER));
         mMockVpn.setVpnType(vpnType);
         mMockVpn.establish(new LinkProperties(), vpnOwnerUid, vpnRange);
         assertVpnUidRangesUpdated(true, vpnRange, vpnOwnerUid);
@@ -9250,7 +9287,7 @@
         lp.setInterfaceName("tun0");
         lp.addRoute(new RouteInfo(new IpPrefix(Inet4Address.ANY, 0), null));
         lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null));
-        final UidRange vpnRange = UidRange.createForUser(PRIMARY_USER);
+        final UidRange vpnRange = createUidRange(PRIMARY_USER);
         Set<UidRange> vpnRanges = Collections.singleton(vpnRange);
         mMockVpn.establish(lp, VPN_UID, vpnRanges);
         assertVpnUidRangesUpdated(true, vpnRanges, VPN_UID);
@@ -9430,8 +9467,12 @@
         fail("TOO_MANY_REQUESTS never thrown");
     }
 
+    private UidRange createUidRange(int userId) {
+        return UidRange.createForUser(UserHandle.of(userId));
+    }
+
     private void mockGetApplicationInfo(@NonNull final String packageName, @NonNull final int uid)
-            throws PackageManager.NameNotFoundException {
+            throws Exception {
         final ApplicationInfo applicationInfo = new ApplicationInfo();
         applicationInfo.uid = uid;
         when(mPackageManager.getApplicationInfo(eq(packageName), anyInt()))
@@ -9451,7 +9492,7 @@
 
     private OemNetworkPreferences createDefaultOemNetworkPreferences(
             @OemNetworkPreferences.OemNetworkPreference final int preference)
-            throws PackageManager.NameNotFoundException {
+            throws Exception {
         // Arrange PackageManager mocks
         mockGetApplicationInfo(TEST_PACKAGE_NAME, TEST_PACKAGE_UID);
 
@@ -9465,7 +9506,7 @@
     public void testOemNetworkRequestFactoryPreferenceUninitializedThrowsError()
             throws PackageManager.NameNotFoundException {
         @OemNetworkPreferences.OemNetworkPreference final int prefToTest =
-                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED;
+                OEM_NETWORK_PREFERENCE_UNINITIALIZED;
 
         // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
         assertThrows(IllegalArgumentException.class,
@@ -9476,13 +9517,13 @@
 
     @Test
     public void testOemNetworkRequestFactoryPreferenceOemPaid()
-            throws PackageManager.NameNotFoundException {
+            throws Exception {
         // Expectations
         final int expectedNumOfNris = 1;
         final int expectedNumOfRequests = 3;
 
         @OemNetworkPreferences.OemNetworkPreference final int prefToTest =
-                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
+                OEM_NETWORK_PREFERENCE_OEM_PAID;
 
         // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
         final ArraySet<ConnectivityService.NetworkRequestInfo> nris =
@@ -9505,13 +9546,13 @@
 
     @Test
     public void testOemNetworkRequestFactoryPreferenceOemPaidNoFallback()
-            throws PackageManager.NameNotFoundException {
+            throws Exception {
         // Expectations
         final int expectedNumOfNris = 1;
         final int expectedNumOfRequests = 2;
 
         @OemNetworkPreferences.OemNetworkPreference final int prefToTest =
-                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+                OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
 
         // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
         final ArraySet<ConnectivityService.NetworkRequestInfo> nris =
@@ -9531,13 +9572,13 @@
 
     @Test
     public void testOemNetworkRequestFactoryPreferenceOemPaidOnly()
-            throws PackageManager.NameNotFoundException {
+            throws Exception {
         // Expectations
         final int expectedNumOfNris = 1;
         final int expectedNumOfRequests = 1;
 
         @OemNetworkPreferences.OemNetworkPreference final int prefToTest =
-                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+                OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
 
         // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
         final ArraySet<ConnectivityService.NetworkRequestInfo> nris =
@@ -9554,13 +9595,13 @@
 
     @Test
     public void testOemNetworkRequestFactoryPreferenceOemPrivateOnly()
-            throws PackageManager.NameNotFoundException {
+            throws Exception {
         // Expectations
         final int expectedNumOfNris = 1;
         final int expectedNumOfRequests = 1;
 
         @OemNetworkPreferences.OemNetworkPreference final int prefToTest =
-                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+                OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
 
         // Act on OemNetworkRequestFactory.createNrisFromOemNetworkPreferences()
         final ArraySet<ConnectivityService.NetworkRequestInfo> nris =
@@ -9578,7 +9619,7 @@
 
     @Test
     public void testOemNetworkRequestFactoryCreatesCorrectNumOfNris()
-            throws PackageManager.NameNotFoundException {
+            throws Exception {
         // Expectations
         final int expectedNumOfNris = 2;
 
@@ -9588,8 +9629,8 @@
         mockGetApplicationInfo(testPackageName2, TEST_PACKAGE_UID);
 
         // Build OemNetworkPreferences object
-        final int testOemPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
-        final int testOemPref2 = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+        final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID;
+        final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
         final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
                 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref)
                 .addNetworkPreference(testPackageName2, testOemPref2)
@@ -9605,7 +9646,7 @@
 
     @Test
     public void testOemNetworkRequestFactoryCorrectlySetsUids()
-            throws PackageManager.NameNotFoundException {
+            throws Exception {
         // Arrange PackageManager mocks
         final String testPackageName2 = "com.google.apps.dialer";
         final int testPackageNameUid2 = 456;
@@ -9613,8 +9654,8 @@
         mockGetApplicationInfo(testPackageName2, testPackageNameUid2);
 
         // Build OemNetworkPreferences object
-        final int testOemPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
-        final int testOemPref2 = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+        final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID;
+        final int testOemPref2 = OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
         final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
                 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref)
                 .addNetworkPreference(testPackageName2, testOemPref2)
@@ -9636,7 +9677,7 @@
 
     @Test
     public void testOemNetworkRequestFactoryAddsPackagesToCorrectPreference()
-            throws PackageManager.NameNotFoundException {
+            throws Exception {
         // Expectations
         final int expectedNumOfNris = 1;
         final int expectedNumOfAppUids = 2;
@@ -9648,7 +9689,7 @@
         mockGetApplicationInfo(testPackageName2, testPackageNameUid2);
 
         // Build OemNetworkPreferences object
-        final int testOemPref = OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
+        final int testOemPref = OEM_NETWORK_PREFERENCE_OEM_PAID;
         final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
                 .addNetworkPreference(TEST_PACKAGE_NAME, testOemPref)
                 .addNetworkPreference(testPackageName2, testOemPref)
@@ -9666,8 +9707,6 @@
     @Test
     public void testSetOemNetworkPreferenceNullListenerAndPrefParamThrowsNpe() {
         mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true);
-        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
-                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
 
         // Act on ConnectivityService.setOemNetworkPreference()
         assertThrows(NullPointerException.class,
@@ -9678,15 +9717,916 @@
 
     @Test
     public void testSetOemNetworkPreferenceFailsForNonAutomotive()
-            throws PackageManager.NameNotFoundException, RemoteException {
+            throws Exception {
         mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false);
         @OemNetworkPreferences.OemNetworkPreference final int networkPref =
-                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+                OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
 
         // Act on ConnectivityService.setOemNetworkPreference()
         assertThrows(UnsupportedOperationException.class,
                 () -> mService.setOemNetworkPreference(
                         createDefaultOemNetworkPreferences(networkPref),
-                        mOnSetOemNetworkPreferenceListener));
+                        new TestOemListenerCallback()));
+    }
+
+    private void setOemNetworkPreferenceAgentConnected(final int transportType,
+            final boolean connectAgent) throws Exception {
+        switch(transportType) {
+            // Corresponds to a metered cellular network. Will be used for the default network.
+            case TRANSPORT_CELLULAR:
+                if (!connectAgent) {
+                    mCellNetworkAgent.disconnect();
+                    break;
+                }
+                mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR);
+                mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
+                mCellNetworkAgent.connect(true);
+                break;
+            // Corresponds to a restricted ethernet network with OEM_PAID/OEM_PRIVATE.
+            case TRANSPORT_ETHERNET:
+                if (!connectAgent) {
+                    stopOemManagedNetwork();
+                    break;
+                }
+                startOemManagedNetwork(true);
+                break;
+            // Corresponds to unmetered Wi-Fi.
+            case TRANSPORT_WIFI:
+                if (!connectAgent) {
+                    mWiFiNetworkAgent.disconnect();
+                    break;
+                }
+                mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI);
+                mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+                mWiFiNetworkAgent.connect(true);
+                break;
+            default:
+                throw new AssertionError("Unsupported transport type passed in.");
+
+        }
+        waitForIdle();
+    }
+
+    private void startOemManagedNetwork(final boolean isOemPaid) throws Exception {
+        mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET);
+        mEthernetNetworkAgent.addCapability(
+                isOemPaid ? NET_CAPABILITY_OEM_PAID : NET_CAPABILITY_OEM_PRIVATE);
+        mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+        mEthernetNetworkAgent.connect(true);
+    }
+
+    private void stopOemManagedNetwork() {
+        mEthernetNetworkAgent.disconnect();
+        waitForIdle();
+    }
+
+    private void verifyMultipleDefaultNetworksTracksCorrectly(
+            final int expectedOemRequestsSize,
+            @NonNull final Network expectedDefaultNetwork,
+            @NonNull final Network expectedPerAppNetwork) {
+        // The current test setup assumes two tracked default network requests; one for the default
+        // network and the other for the OEM network preference being tested. This will be validated
+        // each time to confirm it doesn't change under test.
+        final int expectedDefaultNetworkRequestsSize = 2;
+        assertEquals(expectedDefaultNetworkRequestsSize, mService.mDefaultNetworkRequests.size());
+        for (final ConnectivityService.NetworkRequestInfo defaultRequest
+                : mService.mDefaultNetworkRequests) {
+            final Network defaultNetwork = defaultRequest.getSatisfier() == null
+                    ? null : defaultRequest.getSatisfier().network();
+            // If this is the default request.
+            if (defaultRequest == mService.mDefaultRequest) {
+                assertEquals(
+                        expectedDefaultNetwork,
+                        defaultNetwork);
+                // Make sure this value doesn't change.
+                assertEquals(1, defaultRequest.mRequests.size());
+                continue;
+            }
+            assertEquals(expectedPerAppNetwork, defaultNetwork);
+            assertEquals(expectedOemRequestsSize, defaultRequest.mRequests.size());
+        }
+        verifyMultipleDefaultCallbacks(expectedDefaultNetwork, expectedPerAppNetwork);
+    }
+
+    /**
+     * Verify default callbacks for 'available' fire as expected. This will only run if
+     * registerDefaultNetworkCallbacks() was executed prior and will only be different if the
+     * setOemNetworkPreference() per-app API was used for the current process.
+     * @param expectedSystemDefault the expected network for the system default.
+     * @param expectedPerAppDefault the expected network for the current process's default.
+     */
+    private void verifyMultipleDefaultCallbacks(
+            @NonNull final Network expectedSystemDefault,
+            @NonNull final Network expectedPerAppDefault) {
+        if (null != mSystemDefaultNetworkCallback && null != expectedSystemDefault
+                && mService.mNoServiceNetwork.network() != expectedSystemDefault) {
+            // getLastAvailableNetwork() is used as this method can be called successively with
+            // the same network to validate therefore expectAvailableThenValidatedCallbacks
+            // can't be used.
+            assertEquals(mSystemDefaultNetworkCallback.getLastAvailableNetwork(),
+                    expectedSystemDefault);
+        }
+        if (null != mDefaultNetworkCallback && null != expectedPerAppDefault
+                && mService.mNoServiceNetwork.network() != expectedPerAppDefault) {
+            assertEquals(mDefaultNetworkCallback.getLastAvailableNetwork(),
+                    expectedPerAppDefault);
+        }
+    }
+
+    private void registerDefaultNetworkCallbacks() {
+        // Using Manifest.permission.NETWORK_SETTINGS for registerSystemDefaultNetworkCallback()
+        mServiceContext.setPermission(
+                Manifest.permission.NETWORK_SETTINGS, PERMISSION_GRANTED);
+        mSystemDefaultNetworkCallback = new TestNetworkCallback();
+        mDefaultNetworkCallback = new TestNetworkCallback();
+        mCm.registerSystemDefaultNetworkCallback(mSystemDefaultNetworkCallback,
+                new Handler(ConnectivityThread.getInstanceLooper()));
+        mCm.registerDefaultNetworkCallback(mDefaultNetworkCallback);
+        mServiceContext.setPermission(
+                Manifest.permission.NETWORK_SETTINGS, PERMISSION_DENIED);
+    }
+
+    private void unregisterDefaultNetworkCallbacks() {
+        if (null != mDefaultNetworkCallback) {
+            mCm.unregisterNetworkCallback(mDefaultNetworkCallback);
+        }
+        if (null != mSystemDefaultNetworkCallback) {
+            mCm.unregisterNetworkCallback(mSystemDefaultNetworkCallback);
+        }
+    }
+
+    private void setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(
+            @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup)
+            throws Exception {
+        final int testPackageNameUid = 123;
+        final String testPackageName = "per.app.defaults.package";
+        setupMultipleDefaultNetworksForOemNetworkPreferenceTest(
+                networkPrefToSetup, testPackageNameUid, testPackageName);
+    }
+
+    private void setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(
+            @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup)
+            throws Exception {
+        final int testPackageNameUid = Process.myUid();
+        final String testPackageName = "per.app.defaults.package";
+        setupMultipleDefaultNetworksForOemNetworkPreferenceTest(
+                networkPrefToSetup, testPackageNameUid, testPackageName);
+    }
+
+    private void setupMultipleDefaultNetworksForOemNetworkPreferenceTest(
+            @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup,
+            final int testPackageUid, @NonNull final String testPackageName) throws Exception {
+        // Only the default request should be included at start.
+        assertEquals(1, mService.mDefaultNetworkRequests.size());
+
+        final UidRangeParcel[] uidRanges =
+                toUidRangeStableParcels(uidRangesForUid(testPackageUid));
+        setupSetOemNetworkPreferenceForPreferenceTest(
+                networkPrefToSetup, uidRanges, testPackageName);
+    }
+
+    private void setupSetOemNetworkPreferenceForPreferenceTest(
+            @OemNetworkPreferences.OemNetworkPreference final int networkPrefToSetup,
+            @NonNull final UidRangeParcel[] uidRanges,
+            @NonNull final String testPackageName)
+            throws Exception {
+        mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true);
+
+        // These tests work off a single UID therefore using 'start' is valid.
+        mockGetApplicationInfo(testPackageName, uidRanges[0].start);
+
+        // Build OemNetworkPreferences object
+        final OemNetworkPreferences pref = new OemNetworkPreferences.Builder()
+                .addNetworkPreference(testPackageName, networkPrefToSetup)
+                .build();
+
+        // Act on ConnectivityService.setOemNetworkPreference()
+        final TestOemListenerCallback mOnSetOemNetworkPreferenceTestListener =
+                new TestOemListenerCallback();
+        mService.setOemNetworkPreference(pref, mOnSetOemNetworkPreferenceTestListener);
+
+        // Verify call returned successfully
+        mOnSetOemNetworkPreferenceTestListener.expectOnComplete();
+    }
+
+    private static class TestOemListenerCallback implements IOnSetOemNetworkPreferenceListener {
+        final CompletableFuture<Object> mDone = new CompletableFuture<>();
+
+        @Override
+        public void onComplete() {
+            mDone.complete(new Object());
+        }
+
+        void expectOnComplete() throws Exception {
+            try {
+                mDone.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            } catch (TimeoutException e) {
+                fail("Expected onComplete() not received after " + TIMEOUT_MS + " ms");
+            }
+        }
+
+        @Override
+        public IBinder asBinder() {
+            return null;
+        }
+    }
+
+    @Test
+    public void testMultiDefaultGetActiveNetworkIsCorrect() throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+        final int expectedOemPrefRequestSize = 1;
+        registerDefaultNetworkCallbacks();
+
+        // Setup the test process to use networkPref for their default network.
+        setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        // The active network for the default should be null at this point as this is a retricted
+        // network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mEthernetNetworkAgent.getNetwork());
+
+        // Verify that the active network is correct
+        verifyActiveNetwork(TRANSPORT_ETHERNET);
+        // default NCs will be unregistered in tearDown
+    }
+
+    @Test
+    public void testMultiDefaultIsActiveNetworkMeteredIsCorrect() throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+        final int expectedOemPrefRequestSize = 1;
+        registerDefaultNetworkCallbacks();
+
+        // Setup the test process to use networkPref for their default network.
+        setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+
+        // Returns true by default when no network is available.
+        assertTrue(mCm.isActiveNetworkMetered());
+
+        // Connect to an unmetered restricted network that will only be available to the OEM pref.
+        mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET);
+        mEthernetNetworkAgent.addCapability(NET_CAPABILITY_OEM_PAID);
+        mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        mEthernetNetworkAgent.removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+        mEthernetNetworkAgent.connect(true);
+        waitForIdle();
+
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mEthernetNetworkAgent.getNetwork());
+
+        assertFalse(mCm.isActiveNetworkMetered());
+        // default NCs will be unregistered in tearDown
+    }
+
+    @Test
+    public void testPerAppDefaultRegisterDefaultNetworkCallback() throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+        final int expectedOemPrefRequestSize = 1;
+        final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
+
+        // Register the default network callback before the pref is already set. This means that
+        // the policy will be applied to the callback on setOemNetworkPreference().
+        mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
+        defaultNetworkCallback.assertNoCallback();
+
+        // Setup the test process to use networkPref for their default network.
+        setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        // The active nai for the default is null at this point as this is a restricted network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mEthernetNetworkAgent.getNetwork());
+
+        // At this point with a restricted network used, the available callback should trigger
+        defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent);
+        assertEquals(defaultNetworkCallback.getLastAvailableNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Now bring down the default network which should trigger a LOST callback.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+
+        // At this point, with no network is available, the lost callback should trigger
+        defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+
+        // Confirm we can unregister without issues.
+        mCm.unregisterNetworkCallback(defaultNetworkCallback);
+    }
+
+    @Test
+    public void testPerAppDefaultRegisterDefaultNetworkCallbackAfterPrefSet() throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+        final int expectedOemPrefRequestSize = 1;
+        final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
+
+        // Setup the test process to use networkPref for their default network.
+        setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+
+        // Register the default network callback after the pref is already set. This means that
+        // the policy will be applied to the callback on requestNetwork().
+        mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
+        defaultNetworkCallback.assertNoCallback();
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        // The active nai for the default is null at this point as this is a restricted network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mEthernetNetworkAgent.getNetwork());
+
+        // At this point with a restricted network used, the available callback should trigger
+        defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mEthernetNetworkAgent);
+        assertEquals(defaultNetworkCallback.getLastAvailableNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Now bring down the default network which should trigger a LOST callback.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+
+        // At this point, with no network is available, the lost callback should trigger
+        defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mEthernetNetworkAgent);
+
+        // Confirm we can unregister without issues.
+        mCm.unregisterNetworkCallback(defaultNetworkCallback);
+    }
+
+    @Test
+    public void testPerAppDefaultRegisterDefaultNetworkCallbackDoesNotFire() throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+        final int expectedOemPrefRequestSize = 1;
+        final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
+        final int userId = UserHandle.getUserId(Process.myUid());
+
+        mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
+        defaultNetworkCallback.assertNoCallback();
+
+        // Setup a process different than the test process to use the default network. This means
+        // that the defaultNetworkCallback won't be tracked by the per-app policy.
+        setupMultipleDefaultNetworksForOemNetworkPreferenceNotCurrentUidTest(networkPref);
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        // The active nai for the default is null at this point as this is a restricted network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mEthernetNetworkAgent.getNetwork());
+
+        // As this callback does not have access to the OEM_PAID network, it will not fire.
+        defaultNetworkCallback.assertNoCallback();
+        assertDefaultNetworkCapabilities(userId /* no networks */);
+
+        // Bring up unrestricted cellular. This should now satisfy the default network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // At this point with an unrestricted network used, the available callback should trigger
+        defaultNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+        assertEquals(defaultNetworkCallback.getLastAvailableNetwork(),
+                mCellNetworkAgent.getNetwork());
+        assertDefaultNetworkCapabilities(userId, mCellNetworkAgent);
+
+        // Now bring down the per-app network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+
+        // Since the callback didn't use the per-app network, no callback should fire.
+        defaultNetworkCallback.assertNoCallback();
+
+        // Now bring down the default network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+
+        // As this callback was tracking the default, this should now trigger.
+        defaultNetworkCallback.expectCallback(CallbackEntry.LOST, mCellNetworkAgent);
+
+        // Confirm we can unregister without issues.
+        mCm.unregisterNetworkCallback(defaultNetworkCallback);
+    }
+
+    private void verifySetOemNetworkPreferenceForPreference(
+            @NonNull final UidRangeParcel[] uidRanges,
+            final int addUidRangesNetId,
+            final int addUidRangesTimes,
+            final int removeUidRangesNetId,
+            final int removeUidRangesTimes,
+            final boolean shouldDestroyNetwork) throws RemoteException {
+        final boolean useAnyIdForAdd = OEM_PREF_ANY_NET_ID == addUidRangesNetId;
+        final boolean useAnyIdForRemove = OEM_PREF_ANY_NET_ID == removeUidRangesNetId;
+
+        // Validate netd.
+        verify(mMockNetd, times(addUidRangesTimes))
+                .networkAddUidRanges(
+                        (useAnyIdForAdd ? anyInt() : eq(addUidRangesNetId)), eq(uidRanges));
+        verify(mMockNetd, times(removeUidRangesTimes))
+                .networkRemoveUidRanges(
+                        (useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId)), eq(uidRanges));
+        if (shouldDestroyNetwork) {
+            verify(mMockNetd, times(1))
+                    .networkDestroy((useAnyIdForRemove ? anyInt() : eq(removeUidRangesNetId)));
+        }
+        reset(mMockNetd);
+    }
+
+    /**
+     * Test the tracked default requests clear previous OEM requests on setOemNetworkPreference().
+     */
+    @Test
+    public void testSetOemNetworkPreferenceClearPreviousOemValues() throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PAID;
+        final int testPackageUid = 123;
+        final String testPackageName = "com.google.apps.contacts";
+        final UidRangeParcel[] uidRanges =
+                toUidRangeStableParcels(uidRangesForUid(testPackageUid));
+
+        // Validate the starting requests only includes the fallback request.
+        assertEquals(1, mService.mDefaultNetworkRequests.size());
+
+        // Add an OEM default network request to track.
+        setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName);
+
+        // Two requests should exist, one for the fallback and one for the pref.
+        assertEquals(2, mService.mDefaultNetworkRequests.size());
+
+        networkPref = OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+        setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, testPackageName);
+
+        // Two requests should still exist validating the previous per-app request was replaced.
+        assertEquals(2, mService.mDefaultNetworkRequests.size());
+    }
+
+    /**
+     * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order:
+     * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback
+     */
+    @Test
+    public void testMultilayerForPreferenceOemPaidEvaluatesCorrectly()
+            throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PAID;
+
+        // Arrange PackageManager mocks
+        final int testPackageNameUid = 123;
+        final UidRangeParcel[] uidRanges =
+                toUidRangeStableParcels(uidRangesForUid(testPackageNameUid));
+        setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+
+        // Verify the starting state. No networks should be connected.
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Test lowest to highest priority requests.
+        // Bring up metered cellular. This will satisfy the fallback network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+                mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mWiFiNetworkAgent.getNetwork().netId, 1 /* times */,
+                mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Disconnecting OEM_PAID should have no effect as it is lower in priority then unmetered.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+        // netd should not be called as default networks haven't changed.
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Disconnecting unmetered should put PANS on lowest priority fallback request.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mCellNetworkAgent.getNetwork().netId, 1 /* times */,
+                mWiFiNetworkAgent.getNetwork().netId, 0 /* times */,
+                true /* shouldDestroyNetwork */);
+
+        // Disconnecting the fallback network should result in no connectivity.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                mCellNetworkAgent.getNetwork().netId, 0 /* times */,
+                true /* shouldDestroyNetwork */);
+    }
+
+    /**
+     * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order:
+     * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID
+     */
+    @Test
+    public void testMultilayerForPreferenceOemPaidNoFallbackEvaluatesCorrectly()
+            throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+
+        // Arrange PackageManager mocks
+        final int testPackageNameUid = 123;
+        final UidRangeParcel[] uidRanges =
+                toUidRangeStableParcels(uidRangesForUid(testPackageNameUid));
+        setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+
+        // Verify the starting state. This preference doesn't support using the fallback network
+        // therefore should be on the disconnected network as it has no networks to connect to.
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Test lowest to highest priority requests.
+        // Bring up metered cellular. This will satisfy the fallback network.
+        // This preference should not use this network as it doesn't support fallback usage.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+                mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mWiFiNetworkAgent.getNetwork().netId, 1 /* times */,
+                mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Disconnecting unmetered should put PANS on OEM_PAID.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+                mWiFiNetworkAgent.getNetwork().netId, 0 /* times */,
+                true /* shouldDestroyNetwork */);
+
+        // Disconnecting OEM_PAID should result in no connectivity.
+        // OEM_PAID_NO_FALLBACK not supporting a fallback now uses the disconnected network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+                mEthernetNetworkAgent.getNetwork().netId, 0 /* times */,
+                true /* shouldDestroyNetwork */);
+    }
+
+    /**
+     * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order:
+     * NET_CAPABILITY_OEM_PAID
+     * This preference should only apply to OEM_PAID networks.
+     */
+    @Test
+    public void testMultilayerForPreferenceOemPaidOnlyEvaluatesCorrectly()
+            throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+
+        // Arrange PackageManager mocks
+        final int testPackageNameUid = 123;
+        final UidRangeParcel[] uidRanges =
+                toUidRangeStableParcels(uidRangesForUid(testPackageNameUid));
+        setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+
+        // Verify the starting state. This preference doesn't support using the fallback network
+        // therefore should be on the disconnected network as it has no networks to connect to.
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up metered cellular. This should not apply to this preference.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up unmetered Wi-Fi. This should not apply to this preference.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+                mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Disconnecting OEM_PAID should result in no connectivity.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+                mEthernetNetworkAgent.getNetwork().netId, 0 /* times */,
+                true /* shouldDestroyNetwork */);
+    }
+
+    /**
+     * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order:
+     * NET_CAPABILITY_OEM_PRIVATE
+     * This preference should only apply to OEM_PRIVATE networks.
+     */
+    @Test
+    public void testMultilayerForPreferenceOemPrivateOnlyEvaluatesCorrectly()
+            throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+
+        // Arrange PackageManager mocks
+        final int testPackageNameUid = 123;
+        final UidRangeParcel[] uidRanges =
+                toUidRangeStableParcels(uidRangesForUid(testPackageNameUid));
+        setupSetOemNetworkPreferenceForPreferenceTest(networkPref, uidRanges, TEST_PACKAGE_NAME);
+
+        // Verify the starting state. This preference doesn't support using the fallback network
+        // therefore should be on the disconnected network as it has no networks to connect to.
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up metered cellular. This should not apply to this preference.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up unmetered Wi-Fi. This should not apply to this preference.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                OEM_PREF_ANY_NET_ID, 0 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE.
+        startOemManagedNetwork(false);
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mEthernetNetworkAgent.getNetwork().netId, 1 /* times */,
+                mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+                false /* shouldDestroyNetwork */);
+
+        // Disconnecting OEM_PRIVATE should result in no connectivity.
+        stopOemManagedNetwork();
+        verifySetOemNetworkPreferenceForPreference(uidRanges,
+                mService.mNoServiceNetwork.network.getNetId(), 1 /* times */,
+                mEthernetNetworkAgent.getNetwork().netId, 0 /* times */,
+                true /* shouldDestroyNetwork */);
+    }
+
+    /**
+     * Test network priority for preference OEM_NETWORK_PREFERENCE_OEM_PAID in the following order:
+     * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID -> fallback
+     */
+    @Test
+    public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidCorrectly()
+            throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID;
+        setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+        final int expectedDefaultRequestSize = 2;
+        final int expectedOemPrefRequestSize = 3;
+        registerDefaultNetworkCallbacks();
+
+        // The fallback as well as the OEM preference should now be tracked.
+        assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size());
+
+        // Test lowest to highest priority requests.
+        // Bring up metered cellular. This will satisfy the fallback network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mCellNetworkAgent.getNetwork());
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mWiFiNetworkAgent.getNetwork(),
+                mWiFiNetworkAgent.getNetwork());
+
+        // Disconnecting unmetered Wi-Fi will put the pref on OEM_PAID and fallback on cellular.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mEthernetNetworkAgent.getNetwork());
+
+        // Disconnecting OEM_PAID will put both on null as it is the last network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                null);
+
+        // default NCs will be unregistered in tearDown
+    }
+
+    /**
+     * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK in the following order:
+     * NET_CAPABILITY_NOT_METERED -> NET_CAPABILITY_OEM_PAID
+     */
+    @Test
+    public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidNoFallbackCorrectly()
+            throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_NO_FALLBACK;
+        setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+        final int expectedDefaultRequestSize = 2;
+        final int expectedOemPrefRequestSize = 2;
+        registerDefaultNetworkCallbacks();
+
+        // The fallback as well as the OEM preference should now be tracked.
+        assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size());
+
+        // Test lowest to highest priority requests.
+        // Bring up metered cellular. This will satisfy the fallback network but not the pref.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mService.mNoServiceNetwork.network());
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Bring up unmetered Wi-Fi. This will satisfy NET_CAPABILITY_NOT_METERED.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mWiFiNetworkAgent.getNetwork(),
+                mWiFiNetworkAgent.getNetwork());
+
+        // Disconnecting unmetered Wi-Fi will put the OEM pref on OEM_PAID and fallback on cellular.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Disconnecting cellular should keep OEM network on OEM_PAID and fallback will be null.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mEthernetNetworkAgent.getNetwork());
+
+        // Disconnecting OEM_PAID puts the fallback on null and the pref on the disconnected net.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mService.mNoServiceNetwork.network());
+
+        // default NCs will be unregistered in tearDown
+    }
+
+    /**
+     * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY in the following order:
+     * NET_CAPABILITY_OEM_PAID
+     * This preference should only apply to OEM_PAID networks.
+     */
+    @Test
+    public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPaidOnlyCorrectly()
+            throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_ONLY;
+        setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+        final int expectedDefaultRequestSize = 2;
+        final int expectedOemPrefRequestSize = 1;
+        registerDefaultNetworkCallbacks();
+
+        // The fallback as well as the OEM preference should now be tracked.
+        assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size());
+
+        // Test lowest to highest priority requests.
+        // Bring up metered cellular. This will satisfy the fallback network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mService.mNoServiceNetwork.network());
+
+        // Bring up ethernet with OEM_PAID. This will satisfy NET_CAPABILITY_OEM_PAID.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mWiFiNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Disconnecting OEM_PAID will keep the fallback on cellular and nothing for OEM_PAID.
+        // OEM_PAID_ONLY not supporting a fallback now uses the disconnected network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_ETHERNET, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mService.mNoServiceNetwork.network());
+
+        // Disconnecting cellular will put the fallback on null and the pref on disconnected.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mService.mNoServiceNetwork.network());
+
+        // default NCs will be unregistered in tearDown
+    }
+
+    /**
+     * Test network priority for OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY in the following order:
+     * NET_CAPABILITY_OEM_PRIVATE
+     * This preference should only apply to OEM_PRIVATE networks.
+     */
+    @Test
+    public void testMultipleDefaultNetworksTracksOemNetworkPreferenceOemPrivateOnlyCorrectly()
+            throws Exception {
+        @OemNetworkPreferences.OemNetworkPreference final int networkPref =
+                OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
+        setupMultipleDefaultNetworksForOemNetworkPreferenceCurrentUidTest(networkPref);
+        final int expectedDefaultRequestSize = 2;
+        final int expectedOemPrefRequestSize = 1;
+        registerDefaultNetworkCallbacks();
+
+        // The fallback as well as the OEM preference should now be tracked.
+        assertEquals(expectedDefaultRequestSize, mService.mDefaultNetworkRequests.size());
+
+        // Test lowest to highest priority requests.
+        // Bring up metered cellular. This will satisfy the fallback network.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mService.mNoServiceNetwork.network());
+
+        // Bring up ethernet with OEM_PRIVATE. This will satisfy NET_CAPABILITY_OEM_PRIVATE.
+        startOemManagedNetwork(false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Bring up unmetered Wi-Fi. The OEM network shouldn't change, the fallback will take Wi-Fi.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, true);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mWiFiNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Disconnecting unmetered Wi-Fi shouldn't change the OEM network with fallback on cellular.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_WIFI, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mEthernetNetworkAgent.getNetwork());
+
+        // Disconnecting OEM_PRIVATE will keep the fallback on cellular.
+        // OEM_PRIVATE_ONLY not supporting a fallback now uses to the disconnected network.
+        stopOemManagedNetwork();
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                mCellNetworkAgent.getNetwork(),
+                mService.mNoServiceNetwork.network());
+
+        // Disconnecting cellular will put the fallback on null and pref on disconnected.
+        setOemNetworkPreferenceAgentConnected(TRANSPORT_CELLULAR, false);
+        verifyMultipleDefaultNetworksTracksCorrectly(expectedOemPrefRequestSize,
+                null,
+                mService.mNoServiceNetwork.network());
+
+        // default NCs will be unregistered in tearDown
     }
 }
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index c86224a..32c95f1 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -16,12 +16,16 @@
 
 package com.android.server;
 
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.net.INetd.IF_STATE_DOWN;
+import static android.net.INetd.IF_STATE_UP;
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.AF_INET6;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.argThat;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
@@ -36,6 +40,7 @@
 import android.net.ConnectivityManager;
 import android.net.INetd;
 import android.net.InetAddresses;
+import android.net.InterfaceConfigurationParcel;
 import android.net.IpSecAlgorithm;
 import android.net.IpSecConfig;
 import android.net.IpSecManager;
@@ -48,7 +53,6 @@
 import android.net.LinkProperties;
 import android.net.Network;
 import android.os.Binder;
-import android.os.INetworkManagementService;
 import android.os.ParcelFileDescriptor;
 import android.system.Os;
 import android.test.mock.MockContext;
@@ -148,10 +152,17 @@
             }
             throw new SecurityException("Unavailable permission requested");
         }
+
+        @Override
+        public int checkCallingOrSelfPermission(String permission) {
+            if (android.Manifest.permission.NETWORK_STACK.equals(permission)) {
+                return PERMISSION_GRANTED;
+            }
+            throw new UnsupportedOperationException();
+        }
     };
 
     INetd mMockNetd;
-    INetworkManagementService mNetworkManager;
     PackageManager mMockPkgMgr;
     IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
     IpSecService mIpSecService;
@@ -181,10 +192,9 @@
     @Before
     public void setUp() throws Exception {
         mMockNetd = mock(INetd.class);
-        mNetworkManager = mock(INetworkManagementService.class);
         mMockPkgMgr = mock(PackageManager.class);
         mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
-        mIpSecService = new IpSecService(mMockContext, mNetworkManager, mMockIpSecSrvConfig);
+        mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
 
         // Injecting mock netd
         when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -644,7 +654,10 @@
     }
 
     private IpSecTunnelInterfaceResponse createAndValidateTunnel(
-            String localAddr, String remoteAddr, String pkgName) {
+            String localAddr, String remoteAddr, String pkgName) throws Exception {
+        final InterfaceConfigurationParcel config = new InterfaceConfigurationParcel();
+        config.flags = new String[] {IF_STATE_DOWN};
+        when(mMockNetd.interfaceGetCfg(anyString())).thenReturn(config);
         IpSecTunnelInterfaceResponse createTunnelResp =
                 mIpSecService.createTunnelInterface(
                         mSourceAddr, mDestinationAddr, fakeNetwork, new Binder(), pkgName);
@@ -674,7 +687,8 @@
                         anyInt(),
                         anyInt(),
                         anyInt());
-        verify(mNetworkManager).setInterfaceUp(createTunnelResp.interfaceName);
+        verify(mMockNetd).interfaceSetCfg(argThat(
+                config -> Arrays.asList(config.flags).contains(IF_STATE_UP)));
     }
 
     @Test
diff --git a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
index 788e4ef..22a2c94 100644
--- a/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceRefcountedResourceTest.java
@@ -31,7 +31,6 @@
 import android.content.Context;
 import android.os.Binder;
 import android.os.IBinder;
-import android.os.INetworkManagementService;
 import android.os.RemoteException;
 
 import androidx.test.filters.SmallTest;
@@ -62,8 +61,7 @@
     public void setUp() throws Exception {
         mMockContext = mock(Context.class);
         mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
-        mIpSecService = new IpSecService(
-                mMockContext, mock(INetworkManagementService.class), mMockIpSecSrvConfig);
+        mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
     }
 
     private void assertResourceState(
diff --git a/tests/net/java/com/android/server/IpSecServiceTest.java b/tests/net/java/com/android/server/IpSecServiceTest.java
index 536e983..f97eabf 100644
--- a/tests/net/java/com/android/server/IpSecServiceTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceTest.java
@@ -42,7 +42,6 @@
 import android.net.IpSecSpiResponse;
 import android.net.IpSecUdpEncapResponse;
 import android.os.Binder;
-import android.os.INetworkManagementService;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.system.ErrnoException;
@@ -116,7 +115,6 @@
     }
 
     Context mMockContext;
-    INetworkManagementService mMockNetworkManager;
     INetd mMockNetd;
     IpSecService.IpSecServiceConfiguration mMockIpSecSrvConfig;
     IpSecService mIpSecService;
@@ -124,10 +122,9 @@
     @Before
     public void setUp() throws Exception {
         mMockContext = mock(Context.class);
-        mMockNetworkManager = mock(INetworkManagementService.class);
         mMockNetd = mock(INetd.class);
         mMockIpSecSrvConfig = mock(IpSecService.IpSecServiceConfiguration.class);
-        mIpSecService = new IpSecService(mMockContext, mMockNetworkManager, mMockIpSecSrvConfig);
+        mIpSecService = new IpSecService(mMockContext, mMockIpSecSrvConfig);
 
         // Injecting mock netd
         when(mMockIpSecSrvConfig.getNetdInstance()).thenReturn(mMockNetd);
@@ -135,7 +132,7 @@
 
     @Test
     public void testIpSecServiceCreate() throws InterruptedException {
-        IpSecService ipSecSrv = IpSecService.create(mMockContext, mMockNetworkManager);
+        IpSecService ipSecSrv = IpSecService.create(mMockContext);
         assertNotNull(ipSecSrv);
     }
 
@@ -608,7 +605,7 @@
     public void testOpenUdpEncapSocketTagsSocket() throws Exception {
         IpSecService.UidFdTagger mockTagger = mock(IpSecService.UidFdTagger.class);
         IpSecService testIpSecService = new IpSecService(
-                mMockContext, mMockNetworkManager, mMockIpSecSrvConfig, mockTagger);
+                mMockContext, mMockIpSecSrvConfig, mockTagger);
 
         IpSecUdpEncapResponse udpEncapResp =
                 testIpSecService.openUdpEncapsulationSocket(0, new Binder());
diff --git a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
index 697dbc4..ff8c632 100644
--- a/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
+++ b/tests/net/java/com/android/server/connectivity/NetworkNotificationManagerTest.java
@@ -49,6 +49,7 @@
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.AdditionalAnswers;
@@ -183,6 +184,9 @@
     }
 
     @Test
+    @Ignore
+    // Ignored because the code under test calls Log.wtf, which crashes the tests on eng builds.
+    // TODO: re-enable after fixing this (e.g., turn Log.wtf into exceptions that this test catches)
     public void testNoInternetNotificationsNotShownForCellular() {
         mManager.showNotification(100, NO_INTERNET, mCellNai, mWifiNai, null, false);
         mManager.showNotification(101, LOST_INTERNET, mCellNai, mWifiNai, null, false);
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index 8f5ae97..e4e24b4 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -61,6 +61,7 @@
 import android.net.INetd;
 import android.net.UidRange;
 import android.os.Build;
+import android.os.SystemConfigManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.SparseIntArray;
@@ -114,6 +115,7 @@
     @Mock private PackageManagerInternal mMockPmi;
     @Mock private UserManager mUserManager;
     @Mock private PermissionMonitor.Dependencies mDeps;
+    @Mock private SystemConfigManager mSystemConfigManager;
 
     private PermissionMonitor mPermissionMonitor;
 
@@ -124,6 +126,11 @@
         when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
         when(mUserManager.getUserHandles(eq(true))).thenReturn(
                 Arrays.asList(new UserHandle[] { MOCK_USER1, MOCK_USER2 }));
+        when(mContext.getSystemServiceName(SystemConfigManager.class))
+                .thenReturn(Context.SYSTEM_CONFIG_SERVICE);
+        when(mContext.getSystemService(Context.SYSTEM_CONFIG_SERVICE))
+                .thenReturn(mSystemConfigManager);
+        when(mSystemConfigManager.getSystemPermissionUids(anyString())).thenReturn(new int[0]);
 
         mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService, mDeps));
 
@@ -747,4 +754,20 @@
                 GET_PERMISSIONS | MATCH_ANY_USER);
         assertTrue(monitor.hasPermission(systemInfo, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
     }
+
+    @Test
+    public void testUpdateUidPermissionsFromSystemConfig() throws Exception {
+        final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+        when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(new ArrayList<>());
+        when(mSystemConfigManager.getSystemPermissionUids(eq(INTERNET)))
+                .thenReturn(new int[]{ MOCK_UID1, MOCK_UID2 });
+        when(mSystemConfigManager.getSystemPermissionUids(eq(UPDATE_DEVICE_STATS)))
+                .thenReturn(new int[]{ MOCK_UID2 });
+
+        mPermissionMonitor.startMonitoring();
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{ MOCK_UID1 });
+        mNetdServiceMonitor.expectPermission(
+                INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS,
+                new int[]{ MOCK_UID2 });
+    }
 }
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java
index cffd2d1d..7489a0f 100644
--- a/tests/net/java/com/android/server/connectivity/VpnTest.java
+++ b/tests/net/java/com/android/server/connectivity/VpnTest.java
@@ -21,6 +21,8 @@
 import static android.content.pm.UserInfo.FLAG_PRIMARY;
 import static android.content.pm.UserInfo.FLAG_RESTRICTED;
 import static android.net.ConnectivityManager.NetworkCallback;
+import static android.net.INetd.IF_STATE_DOWN;
+import static android.net.INetd.IF_STATE_UP;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -62,6 +64,7 @@
 import android.net.INetd;
 import android.net.Ikev2VpnProfile;
 import android.net.InetAddresses;
+import android.net.InterfaceConfigurationParcel;
 import android.net.IpPrefix;
 import android.net.IpSecManager;
 import android.net.IpSecTunnelInterfaceResponse;
@@ -179,7 +182,8 @@
             mPackages.put(PKGS[i], PKG_UIDS[i]);
         }
     }
-    private static final UidRange PRI_USER_RANGE = UidRange.createForUser(primaryUser.id);
+    private static final UidRange PRI_USER_RANGE =
+            UidRange.createForUser(UserHandle.of(primaryUser.id));
 
     @Mock(answer = Answers.RETURNS_DEEP_STUBS) private Context mContext;
     @Mock private UserManager mUserManager;
@@ -269,7 +273,7 @@
                 vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, null, null);
 
         assertEquals(new ArraySet<>(Arrays.asList(new UidRange[] {
-                PRI_USER_RANGE, UidRange.createForUser(restrictedProfileA.id)
+                PRI_USER_RANGE, UidRange.createForUser(UserHandle.of(restrictedProfileA.id))
         })), ranges);
     }
 
@@ -872,17 +876,28 @@
                         eq(AppOpsManager.MODE_IGNORED));
     }
 
-    private NetworkCallback triggerOnAvailableAndGetCallback() {
+    private NetworkCallback triggerOnAvailableAndGetCallback() throws Exception {
         final ArgumentCaptor<NetworkCallback> networkCallbackCaptor =
                 ArgumentCaptor.forClass(NetworkCallback.class);
         verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS))
                 .requestNetwork(any(), networkCallbackCaptor.capture());
 
+        // onAvailable() will trigger onDefaultNetworkChanged(), so NetdUtils#setInterfaceUp will be
+        // invoked. Set the return value of INetd#interfaceGetCfg to prevent NullPointerException.
+        final InterfaceConfigurationParcel config = new InterfaceConfigurationParcel();
+        config.flags = new String[] {IF_STATE_DOWN};
+        when(mNetd.interfaceGetCfg(anyString())).thenReturn(config);
         final NetworkCallback cb = networkCallbackCaptor.getValue();
         cb.onAvailable(TEST_NETWORK);
         return cb;
     }
 
+    private void verifyInterfaceSetCfgWithFlags(String flag) throws Exception {
+        // Add a timeout for waiting for interfaceSetCfg to be called.
+        verify(mNetd, timeout(TEST_TIMEOUT_MS)).interfaceSetCfg(argThat(
+                config -> Arrays.asList(config.flags).contains(flag)));
+    }
+
     @Test
     public void testStartPlatformVpnAuthenticationFailed() throws Exception {
         final ArgumentCaptor<IkeSessionCallback> captor =
@@ -894,6 +909,8 @@
         final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), (mVpnProfile));
         final NetworkCallback cb = triggerOnAvailableAndGetCallback();
 
+        verifyInterfaceSetCfgWithFlags(IF_STATE_UP);
+
         // Wait for createIkeSession() to be called before proceeding in order to ensure consistent
         // state
         verify(mIkev2SessionCreator, timeout(TEST_TIMEOUT_MS))
@@ -912,6 +929,8 @@
         final Vpn vpn = startLegacyVpn(createVpn(primaryUser.id), mVpnProfile);
         final NetworkCallback cb = triggerOnAvailableAndGetCallback();
 
+        verifyInterfaceSetCfgWithFlags(IF_STATE_UP);
+
         // Wait for createIkeSession() to be called before proceeding in order to ensure consistent
         // state
         verify(mConnectivityManager, timeout(TEST_TIMEOUT_MS)).unregisterNetworkCallback(eq(cb));
diff --git a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
index 435c3c0..505ff9b 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsCollectionTest.java
@@ -17,6 +17,7 @@
 package com.android.server.net;
 
 import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.NetworkIdentity.OEM_NONE;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.TAG_NONE;
@@ -213,7 +214,7 @@
         final NetworkStats.Entry entry = new NetworkStats.Entry();
         final NetworkIdentitySet identSet = new NetworkIdentitySet();
         identSet.add(new NetworkIdentity(TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
-                TEST_IMSI, null, false, true, true));
+                TEST_IMSI, null, false, true, true, OEM_NONE));
 
         int myUid = Process.myUid();
         int otherUidInSameUser = Process.myUid() + 1;
@@ -468,7 +469,7 @@
         final NetworkStatsCollection large = new NetworkStatsCollection(HOUR_IN_MILLIS);
         final NetworkIdentitySet ident = new NetworkIdentitySet();
         ident.add(new NetworkIdentity(ConnectivityManager.TYPE_MOBILE, -1, TEST_IMSI, null,
-                false, true, true));
+                false, true, true, OEM_NONE));
         large.recordData(ident, UID_ALL, SET_ALL, TAG_NONE, TIME_A, TIME_B,
                 new NetworkStats.Entry(12_730_893_164L, 1, 0, 0, 0));
 
diff --git a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
index 291efc7..9fa1c50 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsObserversTest.java
@@ -17,6 +17,7 @@
 package com.android.server.net;
 
 import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.NetworkIdentity.OEM_NONE;
 import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
 import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
 import static android.net.NetworkStats.METERED_NO;
@@ -220,7 +221,7 @@
         identSet.add(new NetworkIdentity(
                 TYPE_MOBILE, TelephonyManager.NETWORK_TYPE_UNKNOWN,
                 IMSI_1, null /* networkId */, false /* roaming */, true /* metered */,
-                true /* defaultNetwork */));
+                true /* defaultNetwork */, OEM_NONE));
         return identSet;
     }
 
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 214c82d..54d6fb9 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -21,6 +21,9 @@
 import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.ConnectivityManager.TYPE_VPN;
 import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.NetworkIdentity.OEM_NONE;
+import static android.net.NetworkIdentity.OEM_PAID;
+import static android.net.NetworkIdentity.OEM_PRIVATE;
 import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
 import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
 import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
@@ -40,7 +43,10 @@
 import static android.net.NetworkStats.TAG_NONE;
 import static android.net.NetworkStats.UID_ALL;
 import static android.net.NetworkStatsHistory.FIELD_ALL;
+import static android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD;
 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
+import static android.net.NetworkTemplate.OEM_MANAGED_NO;
+import static android.net.NetworkTemplate.OEM_MANAGED_YES;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.NetworkTemplate.buildTemplateMobileWithRatType;
 import static android.net.NetworkTemplate.buildTemplateWifi;
@@ -643,6 +649,116 @@
         assertUidTotal(template5g, UID_RED, 5L, 13L, 31L, 9L, 2);
     }
 
+    @Test
+    public void testMobileStatsOemManaged() throws Exception {
+        final NetworkTemplate templateOemPaid = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+                /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PAID);
+
+        final NetworkTemplate templateOemPrivate = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+                /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_PRIVATE);
+
+        final NetworkTemplate templateOemAll = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+                /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL,
+                OEM_PAID | OEM_PRIVATE);
+
+        final NetworkTemplate templateOemYes = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+                /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_YES);
+
+        final NetworkTemplate templateOemNone = new NetworkTemplate(MATCH_MOBILE_WILDCARD,
+                /*subscriberId=*/null, /*matchSubscriberIds=*/null, /*networkId=*/null,
+                METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO);
+
+        // OEM_PAID network comes online.
+        NetworkState[] states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false,
+                new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
+        expectNetworkStatsSummary(buildEmptyStats());
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+                new UnderlyingNetworkInfo[0]);
+
+        // Create some traffic.
+        incrementCurrentTime(MINUTE_IN_MILLIS);
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+                        36L, 41L, 24L, 96L, 0L)));
+        forcePollAndWaitForIdle();
+
+        // OEM_PRIVATE network comes online.
+        states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false,
+                new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})};
+        expectNetworkStatsSummary(buildEmptyStats());
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+                new UnderlyingNetworkInfo[0]);
+
+        // Create some traffic.
+        incrementCurrentTime(MINUTE_IN_MILLIS);
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+                        49L, 71L, 72L, 48L, 0L)));
+        forcePollAndWaitForIdle();
+
+        // OEM_PAID + OEM_PRIVATE network comes online.
+        states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false,
+                new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
+                          NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
+        expectNetworkStatsSummary(buildEmptyStats());
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+                new UnderlyingNetworkInfo[0]);
+
+        // Create some traffic.
+        incrementCurrentTime(MINUTE_IN_MILLIS);
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+                        57L, 86L, 83L, 93L, 0L)));
+        forcePollAndWaitForIdle();
+
+        // OEM_NONE network comes online.
+        states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})};
+        expectNetworkStatsSummary(buildEmptyStats());
+        expectNetworkStatsUidDetail(buildEmptyStats());
+        mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
+                new UnderlyingNetworkInfo[0]);
+
+        // Create some traffic.
+        incrementCurrentTime(MINUTE_IN_MILLIS);
+        expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 1)
+                .addEntry(new NetworkStats.Entry(TEST_IFACE, UID_RED, SET_DEFAULT, TAG_NONE,
+                        29L, 73L, 34L, 31L, 0L)));
+        forcePollAndWaitForIdle();
+
+        // Verify OEM_PAID template gets only relevant stats.
+        assertUidTotal(templateOemPaid, UID_RED, 36L, 41L, 24L, 96L, 0);
+
+        // Verify OEM_PRIVATE template gets only relevant stats.
+        assertUidTotal(templateOemPrivate, UID_RED, 49L, 71L, 72L, 48L, 0);
+
+        // Verify OEM_PAID + OEM_PRIVATE template gets only relevant stats.
+        assertUidTotal(templateOemAll, UID_RED, 57L, 86L, 83L, 93L, 0);
+
+        // Verify OEM_NONE sees only non-OEM managed stats.
+        assertUidTotal(templateOemNone, UID_RED, 29L, 73L, 34L, 31L, 0);
+
+        // Verify OEM_MANAGED_YES sees all OEM managed stats.
+        assertUidTotal(templateOemYes, UID_RED,
+                36L + 49L + 57L,
+                41L + 71L + 86L,
+                24L + 72L + 83L,
+                96L + 48L + 93L, 0);
+
+        // Verify ALL_MOBILE template gets both OEM managed and non-OEM managed stats.
+        assertUidTotal(sTemplateImsi1, UID_RED,
+                36L + 49L + 57L + 29L,
+                41L + 71L + 86L + 73L,
+                24L + 72L + 83L + 34L,
+                96L + 48L + 93L + 31L, 0);
+    }
+
     // TODO: support per IMSI state
     private void setMobileRatTypeAndWaitForIdle(int ratType) {
         when(mNetworkStatsSubscriptionsMonitor.getRatTypeForSubscriberId(anyString()))
@@ -1461,7 +1577,7 @@
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
         capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
         capabilities.setSSID(TEST_SSID);
-        return new NetworkState(TYPE_WIFI, prop, capabilities, WIFI_NETWORK, null, TEST_SSID);
+        return new NetworkState(TYPE_WIFI, prop, capabilities, WIFI_NETWORK, null);
     }
 
     private static NetworkState buildMobile3gState(String subscriberId) {
@@ -1475,8 +1591,7 @@
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
         capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
         capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-        return new NetworkState(
-                TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId, null);
+        return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId);
     }
 
     private NetworkStats buildEmptyStats() {
@@ -1486,7 +1601,21 @@
     private static NetworkState buildVpnState() {
         final LinkProperties prop = new LinkProperties();
         prop.setInterfaceName(TUN_IFACE);
-        return new NetworkState(TYPE_VPN, prop, new NetworkCapabilities(), VPN_NETWORK, null, null);
+        return new NetworkState(TYPE_VPN, prop, new NetworkCapabilities(), VPN_NETWORK, null);
+    }
+
+    private static NetworkState buildOemManagedMobileState(String subscriberId, boolean isRoaming,
+                int[] oemNetCapabilities) {
+        final LinkProperties prop = new LinkProperties();
+        prop.setInterfaceName(TEST_IFACE);
+        final NetworkCapabilities capabilities = new NetworkCapabilities();
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
+        capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
+        for (int nc : oemNetCapabilities) {
+            capabilities.setCapability(nc, true);
+        }
+        capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId);
     }
 
     private long getElapsedRealtime() {
diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
index 7087676..66590c9 100644
--- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
@@ -16,6 +16,8 @@
 
 package android.net.vcn;
 
+import static android.net.vcn.VcnManager.VCN_STATUS_CODE_ACTIVE;
+
 import static androidx.test.InstrumentationRegistry.getContext;
 
 import static org.junit.Assert.assertEquals;
@@ -204,10 +206,13 @@
         cbBinder.onEnteredSafeMode();
         verify(mMockStatusCallback).onEnteredSafeMode();
 
+        cbBinder.onVcnStatusChanged(VCN_STATUS_CODE_ACTIVE);
+        verify(mMockStatusCallback).onVcnStatusChanged(VCN_STATUS_CODE_ACTIVE);
+
         cbBinder.onGatewayConnectionError(
                 UNDERLYING_NETWORK_CAPABILITIES,
                 VcnManager.VCN_ERROR_CODE_NETWORK_ERROR,
-                "java.net.UnknownHostException",
+                UnknownHostException.class.getName(),
                 "exception_message");
         verify(mMockStatusCallback)
                 .onGatewayConnectionError(
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
index 3ba0a1f..a674425 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
@@ -46,6 +46,6 @@
 
     @Test
     public void testParcelUnparcel() {
-        assertParcelSane(SAMPLE_NETWORK_POLICY, 2);
+        assertParcelSane(SAMPLE_NETWORK_POLICY, 1);
     }
 }
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 45b2381..9b500a7 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -43,7 +43,6 @@
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -59,6 +58,7 @@
 import android.net.vcn.IVcnUnderlyingNetworkPolicyListener;
 import android.net.vcn.VcnConfig;
 import android.net.vcn.VcnConfigTest;
+import android.net.vcn.VcnManager;
 import android.net.vcn.VcnUnderlyingNetworkPolicy;
 import android.net.wifi.WifiInfo;
 import android.os.IBinder;
@@ -783,7 +783,7 @@
                 true /* hasPermissionsforSubGroup */,
                 true /* hasLocationPermission */);
 
-        verify(mMockStatusCallback, times(1)).onEnteredSafeMode();
+        verify(mMockStatusCallback).onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
     }
 
     @Test
@@ -795,7 +795,8 @@
                 false /* hasPermissionsforSubGroup */,
                 true /* hasLocationPermission */);
 
-        verify(mMockStatusCallback, never()).onEnteredSafeMode();
+        verify(mMockStatusCallback, never())
+                .onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
     }
 
     @Test
@@ -807,7 +808,8 @@
                 true /* hasPermissionsforSubGroup */,
                 false /* hasLocationPermission */);
 
-        verify(mMockStatusCallback, never()).onEnteredSafeMode();
+        verify(mMockStatusCallback, never())
+                .onVcnStatusChanged(VcnManager.VCN_STATUS_CODE_SAFE_MODE);
     }
 
     @Test
diff --git a/tools/fonts/fontchain_linter.py b/tools/fonts/fontchain_linter.py
index a4a315b..7de7065 100755
--- a/tools/fonts/fontchain_linter.py
+++ b/tools/fonts/fontchain_linter.py
@@ -11,6 +11,12 @@
 
 EMOJI_VS = 0xFE0F
 
+#TODO(179952916): Rename CutiveMono and DancingScript
+CANONICAL_NAME_EXCEPTION_LIST = [
+    'CutiveMono.ttf',
+    'DancingScript-Regular.ttf',
+]
+
 LANG_TO_SCRIPT = {
     'as': 'Beng',
     'be': 'Cyrl',
@@ -658,6 +664,53 @@
             assert_font_supports_none_of_chars(record.font, cjk_punctuation, name)
 
 
+def getPostScriptName(font):
+  ttf = open_font(font)
+  nameTable = ttf['name']
+  for name in nameTable.names:
+    if name.nameID == 6 and name.platformID == 3 and name.platEncID == 1 and name.langID == 0x0409:
+      return str(name)
+
+
+def getSuffix(font):
+  file_path, index = font
+  with open(path.join(_fonts_dir, file_path), 'rb') as f:
+    tag = f.read(4)
+    isCollection = tag == b'ttcf'
+
+  ttf = open_font(font)
+  isType1 = ('CFF ' in ttf or 'CFF2' in ttf)
+
+  if isType1:
+    if isCollection:
+      return '.otc'
+    else:
+      return '.otf'
+  else:
+    if isCollection:
+      return '.ttc'
+    else:
+      return '.ttf'
+
+
+def check_canonical_name():
+  for record in _all_fonts:
+    file_name, index = record.font
+    if file_name in CANONICAL_NAME_EXCEPTION_LIST:
+      continue
+
+    if index and index != 0:
+      continue
+
+    psName = getPostScriptName(record.font)
+    assert psName, 'PostScript must be defined'
+
+    suffix = getSuffix(record.font)
+    canonicalName = '%s%s' % (psName, suffix)
+
+    assert file_name == canonicalName, (
+        '%s is not a canonical name. Must be %s' % (file_name, canonicalName))
+
 def main():
     global _fonts_dir
     target_out = sys.argv[1]
@@ -675,6 +728,8 @@
 
     check_cjk_punctuation()
 
+    check_canonical_name()
+
     check_emoji = sys.argv[2]
     if check_emoji == 'true':
         ucd_path = sys.argv[3]
diff --git a/tools/protologtool/Android.bp b/tools/protologtool/Android.bp
index 56351e3..ea3cd42 100644
--- a/tools/protologtool/Android.bp
+++ b/tools/protologtool/Android.bp
@@ -34,9 +34,13 @@
     srcs: [
         "tests/**/*.kt",
     ],
+    test_options: {
+        unit_test: true,
+    },
     static_libs: [
         "protologtool-lib",
         "junit",
         "mockito",
+        "objenesis",
     ],
 }