Merge "Add owner for wm policy test"
diff --git a/Android.bp b/Android.bp
index b69fa63..9d48cf8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -564,6 +564,7 @@
     libs: [
         "art.module.public.api",
         "sdk_module-lib_current_framework-tethering",
+        "sdk_module-lib_current_framework-connectivity-t",
         "sdk_public_current_framework-bluetooth",
         // There are a few classes from modules used by the core that
         // need to be resolved by metalava. We use a prebuilt stub of the
diff --git a/StubLibraries.bp b/StubLibraries.bp
index 39fd511..fef95e8 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -250,6 +250,7 @@
     srcs: [":module-lib-api-stubs-docs-non-updatable"],
     libs: [
         "sdk_module-lib_current_framework-tethering",
+        "sdk_module-lib_current_framework-connectivity-t",
         "sdk_public_current_framework-bluetooth",
         // NOTE: The below can be removed once the prebuilt stub contains bluetooth.
         "sdk_system_current_android",
diff --git a/api/Android.bp b/api/Android.bp
index 2c6cade..69d602a 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -93,7 +93,6 @@
 // Silence reflection warnings. See b/168689341
 metalava_cmd += " -J--add-opens=java.base/java.util=ALL-UNNAMED "
 metalava_cmd += " --quiet --no-banner --format=v2 "
-metalava_cmd += " --hide ChangedThrows "
 
 genrule {
     name: "current-api-xml",
@@ -113,7 +112,7 @@
         "framework-appsearch",
         "framework-bluetooth",
         "framework-connectivity",
-        "framework-connectivity-tiramisu",
+        "framework-connectivity-t",
         "framework-graphics",
         "framework-media",
         "framework-mediaprovider",
@@ -179,8 +178,10 @@
     cmd: metalava_cmd +
         "--check-compatibility:api:released $(location :android.api.module-lib.latest) " +
         // Note: having "public" be the base of module-lib is not perfect -- it should
-        // ideally be a merged public+system), but this will  help when migrating from
-        // MODULE_LIBS -> public.
+        // ideally be a merged public+system (which metalava is not currently able to generate).
+        // This "base" will help when migrating from MODULE_LIBS -> public, but not when
+        // migrating from MODULE_LIBS -> system (where it needs to instead be listed as
+        // an incompatibility).
         "--check-compatibility:base $(location :frameworks-base-api-current.txt) " +
         "--baseline:compatibility:released $(location :android-incompatibilities.api.module-lib.latest) " +
         "--update-baseline:compatibility:released $(genDir)/updated-baseline.txt " +
diff --git a/boot/hiddenapi/hiddenapi-max-target-o.txt b/boot/hiddenapi/hiddenapi-max-target-o.txt
index 50e0a1b..e346ebf 100644
--- a/boot/hiddenapi/hiddenapi-max-target-o.txt
+++ b/boot/hiddenapi/hiddenapi-max-target-o.txt
@@ -9315,78 +9315,6 @@
 Landroid/app/usage/IUsageStatsManager;->setAppStandbyBuckets(Landroid/content/pm/ParceledListSlice;I)V
 Landroid/app/usage/IUsageStatsManager;->unregisterAppUsageObserver(ILjava/lang/String;)V
 Landroid/app/usage/IUsageStatsManager;->whitelistAppTemporarily(Ljava/lang/String;JI)V
-Landroid/app/usage/NetworkStats$Bucket;->convertDefaultNetworkStatus(I)I
-Landroid/app/usage/NetworkStats$Bucket;->convertMetered(I)I
-Landroid/app/usage/NetworkStats$Bucket;->convertRoaming(I)I
-Landroid/app/usage/NetworkStats$Bucket;->convertSet(I)I
-Landroid/app/usage/NetworkStats$Bucket;->convertState(I)I
-Landroid/app/usage/NetworkStats$Bucket;->convertTag(I)I
-Landroid/app/usage/NetworkStats$Bucket;->convertUid(I)I
-Landroid/app/usage/NetworkStats$Bucket;->mBeginTimeStamp:J
-Landroid/app/usage/NetworkStats$Bucket;->mDefaultNetworkStatus:I
-Landroid/app/usage/NetworkStats$Bucket;->mEndTimeStamp:J
-Landroid/app/usage/NetworkStats$Bucket;->mMetered:I
-Landroid/app/usage/NetworkStats$Bucket;->mRoaming:I
-Landroid/app/usage/NetworkStats$Bucket;->mRxBytes:J
-Landroid/app/usage/NetworkStats$Bucket;->mRxPackets:J
-Landroid/app/usage/NetworkStats$Bucket;->mState:I
-Landroid/app/usage/NetworkStats$Bucket;->mTag:I
-Landroid/app/usage/NetworkStats$Bucket;->mTxBytes:J
-Landroid/app/usage/NetworkStats$Bucket;->mTxPackets:J
-Landroid/app/usage/NetworkStats$Bucket;->mUid:I
-Landroid/app/usage/NetworkStats;-><init>(Landroid/content/Context;Landroid/net/NetworkTemplate;IJJLandroid/net/INetworkStatsService;)V
-Landroid/app/usage/NetworkStats;->fillBucketFromSummaryEntry(Landroid/app/usage/NetworkStats$Bucket;)V
-Landroid/app/usage/NetworkStats;->getDeviceSummaryForNetwork()Landroid/app/usage/NetworkStats$Bucket;
-Landroid/app/usage/NetworkStats;->getNextHistoryBucket(Landroid/app/usage/NetworkStats$Bucket;)Z
-Landroid/app/usage/NetworkStats;->getNextSummaryBucket(Landroid/app/usage/NetworkStats$Bucket;)Z
-Landroid/app/usage/NetworkStats;->getSummaryAggregate()Landroid/app/usage/NetworkStats$Bucket;
-Landroid/app/usage/NetworkStats;->getUid()I
-Landroid/app/usage/NetworkStats;->hasNextUid()Z
-Landroid/app/usage/NetworkStats;->isUidEnumeration()Z
-Landroid/app/usage/NetworkStats;->mCloseGuard:Ldalvik/system/CloseGuard;
-Landroid/app/usage/NetworkStats;->mEndTimeStamp:J
-Landroid/app/usage/NetworkStats;->mEnumerationIndex:I
-Landroid/app/usage/NetworkStats;->mHistory:Landroid/net/NetworkStatsHistory;
-Landroid/app/usage/NetworkStats;->mRecycledHistoryEntry:Landroid/net/NetworkStatsHistory$Entry;
-Landroid/app/usage/NetworkStats;->mRecycledSummaryEntry:Landroid/net/NetworkStats$Entry;
-Landroid/app/usage/NetworkStats;->mSession:Landroid/net/INetworkStatsSession;
-Landroid/app/usage/NetworkStats;->mStartTimeStamp:J
-Landroid/app/usage/NetworkStats;->mState:I
-Landroid/app/usage/NetworkStats;->mSummary:Landroid/net/NetworkStats;
-Landroid/app/usage/NetworkStats;->mTag:I
-Landroid/app/usage/NetworkStats;->mTemplate:Landroid/net/NetworkTemplate;
-Landroid/app/usage/NetworkStats;->mUidOrUidIndex:I
-Landroid/app/usage/NetworkStats;->mUids:[I
-Landroid/app/usage/NetworkStats;->setSingleUidTagState(III)V
-Landroid/app/usage/NetworkStats;->startHistoryEnumeration(III)V
-Landroid/app/usage/NetworkStats;->startSummaryEnumeration()V
-Landroid/app/usage/NetworkStats;->startUserUidEnumeration()V
-Landroid/app/usage/NetworkStats;->stepHistory()V
-Landroid/app/usage/NetworkStats;->stepUid()V
-Landroid/app/usage/NetworkStats;->TAG:Ljava/lang/String;
-Landroid/app/usage/NetworkStatsManager$CallbackHandler;-><init>(Landroid/os/Looper;ILjava/lang/String;Landroid/app/usage/NetworkStatsManager$UsageCallback;)V
-Landroid/app/usage/NetworkStatsManager$CallbackHandler;->getObject(Landroid/os/Message;Ljava/lang/String;)Ljava/lang/Object;
-Landroid/app/usage/NetworkStatsManager$CallbackHandler;->mCallback:Landroid/app/usage/NetworkStatsManager$UsageCallback;
-Landroid/app/usage/NetworkStatsManager$CallbackHandler;->mNetworkType:I
-Landroid/app/usage/NetworkStatsManager$CallbackHandler;->mSubscriberId:Ljava/lang/String;
-Landroid/app/usage/NetworkStatsManager$UsageCallback;->request:Landroid/net/DataUsageRequest;
-Landroid/app/usage/NetworkStatsManager;-><init>(Landroid/content/Context;Landroid/net/INetworkStatsService;)V
-Landroid/app/usage/NetworkStatsManager;->CALLBACK_LIMIT_REACHED:I
-Landroid/app/usage/NetworkStatsManager;->CALLBACK_RELEASED:I
-Landroid/app/usage/NetworkStatsManager;->createTemplate(ILjava/lang/String;)Landroid/net/NetworkTemplate;
-Landroid/app/usage/NetworkStatsManager;->DBG:Z
-Landroid/app/usage/NetworkStatsManager;->FLAG_AUGMENT_WITH_SUBSCRIPTION_PLAN:I
-Landroid/app/usage/NetworkStatsManager;->FLAG_POLL_FORCE:I
-Landroid/app/usage/NetworkStatsManager;->FLAG_POLL_ON_OPEN:I
-Landroid/app/usage/NetworkStatsManager;->mContext:Landroid/content/Context;
-Landroid/app/usage/NetworkStatsManager;->mFlags:I
-Landroid/app/usage/NetworkStatsManager;->MIN_THRESHOLD_BYTES:J
-Landroid/app/usage/NetworkStatsManager;->mService:Landroid/net/INetworkStatsService;
-Landroid/app/usage/NetworkStatsManager;->querySummaryForDevice(Landroid/net/NetworkTemplate;JJ)Landroid/app/usage/NetworkStats$Bucket;
-Landroid/app/usage/NetworkStatsManager;->registerUsageCallback(Landroid/net/NetworkTemplate;IJLandroid/app/usage/NetworkStatsManager$UsageCallback;Landroid/os/Handler;)V
-Landroid/app/usage/NetworkStatsManager;->setAugmentWithSubscriptionPlan(Z)V
-Landroid/app/usage/NetworkStatsManager;->setPollOnOpen(Z)V
-Landroid/app/usage/NetworkStatsManager;->TAG:Ljava/lang/String;
 Landroid/app/usage/StorageStats;-><init>()V
 Landroid/app/usage/StorageStats;-><init>(Landroid/os/Parcel;)V
 Landroid/app/usage/StorageStats;->cacheBytes:J
@@ -35338,13 +35266,6 @@
 Landroid/net/Credentials;->gid:I
 Landroid/net/Credentials;->pid:I
 Landroid/net/Credentials;->uid:I
-Landroid/net/DataUsageRequest;-><init>(ILandroid/net/NetworkTemplate;J)V
-Landroid/net/DataUsageRequest;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/net/DataUsageRequest;->PARCELABLE_KEY:Ljava/lang/String;
-Landroid/net/DataUsageRequest;->requestId:I
-Landroid/net/DataUsageRequest;->REQUEST_ID_UNSET:I
-Landroid/net/DataUsageRequest;->template:Landroid/net/NetworkTemplate;
-Landroid/net/DataUsageRequest;->thresholdInBytes:J
 Landroid/net/DhcpResults;->addDns(Ljava/lang/String;)Z
 Landroid/net/DhcpResults;->clear()V
 Landroid/net/DhcpResults;->CREATOR:Landroid/os/Parcelable$Creator;
@@ -35793,68 +35714,6 @@
 Landroid/net/INetworkScoreService;->setActiveScorer(Ljava/lang/String;)Z
 Landroid/net/INetworkScoreService;->unregisterNetworkScoreCache(ILandroid/net/INetworkScoreCache;)V
 Landroid/net/INetworkScoreService;->updateScores([Landroid/net/ScoredNetwork;)Z
-Landroid/net/INetworkStatsService$Stub$Proxy;->forceUpdate()V
-Landroid/net/INetworkStatsService$Stub$Proxy;->forceUpdateIfaces([Landroid/net/Network;)V
-Landroid/net/INetworkStatsService$Stub$Proxy;->getDataLayerSnapshotForUid(I)Landroid/net/NetworkStats;
-Landroid/net/INetworkStatsService$Stub$Proxy;->getDetailedUidStats([Ljava/lang/String;)Landroid/net/NetworkStats;
-Landroid/net/INetworkStatsService$Stub$Proxy;->getIfaceStats(Ljava/lang/String;I)J
-Landroid/net/INetworkStatsService$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/net/INetworkStatsService$Stub$Proxy;->getTotalStats(I)J
-Landroid/net/INetworkStatsService$Stub$Proxy;->getUidStats(II)J
-Landroid/net/INetworkStatsService$Stub$Proxy;->incrementOperationCount(III)V
-Landroid/net/INetworkStatsService$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/INetworkStatsService$Stub$Proxy;->openSession()Landroid/net/INetworkStatsSession;
-Landroid/net/INetworkStatsService$Stub$Proxy;->openSessionForUsageStats(ILjava/lang/String;)Landroid/net/INetworkStatsSession;
-Landroid/net/INetworkStatsService$Stub$Proxy;->registerUsageCallback(Ljava/lang/String;Landroid/net/DataUsageRequest;Landroid/os/Messenger;Landroid/os/IBinder;)Landroid/net/DataUsageRequest;
-Landroid/net/INetworkStatsService$Stub$Proxy;->unregisterUsageRequest(Landroid/net/DataUsageRequest;)V
-Landroid/net/INetworkStatsService$Stub;-><init>()V
-Landroid/net/INetworkStatsService$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_forceUpdate:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_forceUpdateIfaces:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getDataLayerSnapshotForUid:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getDetailedUidStats:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getIfaceStats:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getMobileIfaces:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getTotalStats:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_getUidStats:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_incrementOperationCount:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_openSession:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_openSessionForUsageStats:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_registerUsageCallback:I
-Landroid/net/INetworkStatsService$Stub;->TRANSACTION_unregisterUsageRequest:I
-Landroid/net/INetworkStatsService;->forceUpdateIfaces([Landroid/net/Network;)V
-Landroid/net/INetworkStatsService;->getDetailedUidStats([Ljava/lang/String;)Landroid/net/NetworkStats;
-Landroid/net/INetworkStatsService;->getIfaceStats(Ljava/lang/String;I)J
-Landroid/net/INetworkStatsService;->getTotalStats(I)J
-Landroid/net/INetworkStatsService;->getUidStats(II)J
-Landroid/net/INetworkStatsService;->incrementOperationCount(III)V
-Landroid/net/INetworkStatsService;->registerUsageCallback(Ljava/lang/String;Landroid/net/DataUsageRequest;Landroid/os/Messenger;Landroid/os/IBinder;)Landroid/net/DataUsageRequest;
-Landroid/net/INetworkStatsService;->unregisterUsageRequest(Landroid/net/DataUsageRequest;)V
-Landroid/net/INetworkStatsSession$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/INetworkStatsSession$Stub$Proxy;->close()V
-Landroid/net/INetworkStatsSession$Stub$Proxy;->getDeviceSummaryForNetwork(Landroid/net/NetworkTemplate;JJ)Landroid/net/NetworkStats;
-Landroid/net/INetworkStatsSession$Stub$Proxy;->getHistoryForNetwork(Landroid/net/NetworkTemplate;I)Landroid/net/NetworkStatsHistory;
-Landroid/net/INetworkStatsSession$Stub$Proxy;->getHistoryForUid(Landroid/net/NetworkTemplate;IIII)Landroid/net/NetworkStatsHistory;
-Landroid/net/INetworkStatsSession$Stub$Proxy;->getHistoryIntervalForUid(Landroid/net/NetworkTemplate;IIIIJJ)Landroid/net/NetworkStatsHistory;
-Landroid/net/INetworkStatsSession$Stub$Proxy;->getInterfaceDescriptor()Ljava/lang/String;
-Landroid/net/INetworkStatsSession$Stub$Proxy;->getRelevantUids()[I
-Landroid/net/INetworkStatsSession$Stub$Proxy;->getSummaryForAllUid(Landroid/net/NetworkTemplate;JJZ)Landroid/net/NetworkStats;
-Landroid/net/INetworkStatsSession$Stub$Proxy;->getSummaryForNetwork(Landroid/net/NetworkTemplate;JJ)Landroid/net/NetworkStats;
-Landroid/net/INetworkStatsSession$Stub$Proxy;->mRemote:Landroid/os/IBinder;
-Landroid/net/INetworkStatsSession$Stub;-><init>()V
-Landroid/net/INetworkStatsSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsSession;
-Landroid/net/INetworkStatsSession$Stub;->DESCRIPTOR:Ljava/lang/String;
-Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_close:I
-Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getDeviceSummaryForNetwork:I
-Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getHistoryForNetwork:I
-Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getHistoryForUid:I
-Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getHistoryIntervalForUid:I
-Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getRelevantUids:I
-Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getSummaryForAllUid:I
-Landroid/net/INetworkStatsSession$Stub;->TRANSACTION_getSummaryForNetwork:I
-Landroid/net/INetworkStatsSession;->getDeviceSummaryForNetwork(Landroid/net/NetworkTemplate;JJ)Landroid/net/NetworkStats;
-Landroid/net/INetworkStatsSession;->getHistoryIntervalForUid(Landroid/net/NetworkTemplate;IIIIJJ)Landroid/net/NetworkStatsHistory;
-Landroid/net/INetworkStatsSession;->getRelevantUids()[I
 Landroid/net/InterfaceConfiguration;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/net/InterfaceConfiguration;->FLAG_DOWN:Ljava/lang/String;
 Landroid/net/InterfaceConfiguration;->FLAG_UP:Ljava/lang/String;
@@ -36529,41 +36388,6 @@
 Landroid/net/StringNetworkSpecifier;-><init>(Ljava/lang/String;)V
 Landroid/net/StringNetworkSpecifier;->CREATOR:Landroid/os/Parcelable$Creator;
 Landroid/net/StringNetworkSpecifier;->satisfiedBy(Landroid/net/NetworkSpecifier;)Z
-Landroid/net/TrafficStats;->addIfSupported(J)J
-Landroid/net/TrafficStats;->closeQuietly(Landroid/net/INetworkStatsSession;)V
-Landroid/net/TrafficStats;->GB_IN_BYTES:J
-Landroid/net/TrafficStats;->getDataLayerSnapshotForUid(Landroid/content/Context;)Landroid/net/NetworkStats;
-Landroid/net/TrafficStats;->getRxPackets(Ljava/lang/String;)J
-Landroid/net/TrafficStats;->getTxPackets(Ljava/lang/String;)J
-Landroid/net/TrafficStats;->KB_IN_BYTES:J
-Landroid/net/TrafficStats;->LOOPBACK_IFACE:Ljava/lang/String;
-Landroid/net/TrafficStats;->MB_IN_BYTES:J
-Landroid/net/TrafficStats;->PB_IN_BYTES:J
-Landroid/net/TrafficStats;->sActiveProfilingStart:Landroid/net/NetworkStats;
-Landroid/net/TrafficStats;->sProfilingLock:Ljava/lang/Object;
-Landroid/net/TrafficStats;->sStatsService:Landroid/net/INetworkStatsService;
-Landroid/net/TrafficStats;->startDataProfiling(Landroid/content/Context;)V
-Landroid/net/TrafficStats;->stopDataProfiling(Landroid/content/Context;)Landroid/net/NetworkStats;
-Landroid/net/TrafficStats;->TAG_SYSTEM_APP:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_BACKUP:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_DHCP:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_DOWNLOAD:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_GPS:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_MEDIA:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_NEIGHBOR:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_NTP:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_PAC:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_PROBE:I
-Landroid/net/TrafficStats;->TAG_SYSTEM_RESTORE:I
-Landroid/net/TrafficStats;->TB_IN_BYTES:J
-Landroid/net/TrafficStats;->TYPE_RX_BYTES:I
-Landroid/net/TrafficStats;->TYPE_RX_PACKETS:I
-Landroid/net/TrafficStats;->TYPE_TCP_RX_PACKETS:I
-Landroid/net/TrafficStats;->TYPE_TCP_TX_PACKETS:I
-Landroid/net/TrafficStats;->TYPE_TX_BYTES:I
-Landroid/net/TrafficStats;->TYPE_TX_PACKETS:I
-Landroid/net/TrafficStats;->UID_REMOVED:I
-Landroid/net/TrafficStats;->UID_TETHERING:I
 Landroid/net/Uri$AbstractHierarchicalUri;-><init>()V
 Landroid/net/Uri$AbstractHierarchicalUri;->getUserInfoPart()Landroid/net/Uri$Part;
 Landroid/net/Uri$AbstractHierarchicalUri;->host:Ljava/lang/String;
diff --git a/boot/hiddenapi/hiddenapi-unsupported.txt b/boot/hiddenapi/hiddenapi-unsupported.txt
index 002d42d..e47149b 100644
--- a/boot/hiddenapi/hiddenapi-unsupported.txt
+++ b/boot/hiddenapi/hiddenapi-unsupported.txt
@@ -170,9 +170,6 @@
 Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V
 Landroid/net/INetworkPolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkPolicyManager;
 Landroid/net/INetworkScoreService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkScoreService;
-Landroid/net/INetworkStatsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Landroid/net/INetworkStatsService$Stub$Proxy;->getMobileIfaces()[Ljava/lang/String;
-Landroid/net/INetworkStatsService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/INetworkStatsService;
 Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/os/IDeviceIdentifiersPolicyService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdentifiersPolicyService;
 Landroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController;
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 30a8a8e..52fd7be 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -764,6 +764,7 @@
     // We have no bootanimation file, so we use the stock android logo
     // animation.
     if (mZipFileName.isEmpty()) {
+        ALOGD("No animation file");
         result = android();
     } else {
         result = movie();
@@ -1474,6 +1475,10 @@
                     part.backgroundColor[2],
                     1.0f);
 
+            ALOGD("Playing files = %s/%s, Requested repeat = %d, playUntilComplete = %s",
+                    animation.fileName.string(), part.path.string(), part.count,
+                    part.playUntilComplete ? "true" : "false");
+
             // For the last animation, if we have progress indicator from
             // the system, display it.
             int currentProgress = android::base::GetIntProperty(PROGRESS_PROP_NAME, 0);
@@ -1607,6 +1612,9 @@
         }
     }
 
+    ALOGD("%sAnimationShownTiming End time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
+            elapsedRealtime());
+
     return true;
 }
 
@@ -1682,6 +1690,8 @@
         return nullptr;
     }
 
+    ALOGD("%s is loaded successfully", fn.string());
+
     Animation *animation =  new Animation;
     animation->fileName = fn;
     animation->zip = zip;
diff --git a/cmds/idmap2/tests/IdmapTests.cpp b/cmds/idmap2/tests/IdmapTests.cpp
index 9c6402a..738b9cf 100644
--- a/cmds/idmap2/tests/IdmapTests.cpp
+++ b/cmds/idmap2/tests/IdmapTests.cpp
@@ -37,7 +37,6 @@
 #include "idmap2/Idmap.h"
 #include "idmap2/LogInfo.h"
 
-using android::Res_value;
 using ::testing::NotNull;
 
 using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
diff --git a/cmds/idmap2/tests/ResourceMappingTests.cpp b/cmds/idmap2/tests/ResourceMappingTests.cpp
index 5a1d808..32b3d13 100644
--- a/cmds/idmap2/tests/ResourceMappingTests.cpp
+++ b/cmds/idmap2/tests/ResourceMappingTests.cpp
@@ -29,8 +29,6 @@
 #include "idmap2/LogInfo.h"
 #include "idmap2/ResourceMapping.h"
 
-using android::Res_value;
-
 using PolicyFlags = android::ResTable_overlayable_policy_header::PolicyFlags;
 
 namespace android::idmap2 {
diff --git a/core/api/current.txt b/core/api/current.txt
index b5066d9..42407ea 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8339,62 +8339,6 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.app.usage.ExternalStorageStats> CREATOR;
   }
 
-  public final class NetworkStats implements java.lang.AutoCloseable {
-    method public void close();
-    method public boolean getNextBucket(android.app.usage.NetworkStats.Bucket);
-    method public boolean hasNextBucket();
-  }
-
-  public static class NetworkStats.Bucket {
-    ctor public NetworkStats.Bucket();
-    method public int getDefaultNetworkStatus();
-    method public long getEndTimeStamp();
-    method public int getMetered();
-    method public int getRoaming();
-    method public long getRxBytes();
-    method public long getRxPackets();
-    method public long getStartTimeStamp();
-    method public int getState();
-    method public int getTag();
-    method public long getTxBytes();
-    method public long getTxPackets();
-    method public int getUid();
-    field public static final int DEFAULT_NETWORK_ALL = -1; // 0xffffffff
-    field public static final int DEFAULT_NETWORK_NO = 1; // 0x1
-    field public static final int DEFAULT_NETWORK_YES = 2; // 0x2
-    field public static final int METERED_ALL = -1; // 0xffffffff
-    field public static final int METERED_NO = 1; // 0x1
-    field public static final int METERED_YES = 2; // 0x2
-    field public static final int ROAMING_ALL = -1; // 0xffffffff
-    field public static final int ROAMING_NO = 1; // 0x1
-    field public static final int ROAMING_YES = 2; // 0x2
-    field public static final int STATE_ALL = -1; // 0xffffffff
-    field public static final int STATE_DEFAULT = 1; // 0x1
-    field public static final int STATE_FOREGROUND = 2; // 0x2
-    field public static final int TAG_NONE = 0; // 0x0
-    field public static final int UID_ALL = -1; // 0xffffffff
-    field public static final int UID_REMOVED = -4; // 0xfffffffc
-    field public static final int UID_TETHERING = -5; // 0xfffffffb
-  }
-
-  public class NetworkStatsManager {
-    method @WorkerThread public android.app.usage.NetworkStats queryDetails(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats queryDetailsForUid(int, String, long, long, int) throws java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTag(int, String, long, long, int, int) throws java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTagState(int, String, long, long, int, int, int) throws java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats querySummary(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForDevice(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
-    method @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForUser(int, String, long, long) throws android.os.RemoteException, java.lang.SecurityException;
-    method public void registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback);
-    method public void registerUsageCallback(int, String, long, android.app.usage.NetworkStatsManager.UsageCallback, @Nullable android.os.Handler);
-    method public void unregisterUsageCallback(android.app.usage.NetworkStatsManager.UsageCallback);
-  }
-
-  public abstract static class NetworkStatsManager.UsageCallback {
-    ctor public NetworkStatsManager.UsageCallback();
-    method public abstract void onThresholdReached(int, String);
-  }
-
   public final class StorageStats implements android.os.Parcelable {
     method public int describeContents();
     method public long getAppBytes();
@@ -25311,9 +25255,9 @@
 
   public abstract class PlatformVpnProfile {
     method public final boolean areLocalRoutesExcluded();
-    method public final boolean getRequiresInternetValidation();
     method public final int getType();
     method @NonNull public final String getTypeString();
+    method public final boolean isInternetValidationRequired();
     field public static final int TYPE_IKEV2_IPSEC_PSK = 7; // 0x7
     field public static final int TYPE_IKEV2_IPSEC_RSA = 8; // 0x8
     field public static final int TYPE_IKEV2_IPSEC_USER_PASS = 6; // 0x6
@@ -25366,50 +25310,6 @@
     method @NonNull public android.net.TelephonyNetworkSpecifier.Builder setSubscriptionId(int);
   }
 
-  public class TrafficStats {
-    ctor public TrafficStats();
-    method public static void clearThreadStatsTag();
-    method public static void clearThreadStatsUid();
-    method public static int getAndSetThreadStatsTag(int);
-    method public static long getMobileRxBytes();
-    method public static long getMobileRxPackets();
-    method public static long getMobileTxBytes();
-    method public static long getMobileTxPackets();
-    method public static long getRxBytes(@NonNull String);
-    method public static long getRxPackets(@NonNull String);
-    method public static int getThreadStatsTag();
-    method public static int getThreadStatsUid();
-    method public static long getTotalRxBytes();
-    method public static long getTotalRxPackets();
-    method public static long getTotalTxBytes();
-    method public static long getTotalTxPackets();
-    method public static long getTxBytes(@NonNull String);
-    method public static long getTxPackets(@NonNull String);
-    method public static long getUidRxBytes(int);
-    method public static long getUidRxPackets(int);
-    method @Deprecated public static long getUidTcpRxBytes(int);
-    method @Deprecated public static long getUidTcpRxSegments(int);
-    method @Deprecated public static long getUidTcpTxBytes(int);
-    method @Deprecated public static long getUidTcpTxSegments(int);
-    method public static long getUidTxBytes(int);
-    method public static long getUidTxPackets(int);
-    method @Deprecated public static long getUidUdpRxBytes(int);
-    method @Deprecated public static long getUidUdpRxPackets(int);
-    method @Deprecated public static long getUidUdpTxBytes(int);
-    method @Deprecated public static long getUidUdpTxPackets(int);
-    method public static void incrementOperationCount(int);
-    method public static void incrementOperationCount(int, int);
-    method public static void setThreadStatsTag(int);
-    method public static void setThreadStatsUid(int);
-    method public static void tagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
-    method public static void tagFileDescriptor(java.io.FileDescriptor) throws java.io.IOException;
-    method public static void tagSocket(java.net.Socket) throws java.net.SocketException;
-    method public static void untagDatagramSocket(java.net.DatagramSocket) throws java.net.SocketException;
-    method public static void untagFileDescriptor(java.io.FileDescriptor) throws java.io.IOException;
-    method public static void untagSocket(java.net.Socket) throws java.net.SocketException;
-    field public static final int UNSUPPORTED = -1; // 0xffffffff
-  }
-
   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);
@@ -25564,7 +25464,7 @@
     field public static final String EXTRA_ERROR_CLASS = "android.net.extra.ERROR_CLASS";
     field public static final String EXTRA_ERROR_CODE = "android.net.extra.ERROR_CODE";
     field public static final String EXTRA_SESSION_KEY = "android.net.extra.SESSION_KEY";
-    field public static final String EXTRA_TIMESTAMP = "android.net.extra.TIMESTAMP";
+    field public static final String EXTRA_TIMESTAMP_MILLIS = "android.net.extra.TIMESTAMP_MILLIS";
     field public static final String EXTRA_UNDERLYING_LINK_PROPERTIES = "android.net.extra.UNDERLYING_LINK_PROPERTIES";
     field public static final String EXTRA_UNDERLYING_NETWORK = "android.net.extra.UNDERLYING_NETWORK";
     field public static final String EXTRA_UNDERLYING_NETWORK_CAPABILITIES = "android.net.extra.UNDERLYING_NETWORK_CAPABILITIES";
@@ -29595,6 +29495,7 @@
     field public static final int PREVIEW_SDK_INT;
     field public static final String RELEASE;
     field @NonNull public static final String RELEASE_OR_CODENAME;
+    field @NonNull public static final String RELEASE_OR_PREVIEW_DISPLAY;
     field @Deprecated public static final String SDK;
     field public static final int SDK_INT;
     field public static final String SECURITY_PATCH;
@@ -29669,7 +29570,7 @@
     method @Deprecated @Nullable public android.os.Parcelable[] getParcelableArray(@Nullable String);
     method @Nullable public <T> T[] getParcelableArray(@Nullable String, @NonNull Class<T>);
     method @Deprecated @Nullable public <T extends android.os.Parcelable> java.util.ArrayList<T> getParcelableArrayList(@Nullable String);
-    method @Nullable public <T> java.util.ArrayList<T> getParcelableArrayList(@Nullable String, @NonNull Class<T>);
+    method @Nullable public <T> java.util.ArrayList<T> getParcelableArrayList(@Nullable String, @NonNull Class<? extends T>);
     method @Deprecated @Nullable public java.io.Serializable getSerializable(@Nullable String);
     method @Nullable public <T extends java.io.Serializable> T getSerializable(@Nullable String, @NonNull Class<T>);
     method public short getShort(String);
@@ -29678,7 +29579,7 @@
     method @Nullable public android.util.Size getSize(@Nullable String);
     method @Nullable public android.util.SizeF getSizeF(@Nullable String);
     method @Deprecated @Nullable public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(@Nullable String);
-    method @Nullable public <T> android.util.SparseArray<T> getSparseParcelableArray(@Nullable String, @NonNull Class<T>);
+    method @Nullable public <T> android.util.SparseArray<T> getSparseParcelableArray(@Nullable String, @NonNull Class<? extends T>);
     method @Nullable public java.util.ArrayList<java.lang.String> getStringArrayList(@Nullable String);
     method public boolean hasFileDescriptors();
     method public void putAll(android.os.Bundle);
@@ -30301,7 +30202,7 @@
     method @Deprecated @Nullable public android.os.Parcelable.Creator<?> readParcelableCreator(@Nullable ClassLoader);
     method @Nullable public <T> android.os.Parcelable.Creator<T> readParcelableCreator(@Nullable ClassLoader, @NonNull Class<T>);
     method @Deprecated @NonNull public <T extends android.os.Parcelable> java.util.List<T> readParcelableList(@NonNull java.util.List<T>, @Nullable ClassLoader);
-    method @NonNull public <T> java.util.List<T> readParcelableList(@NonNull java.util.List<T>, @Nullable ClassLoader, @NonNull Class<T>);
+    method @NonNull public <T> java.util.List<T> readParcelableList(@NonNull java.util.List<T>, @Nullable ClassLoader, @NonNull Class<? extends T>);
     method @Nullable public android.os.PersistableBundle readPersistableBundle();
     method @Nullable public android.os.PersistableBundle readPersistableBundle(@Nullable ClassLoader);
     method @Deprecated @Nullable public java.io.Serializable readSerializable();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index bcdd0a46..a9f0d2e 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -51,31 +51,6 @@
 
 }
 
-package android.app.usage {
-
-  public class NetworkStatsManager {
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void forceUpdate();
-    method public static int getCollapsedRatType(int);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void notifyNetworkStatus(@NonNull java.util.List<android.net.Network>, @NonNull java.util.List<android.net.NetworkStateSnapshot>, @Nullable String, @NonNull java.util.List<android.net.UnderlyingNetworkInfo>);
-    method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForDevice(@NonNull android.net.NetworkTemplate, long, long);
-    method @NonNull @WorkerThread public android.app.usage.NetworkStats queryDetailsForUidTagState(@NonNull android.net.NetworkTemplate, long, long, int, int, int) throws java.lang.SecurityException;
-    method @NonNull @WorkerThread public android.app.usage.NetworkStats querySummary(@NonNull android.net.NetworkTemplate, long, long) throws java.lang.SecurityException;
-    method @NonNull @WorkerThread public android.app.usage.NetworkStats.Bucket querySummaryForDevice(@NonNull android.net.NetworkTemplate, long, long);
-    method @NonNull @WorkerThread public android.app.usage.NetworkStats queryTaggedSummary(@NonNull android.net.NetworkTemplate, long, long) throws java.lang.SecurityException;
-    method public void registerUsageCallback(@NonNull android.net.NetworkTemplate, long, @NonNull java.util.concurrent.Executor, @NonNull android.app.usage.NetworkStatsManager.UsageCallback);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setDefaultGlobalAlert(long);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setPollOnOpen(boolean);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setStatsProviderWarningAndLimitAsync(@NonNull String, long, long);
-    method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK}) public void setUidForeground(int, boolean);
-    field public static final int NETWORK_TYPE_5G_NSA = -2; // 0xfffffffe
-  }
-
-  public abstract static class NetworkStatsManager.UsageCallback {
-    method public void onThresholdReached(@NonNull android.net.NetworkTemplate);
-  }
-
-}
-
 package android.content {
 
   public abstract class ContentProvider implements android.content.ComponentCallbacks2 {
@@ -238,32 +213,6 @@
     ctor public LocalSocket(@NonNull java.io.FileDescriptor);
   }
 
-  public class NetworkIdentity {
-    method public int getOemManaged();
-    method public int getRatType();
-    method @Nullable public String getSubscriberId();
-    method public int getType();
-    method @Nullable public String getWifiNetworkKey();
-    method public boolean isDefaultNetwork();
-    method public boolean isMetered();
-    method public boolean isRoaming();
-  }
-
-  public static final class NetworkIdentity.Builder {
-    ctor public NetworkIdentity.Builder();
-    method @NonNull public android.net.NetworkIdentity build();
-    method @NonNull public android.net.NetworkIdentity.Builder clearRatType();
-    method @NonNull public android.net.NetworkIdentity.Builder setDefaultNetwork(boolean);
-    method @NonNull public android.net.NetworkIdentity.Builder setMetered(boolean);
-    method @NonNull public android.net.NetworkIdentity.Builder setNetworkStateSnapshot(@NonNull android.net.NetworkStateSnapshot);
-    method @NonNull public android.net.NetworkIdentity.Builder setOemManaged(int);
-    method @NonNull public android.net.NetworkIdentity.Builder setRatType(int);
-    method @NonNull public android.net.NetworkIdentity.Builder setRoaming(boolean);
-    method @NonNull public android.net.NetworkIdentity.Builder setSubscriberId(@Nullable String);
-    method @NonNull public android.net.NetworkIdentity.Builder setType(int);
-    method @NonNull public android.net.NetworkIdentity.Builder setWifiNetworkKey(@Nullable String);
-  }
-
   public class NetworkPolicyManager {
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getMultipathPreference(@NonNull android.net.Network);
     method @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public int getRestrictBackgroundStatus(int);
@@ -279,94 +228,6 @@
     method public default void onUidBlockedReasonChanged(int, int);
   }
 
-  public final class NetworkStateSnapshot implements android.os.Parcelable {
-    ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int);
-    method public int describeContents();
-    method public int getLegacyType();
-    method @NonNull public android.net.LinkProperties getLinkProperties();
-    method @NonNull public android.net.Network getNetwork();
-    method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
-    method @Nullable public String getSubscriberId();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStateSnapshot> CREATOR;
-  }
-
-  public class NetworkStatsCollection {
-    method @NonNull public java.util.Map<android.net.NetworkStatsCollection.Key,android.net.NetworkStatsHistory> getEntries();
-  }
-
-  public static final class NetworkStatsCollection.Builder {
-    ctor public NetworkStatsCollection.Builder(long);
-    method @NonNull public android.net.NetworkStatsCollection.Builder addEntry(@NonNull android.net.NetworkStatsCollection.Key, @NonNull android.net.NetworkStatsHistory);
-    method @NonNull public android.net.NetworkStatsCollection build();
-  }
-
-  public static class NetworkStatsCollection.Key {
-    ctor public NetworkStatsCollection.Key(@NonNull java.util.Set<android.net.NetworkIdentity>, int, int, int);
-  }
-
-  public final class NetworkStatsHistory implements android.os.Parcelable {
-    method public int describeContents();
-    method @NonNull public java.util.List<android.net.NetworkStatsHistory.Entry> getEntries();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStatsHistory> CREATOR;
-  }
-
-  public static final class NetworkStatsHistory.Builder {
-    ctor public NetworkStatsHistory.Builder(long, int);
-    method @NonNull public android.net.NetworkStatsHistory.Builder addEntry(@NonNull android.net.NetworkStatsHistory.Entry);
-    method @NonNull public android.net.NetworkStatsHistory build();
-  }
-
-  public static final class NetworkStatsHistory.Entry {
-    ctor public NetworkStatsHistory.Entry(long, long, long, long, long, long, long);
-    method public long getActiveTime();
-    method public long getBucketStart();
-    method public long getOperations();
-    method public long getRxBytes();
-    method public long getRxPackets();
-    method public long getTxBytes();
-    method public long getTxPackets();
-  }
-
-  public final class NetworkTemplate implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getDefaultNetworkStatus();
-    method public int getMatchRule();
-    method public int getMeteredness();
-    method public int getOemManaged();
-    method public int getRatType();
-    method public int getRoaming();
-    method @NonNull public java.util.Set<java.lang.String> getSubscriberIds();
-    method @NonNull public java.util.Set<java.lang.String> getWifiNetworkKeys();
-    method public boolean matches(@NonNull android.net.NetworkIdentity);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkTemplate> CREATOR;
-    field public static final int MATCH_BLUETOOTH = 8; // 0x8
-    field public static final int MATCH_CARRIER = 10; // 0xa
-    field public static final int MATCH_ETHERNET = 5; // 0x5
-    field public static final int MATCH_MOBILE = 1; // 0x1
-    field public static final int MATCH_WIFI = 4; // 0x4
-    field public static final int NETWORK_TYPE_ALL = -1; // 0xffffffff
-    field public static final int OEM_MANAGED_ALL = -1; // 0xffffffff
-    field public static final int OEM_MANAGED_NO = 0; // 0x0
-    field public static final int OEM_MANAGED_PAID = 1; // 0x1
-    field public static final int OEM_MANAGED_PRIVATE = 2; // 0x2
-    field public static final int OEM_MANAGED_YES = -2; // 0xfffffffe
-  }
-
-  public static final class NetworkTemplate.Builder {
-    ctor public NetworkTemplate.Builder(int);
-    method @NonNull public android.net.NetworkTemplate build();
-    method @NonNull public android.net.NetworkTemplate.Builder setDefaultNetworkStatus(int);
-    method @NonNull public android.net.NetworkTemplate.Builder setMeteredness(int);
-    method @NonNull public android.net.NetworkTemplate.Builder setOemManaged(int);
-    method @NonNull public android.net.NetworkTemplate.Builder setRatType(int);
-    method @NonNull public android.net.NetworkTemplate.Builder setRoaming(int);
-    method @NonNull public android.net.NetworkTemplate.Builder setSubscriberIds(@NonNull java.util.Set<java.lang.String>);
-    method @NonNull public android.net.NetworkTemplate.Builder setWifiNetworkKeys(@NonNull java.util.Set<java.lang.String>);
-  }
-
   public class NetworkWatchlistManager {
     method @Nullable public byte[] getWatchlistConfigHash();
   }
@@ -385,21 +246,6 @@
     method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo);
   }
 
-  public class TrafficStats {
-    method public static void attachSocketTagger();
-    method public static void init(@NonNull android.content.Context);
-  }
-
-  public final class UnderlyingNetworkInfo implements android.os.Parcelable {
-    ctor public UnderlyingNetworkInfo(int, @NonNull String, @NonNull java.util.List<java.lang.String>);
-    method public int describeContents();
-    method @NonNull public String getInterface();
-    method public int getOwnerUid();
-    method @NonNull public java.util.List<java.lang.String> getUnderlyingInterfaces();
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.UnderlyingNetworkInfo> CREATOR;
-  }
-
   public class VpnManager {
     field public static final int TYPE_VPN_LEGACY = 3; // 0x3
     field public static final int TYPE_VPN_NONE = -1; // 0xffffffff
diff --git a/core/api/removed.txt b/core/api/removed.txt
index bf86422..32a4673 100644
--- a/core/api/removed.txt
+++ b/core/api/removed.txt
@@ -260,10 +260,6 @@
     method @Deprecated public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache);
   }
 
-  public class TrafficStats {
-    method @Deprecated public static void setThreadStatsUidSelf();
-  }
-
 }
 
 package android.os {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 5c6076b..9db26bd 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -1852,13 +1852,6 @@
     field public static final String SERVICE_INTERFACE = "android.app.usage.CacheQuotaService";
   }
 
-  public class NetworkStatsManager {
-    method @NonNull @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public android.net.NetworkStats getMobileUidStats();
-    method @NonNull @RequiresPermission(android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK) public android.net.NetworkStats getWifiUidStats();
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void registerNetworkStatsProvider(@NonNull String, @NonNull android.net.netstats.provider.NetworkStatsProvider);
-    method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_STATS_PROVIDER, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void unregisterNetworkStatsProvider(@NonNull android.net.netstats.provider.NetworkStatsProvider);
-  }
-
   public static final class UsageEvents.Event {
     method public int getInstanceId();
     method @Nullable public String getNotificationChannelId();
@@ -7046,14 +7039,21 @@
   }
 
   public final class EthernetNetworkUpdateRequest implements android.os.Parcelable {
-    ctor public EthernetNetworkUpdateRequest(@NonNull android.net.StaticIpConfiguration, @NonNull android.net.NetworkCapabilities);
     method public int describeContents();
-    method @NonNull public android.net.StaticIpConfiguration getIpConfig();
+    method @NonNull public android.net.IpConfiguration getIpConfiguration();
     method @NonNull public android.net.NetworkCapabilities getNetworkCapabilities();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.net.EthernetNetworkUpdateRequest> CREATOR;
   }
 
+  public static final class EthernetNetworkUpdateRequest.Builder {
+    ctor public EthernetNetworkUpdateRequest.Builder();
+    ctor public EthernetNetworkUpdateRequest.Builder(@NonNull android.net.EthernetNetworkUpdateRequest);
+    method @NonNull public android.net.EthernetNetworkUpdateRequest build();
+    method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setIpConfiguration(@NonNull android.net.IpConfiguration);
+    method @NonNull public android.net.EthernetNetworkUpdateRequest.Builder setNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
+  }
+
   public final class MatchAllNetworkSpecifier extends android.net.NetworkSpecifier implements android.os.Parcelable {
     ctor public MatchAllNetworkSpecifier();
     method public int describeContents();
@@ -7115,48 +7115,6 @@
     field public static final String PERMISSION_MAINLINE_NETWORK_STACK = "android.permission.MAINLINE_NETWORK_STACK";
   }
 
-  public final class NetworkStats implements java.lang.Iterable<android.net.NetworkStats.Entry> android.os.Parcelable {
-    ctor public NetworkStats(long, int);
-    method @NonNull public android.net.NetworkStats add(@NonNull android.net.NetworkStats);
-    method @NonNull public android.net.NetworkStats addEntry(@NonNull android.net.NetworkStats.Entry);
-    method public int describeContents();
-    method @NonNull public java.util.Iterator<android.net.NetworkStats.Entry> iterator();
-    method @NonNull public android.net.NetworkStats subtract(@NonNull android.net.NetworkStats);
-    method public void writeToParcel(@NonNull android.os.Parcel, int);
-    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStats> CREATOR;
-    field public static final int DEFAULT_NETWORK_ALL = -1; // 0xffffffff
-    field public static final int DEFAULT_NETWORK_NO = 0; // 0x0
-    field public static final int DEFAULT_NETWORK_YES = 1; // 0x1
-    field public static final String IFACE_VT = "vt_data0";
-    field public static final int METERED_ALL = -1; // 0xffffffff
-    field public static final int METERED_NO = 0; // 0x0
-    field public static final int METERED_YES = 1; // 0x1
-    field public static final int ROAMING_ALL = -1; // 0xffffffff
-    field public static final int ROAMING_NO = 0; // 0x0
-    field public static final int ROAMING_YES = 1; // 0x1
-    field public static final int SET_ALL = -1; // 0xffffffff
-    field public static final int SET_DEFAULT = 0; // 0x0
-    field public static final int SET_FOREGROUND = 1; // 0x1
-    field public static final int TAG_NONE = 0; // 0x0
-    field public static final int UID_ALL = -1; // 0xffffffff
-    field public static final int UID_TETHERING = -5; // 0xfffffffb
-  }
-
-  public static class NetworkStats.Entry {
-    ctor public NetworkStats.Entry(@Nullable String, int, int, int, int, int, int, long, long, long, long, long);
-    method public int getDefaultNetwork();
-    method public int getMetered();
-    method public long getOperations();
-    method public int getRoaming();
-    method public long getRxBytes();
-    method public long getRxPackets();
-    method public int getSet();
-    method public int getTag();
-    method public long getTxBytes();
-    method public long getTxPackets();
-    method public int getUid();
-  }
-
   public class RssiCurve implements android.os.Parcelable {
     ctor public RssiCurve(int, int, byte[]);
     ctor public RssiCurve(int, int, byte[], int);
@@ -7188,19 +7146,6 @@
     field public final android.net.RssiCurve rssiCurve;
   }
 
-  public class TrafficStats {
-    method public static void setThreadStatsTagApp();
-    method public static void setThreadStatsTagBackup();
-    method public static void setThreadStatsTagDownload();
-    method public static void setThreadStatsTagRestore();
-    field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_END = -113; // 0xffffff8f
-    field public static final int TAG_NETWORK_STACK_IMPERSONATION_RANGE_START = -128; // 0xffffff80
-    field public static final int TAG_NETWORK_STACK_RANGE_END = -257; // 0xfffffeff
-    field public static final int TAG_NETWORK_STACK_RANGE_START = -768; // 0xfffffd00
-    field public static final int TAG_SYSTEM_IMPERSONATION_RANGE_END = -241; // 0xffffff0f
-    field public static final int TAG_SYSTEM_IMPERSONATION_RANGE_START = -256; // 0xffffff00
-  }
-
   public abstract class Uri implements java.lang.Comparable<android.net.Uri> android.os.Parcelable {
     method @NonNull public String toSafeString();
   }
@@ -7381,23 +7326,6 @@
 
 }
 
-package android.net.netstats.provider {
-
-  public abstract class NetworkStatsProvider {
-    ctor public NetworkStatsProvider();
-    method public void notifyAlertReached();
-    method public void notifyLimitReached();
-    method public void notifyStatsUpdated(int, @NonNull android.net.NetworkStats, @NonNull android.net.NetworkStats);
-    method public void notifyWarningReached();
-    method public abstract void onRequestStatsUpdate(int);
-    method public abstract void onSetAlert(long);
-    method public abstract void onSetLimit(@NonNull String, long);
-    method public void onSetWarningAndLimit(@NonNull String, long, long);
-    field public static final int QUOTA_UNLIMITED = -1; // 0xffffffff
-  }
-
-}
-
 package android.net.sip {
 
   @Deprecated public class SipAudioCall {
@@ -9006,6 +8934,7 @@
     field public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS = "android.settings.SHOW_ADMIN_SUPPORT_DETAILS";
     field public static final String ACTION_TETHER_PROVISIONING_UI = "android.settings.TETHER_PROVISIONING_UI";
     field public static final String ACTION_TETHER_SETTINGS = "android.settings.TETHER_SETTINGS";
+    field public static final String ACTION_TETHER_UNSUPPORTED_CARRIER_UI = "android.settings.TETHER_UNSUPPORTED_CARRIER_UI";
   }
 
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index a0b3580..73caa5d 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -635,10 +635,6 @@
 
 package android.app.usage {
 
-  public class NetworkStatsManager {
-    method public void setPollForce(boolean);
-  }
-
   public class StorageStatsManager {
     method public boolean isQuotaSupported(@NonNull java.util.UUID);
     method public boolean isReservedSupported(@NonNull java.util.UUID);
@@ -1589,13 +1585,6 @@
     method @Nullable public byte[] getWatchlistConfigHash();
   }
 
-  public class TrafficStats {
-    method public static long getLoopbackRxBytes();
-    method public static long getLoopbackRxPackets();
-    method public static long getLoopbackTxBytes();
-    method public static long getLoopbackTxPackets();
-  }
-
 }
 
 package android.os {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 3766dc8..6a0a289 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -44,7 +44,6 @@
 import android.app.trust.TrustManager;
 import android.app.usage.IStorageStatsManager;
 import android.app.usage.IUsageStatsManager;
-import android.app.usage.NetworkStatsManager;
 import android.app.usage.StorageStatsManager;
 import android.app.usage.UsageStatsManager;
 import android.apphibernation.AppHibernationManager;
@@ -129,7 +128,6 @@
 import android.net.EthernetManager;
 import android.net.IEthernetManager;
 import android.net.INetworkPolicyManager;
-import android.net.INetworkStatsService;
 import android.net.IPacProxyManager;
 import android.net.IVpnManager;
 import android.net.NetworkPolicyManager;
@@ -967,17 +965,6 @@
                 return new UsageStatsManager(ctx.getOuterContext(), service);
             }});
 
-        registerService(Context.NETWORK_STATS_SERVICE, NetworkStatsManager.class,
-                new CachedServiceFetcher<NetworkStatsManager>() {
-            @Override
-            public NetworkStatsManager createService(ContextImpl ctx) throws ServiceNotFoundException {
-                // TODO: Replace with an initializer in the module, see
-                //  {@code ConnectivityFrameworkInitializer}.
-                final INetworkStatsService service = INetworkStatsService.Stub.asInterface(
-                        ServiceManager.getServiceOrThrow(Context.NETWORK_STATS_SERVICE));
-                return new NetworkStatsManager(ctx.getOuterContext(), service);
-            }});
-
         registerService(Context.PERSISTENT_DATA_BLOCK_SERVICE, PersistentDataBlockManager.class,
                 new StaticServiceFetcher<PersistentDataBlockManager>() {
             @Override
diff --git a/core/java/android/app/time/ExternalTimeSuggestion.java b/core/java/android/app/time/ExternalTimeSuggestion.java
index 8e281c0..a7c0e5c 100644
--- a/core/java/android/app/time/ExternalTimeSuggestion.java
+++ b/core/java/android/app/time/ExternalTimeSuggestion.java
@@ -50,16 +50,17 @@
  * <p>The creator of an external suggestion is expected to be separate Android process, e.g. a
  * process integrating with the external time source via a HAL or local network. The creator must
  * capture the elapsed realtime reference clock, e.g. via {@link SystemClock#elapsedRealtime()},
- * when the UTC time is first obtained (usually under a wakelock). This enables Android to adjust
- * for latency introduced between suggestion creation and eventual use. Adjustments for other
+ * when the Unix epoch time is first obtained (usually under a wakelock). This enables Android to
+ * adjust for latency introduced between suggestion creation and eventual use. Adjustments for other
  * sources of latency, i.e. those before the external time suggestion is created, must be handled by
  * the creator.
  *
  * <p>{@code elapsedRealtimeMillis} and {@code suggestionMillis} represent the suggested time.
- * {@code suggestionMillis} is the number of milliseconds elapsed since 1/1/1970 00:00:00 UTC.
- * {@code elapsedRealtimeMillis} is the value of the elapsed realtime clock when {@code
- * suggestionMillis} was established. Note that the elapsed realtime clock is considered accurate
- * but it is volatile, so time suggestions cannot be persisted across device resets.
+ * {@code suggestionMillis} is the number of milliseconds elapsed since 1/1/1970 00:00:00 UTC
+ * according to the Unix time scale. {@code elapsedRealtimeMillis} is the value of the elapsed
+ * realtime clock when {@code suggestionMillis} was established. Note that the elapsed realtime
+ * clock is considered accurate but it is volatile, so time suggestions cannot be persisted across
+ * device resets.
  *
  * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
  * record why the suggestion exists and how it was entered. This information exists only to aid in
@@ -83,7 +84,7 @@
             };
 
     @NonNull
-    private final TimestampedValue<Long> mUtcTime;
+    private final TimestampedValue<Long> mUnixEpochTime;
     @Nullable
     private ArrayList<String> mDebugInfo;
 
@@ -92,12 +93,12 @@
      * ExternalTimeSuggestion} for more details.
      *
      * @param elapsedRealtimeMillis the elapsed realtime clock reference for the suggestion
-     * @param suggestionMillis      the suggested UTC time in milliseconds since the start of the
+     * @param suggestionMillis      the suggested time in milliseconds since the start of the
      *                              Unix epoch
      */
     public ExternalTimeSuggestion(@ElapsedRealtimeLong long elapsedRealtimeMillis,
             @CurrentTimeMillisLong long suggestionMillis) {
-        mUtcTime = new TimestampedValue(elapsedRealtimeMillis, suggestionMillis);
+        mUnixEpochTime = new TimestampedValue(elapsedRealtimeMillis, suggestionMillis);
     }
 
     private static ExternalTimeSuggestion createFromParcel(Parcel in) {
@@ -117,7 +118,7 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mUtcTime, 0);
+        dest.writeParcelable(mUnixEpochTime, 0);
         dest.writeList(mDebugInfo);
     }
 
@@ -125,8 +126,8 @@
      * {@hide}
      */
     @NonNull
-    public TimestampedValue<Long> getUtcTime() {
-        return mUtcTime;
+    public TimestampedValue<Long> getUnixEpochTime() {
+        return mUnixEpochTime;
     }
 
     /**
@@ -160,17 +161,18 @@
             return false;
         }
         ExternalTimeSuggestion that = (ExternalTimeSuggestion) o;
-        return Objects.equals(mUtcTime, that.mUtcTime);
+        return Objects.equals(mUnixEpochTime, that.mUnixEpochTime);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mUtcTime);
+        return Objects.hash(mUnixEpochTime);
     }
 
     @Override
     public String toString() {
-        return "ExternalTimeSuggestion{" + "mUtcTime=" + mUtcTime + ", mDebugInfo=" + mDebugInfo
+        return "ExternalTimeSuggestion{" + "mUnixEpochTime=" + mUnixEpochTime
+                + ", mDebugInfo=" + mDebugInfo
                 + '}';
     }
 }
diff --git a/core/java/android/app/timedetector/GnssTimeSuggestion.java b/core/java/android/app/timedetector/GnssTimeSuggestion.java
index 6478a2d..34f4565 100644
--- a/core/java/android/app/timedetector/GnssTimeSuggestion.java
+++ b/core/java/android/app/timedetector/GnssTimeSuggestion.java
@@ -31,11 +31,11 @@
 /**
  * A time signal from a GNSS source.
  *
- * <p>{@code utcTime} is the suggested time. The {@code utcTime.value} is the number of milliseconds
- * elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the value of the
- * elapsed realtime clock when the {@code utcTime.value} was established.
- * Note that the elapsed realtime clock is considered accurate but it is volatile, so time
- * suggestions cannot be persisted across device resets.
+ * <p>{@code unixEpochTime} is the suggested time. The {@code unixEpochTime.value} is the number of
+ * milliseconds elapsed since 1/1/1970 00:00:00 UTC according to the Unix time system. The {@code
+ * unixEpochTime.referenceTimeMillis} is the value of the elapsed realtime clock when the {@code
+ * unixEpochTime.value} was established. Note that the elapsed realtime clock is considered accurate
+ * but it is volatile, so time suggestions cannot be persisted across device resets.
  *
  * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
  * record why the suggestion exists and how it was entered. This information exists only to aid in
@@ -57,17 +57,17 @@
                 }
             };
 
-    @NonNull private final TimestampedValue<Long> mUtcTime;
+    @NonNull private final TimestampedValue<Long> mUnixEpochTime;
     @Nullable private ArrayList<String> mDebugInfo;
 
-    public GnssTimeSuggestion(@NonNull TimestampedValue<Long> utcTime) {
-        mUtcTime = Objects.requireNonNull(utcTime);
-        Objects.requireNonNull(utcTime.getValue());
+    public GnssTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) {
+        mUnixEpochTime = Objects.requireNonNull(unixEpochTime);
+        Objects.requireNonNull(unixEpochTime.getValue());
     }
 
     private static GnssTimeSuggestion createFromParcel(Parcel in) {
-        TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */);
-        GnssTimeSuggestion suggestion = new GnssTimeSuggestion(utcTime);
+        TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */);
+        GnssTimeSuggestion suggestion = new GnssTimeSuggestion(unixEpochTime);
         @SuppressWarnings("unchecked")
         ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
         suggestion.mDebugInfo = debugInfo;
@@ -81,13 +81,13 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mUtcTime, 0);
+        dest.writeParcelable(mUnixEpochTime, 0);
         dest.writeList(mDebugInfo);
     }
 
     @NonNull
-    public TimestampedValue<Long> getUtcTime() {
-        return mUtcTime;
+    public TimestampedValue<Long> getUnixEpochTime() {
+        return mUnixEpochTime;
     }
 
     @NonNull
@@ -117,18 +117,18 @@
             return false;
         }
         GnssTimeSuggestion that = (GnssTimeSuggestion) o;
-        return Objects.equals(mUtcTime, that.mUtcTime);
+        return Objects.equals(mUnixEpochTime, that.mUnixEpochTime);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mUtcTime);
+        return Objects.hash(mUnixEpochTime);
     }
 
     @Override
     public String toString() {
         return "GnssTimeSuggestion{"
-                + "mUtcTime=" + mUtcTime
+                + "mUnixEpochTime=" + mUnixEpochTime
                 + ", mDebugInfo=" + mDebugInfo
                 + '}';
     }
diff --git a/core/java/android/app/timedetector/ManualTimeSuggestion.java b/core/java/android/app/timedetector/ManualTimeSuggestion.java
index 299e951..76db33b 100644
--- a/core/java/android/app/timedetector/ManualTimeSuggestion.java
+++ b/core/java/android/app/timedetector/ManualTimeSuggestion.java
@@ -31,9 +31,9 @@
 /**
  * A time signal from a manual (user provided) source.
  *
- * <p>{@code utcTime} is the suggested time. The {@code utcTime.value} is the number of milliseconds
- * elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the value of the
- * elapsed realtime clock when the {@code utcTime.value} was established.
+ * <p>{@code unixEpochTime} is the suggested time. The {@code unixEpochTime.value} is the number of
+ * milliseconds elapsed since 1/1/1970 00:00:00 UTC. The {@code unixEpochTime.referenceTimeMillis}
+ * is the value of the elapsed realtime clock when the {@code unixEpochTime.value} was established.
  * Note that the elapsed realtime clock is considered accurate but it is volatile, so time
  * suggestions cannot be persisted across device resets.
  *
@@ -57,17 +57,17 @@
                 }
             };
 
-    @NonNull private final TimestampedValue<Long> mUtcTime;
+    @NonNull private final TimestampedValue<Long> mUnixEpochTime;
     @Nullable private ArrayList<String> mDebugInfo;
 
-    public ManualTimeSuggestion(@NonNull TimestampedValue<Long> utcTime) {
-        mUtcTime = Objects.requireNonNull(utcTime);
-        Objects.requireNonNull(utcTime.getValue());
+    public ManualTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) {
+        mUnixEpochTime = Objects.requireNonNull(unixEpochTime);
+        Objects.requireNonNull(unixEpochTime.getValue());
     }
 
     private static ManualTimeSuggestion createFromParcel(Parcel in) {
-        TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */);
-        ManualTimeSuggestion suggestion = new ManualTimeSuggestion(utcTime);
+        TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */);
+        ManualTimeSuggestion suggestion = new ManualTimeSuggestion(unixEpochTime);
         @SuppressWarnings("unchecked")
         ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
         suggestion.mDebugInfo = debugInfo;
@@ -81,13 +81,13 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mUtcTime, 0);
+        dest.writeParcelable(mUnixEpochTime, 0);
         dest.writeList(mDebugInfo);
     }
 
     @NonNull
-    public TimestampedValue<Long> getUtcTime() {
-        return mUtcTime;
+    public TimestampedValue<Long> getUnixEpochTime() {
+        return mUnixEpochTime;
     }
 
     @NonNull
@@ -117,18 +117,18 @@
             return false;
         }
         ManualTimeSuggestion that = (ManualTimeSuggestion) o;
-        return Objects.equals(mUtcTime, that.mUtcTime);
+        return Objects.equals(mUnixEpochTime, that.mUnixEpochTime);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mUtcTime);
+        return Objects.hash(mUnixEpochTime);
     }
 
     @Override
     public String toString() {
         return "ManualTimeSuggestion{"
-                + "mUtcTime=" + mUtcTime
+                + "mUnixEpochTime=" + mUnixEpochTime
                 + ", mDebugInfo=" + mDebugInfo
                 + '}';
     }
diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.java b/core/java/android/app/timedetector/NetworkTimeSuggestion.java
index a5259c2..e22f1d6e 100644
--- a/core/java/android/app/timedetector/NetworkTimeSuggestion.java
+++ b/core/java/android/app/timedetector/NetworkTimeSuggestion.java
@@ -31,11 +31,12 @@
 /**
  * A time signal from a network time source like NTP.
  *
- * <p>{@code utcTime} contains the suggested time. The {@code utcTime.value} is the number of
- * milliseconds elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the
- * value of the elapsed realtime clock when the {@code utcTime.value} was established.
- * Note that the elapsed realtime clock is considered accurate but it is volatile, so time
- * suggestions cannot be persisted across device resets.
+ * <p>{@code unixEpochTime} contains the suggested time. The {@code unixEpochTime.value} is the
+ * number of milliseconds elapsed since 1/1/1970 00:00:00 UTC according to the Unix time system.
+ * The {@code unixEpochTime.referenceTimeMillis} is the value of the elapsed realtime clock when
+ * the {@code unixEpochTime.value} was established. Note that the elapsed realtime clock is
+ * considered accurate but it is volatile, so time suggestions cannot be persisted across device
+ * resets.
  *
  * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
  * record why the suggestion exists and how it was determined. This information exists only to aid
@@ -57,17 +58,17 @@
                 }
             };
 
-    @NonNull private final TimestampedValue<Long> mUtcTime;
+    @NonNull private final TimestampedValue<Long> mUnixEpochTime;
     @Nullable private ArrayList<String> mDebugInfo;
 
-    public NetworkTimeSuggestion(@NonNull TimestampedValue<Long> utcTime) {
-        mUtcTime = Objects.requireNonNull(utcTime);
-        Objects.requireNonNull(utcTime.getValue());
+    public NetworkTimeSuggestion(@NonNull TimestampedValue<Long> unixEpochTime) {
+        mUnixEpochTime = Objects.requireNonNull(unixEpochTime);
+        Objects.requireNonNull(unixEpochTime.getValue());
     }
 
     private static NetworkTimeSuggestion createFromParcel(Parcel in) {
-        TimestampedValue<Long> utcTime = in.readParcelable(null /* classLoader */);
-        NetworkTimeSuggestion suggestion = new NetworkTimeSuggestion(utcTime);
+        TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */);
+        NetworkTimeSuggestion suggestion = new NetworkTimeSuggestion(unixEpochTime);
         @SuppressWarnings("unchecked")
         ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
         suggestion.mDebugInfo = debugInfo;
@@ -81,13 +82,13 @@
 
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeParcelable(mUtcTime, 0);
+        dest.writeParcelable(mUnixEpochTime, 0);
         dest.writeList(mDebugInfo);
     }
 
     @NonNull
-    public TimestampedValue<Long> getUtcTime() {
-        return mUtcTime;
+    public TimestampedValue<Long> getUnixEpochTime() {
+        return mUnixEpochTime;
     }
 
     @NonNull
@@ -117,18 +118,18 @@
             return false;
         }
         NetworkTimeSuggestion that = (NetworkTimeSuggestion) o;
-        return Objects.equals(mUtcTime, that.mUtcTime);
+        return Objects.equals(mUnixEpochTime, that.mUnixEpochTime);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mUtcTime);
+        return Objects.hash(mUnixEpochTime);
     }
 
     @Override
     public String toString() {
         return "NetworkTimeSuggestion{"
-                + "mUtcTime=" + mUtcTime
+                + "mUnixEpochTime=" + mUnixEpochTime
                 + ", mDebugInfo=" + mDebugInfo
                 + '}';
     }
diff --git a/core/java/android/app/timedetector/TelephonyTimeSuggestion.java b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java
index 6c3a304..4ff7517 100644
--- a/core/java/android/app/timedetector/TelephonyTimeSuggestion.java
+++ b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java
@@ -34,12 +34,12 @@
  * <p>{@code slotIndex} identifies the suggestion source. This enables detection logic to identify
  * suggestions from the same source when there are several in use.
  *
- * <p>{@code utcTime}. When not {@code null}, the {@code utcTime.value} is the number of
- * milliseconds elapsed since 1/1/1970 00:00:00 UTC. The {@code utcTime.referenceTimeMillis} is the
- * value of the elapsed realtime clock when the {@code utcTime.value} was established.
+ * <p>{@code unixEpochTime}. When not {@code null}, the {@code unixEpochTime.value} is the number of
+ * milliseconds elapsed since 1/1/1970 00:00:00 UTC. The {@code unixEpochTime.referenceTimeMillis}
+ * is the value of the elapsed realtime clock when the {@code unixEpochTime.value} was established.
  * Note that the elapsed realtime clock is considered accurate but it is volatile, so time
- * suggestions cannot be persisted across device resets. {@code utcTime} can be {@code null} to
- * indicate that the telephony source has entered an "un-opinionated" state and any previous
+ * suggestions cannot be persisted across device resets. {@code unixEpochTime} can be {@code null}
+ * to indicate that the telephony source has entered an "un-opinionated" state and any previous
  * suggestion from the source is being withdrawn.
  *
  * <p>{@code debugInfo} contains debugging metadata associated with the suggestion. This is used to
@@ -65,19 +65,20 @@
             };
 
     private final int mSlotIndex;
-    @Nullable private final TimestampedValue<Long> mUtcTime;
+    @Nullable private final TimestampedValue<Long> mUnixEpochTime;
     @Nullable private ArrayList<String> mDebugInfo;
 
     private TelephonyTimeSuggestion(Builder builder) {
         mSlotIndex = builder.mSlotIndex;
-        mUtcTime = builder.mUtcTime;
+        mUnixEpochTime = builder.mUnixEpochTime;
         mDebugInfo = builder.mDebugInfo != null ? new ArrayList<>(builder.mDebugInfo) : null;
     }
 
     private static TelephonyTimeSuggestion createFromParcel(Parcel in) {
         int slotIndex = in.readInt();
+        TimestampedValue<Long> unixEpochTime = in.readParcelable(null /* classLoader */);
         TelephonyTimeSuggestion suggestion = new TelephonyTimeSuggestion.Builder(slotIndex)
-                .setUtcTime(in.readParcelable(null /* classLoader */))
+                .setUnixEpochTime(unixEpochTime)
                 .build();
         @SuppressWarnings("unchecked")
         ArrayList<String> debugInfo = (ArrayList<String>) in.readArrayList(null /* classLoader */);
@@ -95,7 +96,7 @@
     @Override
     public void writeToParcel(@NonNull Parcel dest, int flags) {
         dest.writeInt(mSlotIndex);
-        dest.writeParcelable(mUtcTime, 0);
+        dest.writeParcelable(mUnixEpochTime, 0);
         dest.writeList(mDebugInfo);
     }
 
@@ -111,11 +112,11 @@
     /**
      * Returns the suggested time or {@code null} if there isn't one.
      *
-     * <p>See {@link TelephonyTimeSuggestion} for more information about {@code utcTime}.
+     * <p>See {@link TelephonyTimeSuggestion} for more information about {@code unixEpochTime}.
      */
     @Nullable
-    public TimestampedValue<Long> getUtcTime() {
-        return mUtcTime;
+    public TimestampedValue<Long> getUnixEpochTime() {
+        return mUnixEpochTime;
     }
 
     /**
@@ -163,19 +164,19 @@
         }
         TelephonyTimeSuggestion that = (TelephonyTimeSuggestion) o;
         return mSlotIndex == that.mSlotIndex
-                && Objects.equals(mUtcTime, that.mUtcTime);
+                && Objects.equals(mUnixEpochTime, that.mUnixEpochTime);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mSlotIndex, mUtcTime);
+        return Objects.hash(mSlotIndex, mUnixEpochTime);
     }
 
     @Override
     public String toString() {
         return "TelephonyTimeSuggestion{"
                 + "mSlotIndex='" + mSlotIndex + '\''
-                + ", mUtcTime=" + mUtcTime
+                + ", mUnixEpochTime=" + mUnixEpochTime
                 + ", mDebugInfo=" + mDebugInfo
                 + '}';
     }
@@ -187,7 +188,7 @@
      */
     public static final class Builder {
         private final int mSlotIndex;
-        @Nullable private TimestampedValue<Long> mUtcTime;
+        @Nullable private TimestampedValue<Long> mUnixEpochTime;
         @Nullable private List<String> mDebugInfo;
 
         /**
@@ -202,16 +203,16 @@
         /**
          * Returns the builder for call chaining.
          *
-         * <p>See {@link TelephonyTimeSuggestion} for more information about {@code utcTime}.
+         * <p>See {@link TelephonyTimeSuggestion} for more information about {@code unixEpochTime}.
          */
         @NonNull
-        public Builder setUtcTime(@Nullable TimestampedValue<Long> utcTime) {
-            if (utcTime != null) {
-                // utcTime can be null, but the value it holds cannot.
-                Objects.requireNonNull(utcTime.getValue());
+        public Builder setUnixEpochTime(@Nullable TimestampedValue<Long> unixEpochTime) {
+            if (unixEpochTime != null) {
+                // unixEpochTime can be null, but the value it holds cannot.
+                Objects.requireNonNull(unixEpochTime.getValue());
             }
 
-            mUtcTime = utcTime;
+            mUnixEpochTime = unixEpochTime;
             return this;
         }
 
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 001be57..7cb0934 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3480,11 +3480,11 @@
      *          <li>{@link #BIND_INCLUDE_CAPABILITIES}
      *      </ul>
      *
-      * @return {@code true} if the system is in the process of bringing up a
-     *         service that your client has permission to bind to; {@code false}
-     *         if the system couldn't find the service or if your client doesn't
-     *         have permission to bind to it. You should call {@link #unbindService}
-     *         to release the connection even if this method returned {@code false}.
+     * @return {@code true} if the system is in the process of bringing up a
+     *      service that your client has permission to bind to; {@code false}
+     *      if the system couldn't find the service or if your client doesn't
+     *      have permission to bind to it. Regardless of the return value, you
+     *      should later call {@link #unbindService} to release the connection.
      *
      * @throws SecurityException If the caller does not have permission to
      *      access the service or the service cannot be found. Call
@@ -3498,10 +3498,16 @@
             @NonNull ServiceConnection conn, @BindServiceFlags int flags);
 
     /**
-     * Same as {@link #bindService(Intent, ServiceConnection, int)} with executor to control
-     * ServiceConnection callbacks.
+     * Same as {@link #bindService(Intent, ServiceConnection, int)
+     * bindService(Intent, ServiceConnection, int)} with executor to control ServiceConnection
+     * callbacks.
+     *
      * @param executor Callbacks on ServiceConnection will be called on executor. Must use same
      *      instance for the same instance of ServiceConnection.
+     *
+     * @return The result of the binding as described in
+     *      {@link #bindService(Intent, ServiceConnection, int)
+     *      bindService(Intent, ServiceConnection, int)}.
      */
     public boolean bindService(@RequiresPermission @NonNull Intent service,
             @BindServiceFlags int flags, @NonNull @CallbackExecutor Executor executor,
@@ -3527,12 +3533,13 @@
      * @param instanceName Unique identifier for the service instance.  Each unique
      *      name here will result in a different service instance being created.  Identifiers
      *      must only contain ASCII letters, digits, underscores, and periods.
-     * @return Returns success of binding as per {@link #bindService}.
      * @param executor Callbacks on ServiceConnection will be called on executor.
      *      Must use same instance for the same instance of ServiceConnection.
      * @param conn Receives information as the service is started and stopped.
      *      This must be a valid ServiceConnection object; it must not be null.
      *
+     * @return Returns success of binding as per {@link #bindService}.
+     *
      * @throws SecurityException If the caller does not have permission to access the service
      * @throws IllegalArgumentException If the instanceName is invalid.
      *
@@ -3547,8 +3554,7 @@
     }
 
     /**
-     * Binds to a service in the given {@code user} in the same manner as
-     * {@link #bindService(Intent, ServiceConnection, int)}.
+     * Binds to a service in the given {@code user} in the same manner as {@link #bindService}.
      *
      * <p>If the given {@code user} is in the same profile group and the target package is the
      * same as the caller, {@code android.Manifest.permission.INTERACT_ACROSS_PROFILES} is
diff --git a/core/java/android/net/PlatformVpnProfile.java b/core/java/android/net/PlatformVpnProfile.java
index c0fb4cf..6b6f1ca 100644
--- a/core/java/android/net/PlatformVpnProfile.java
+++ b/core/java/android/net/PlatformVpnProfile.java
@@ -100,7 +100,7 @@
      * always gain the {@link NetworkCapabilities#NET_CAPABILITY_VALIDATED} capability
      * immediately after it connects, whether it can reach public Internet destinations or not.
      */
-    public final boolean getRequiresInternetValidation() {
+    public final boolean isInternetValidationRequired() {
         return mRequiresInternetValidation;
     }
 
diff --git a/core/java/android/net/VpnManager.java b/core/java/android/net/VpnManager.java
index 779d931..c51444c 100644
--- a/core/java/android/net/VpnManager.java
+++ b/core/java/android/net/VpnManager.java
@@ -108,7 +108,7 @@
      * <ul>
      *   <li>{@link #EXTRA_SESSION_KEY}, a {@code String} for the session key, as returned by
      *       {@link #startProvisionedVpnProfileSession}.
-     *   <li>{@link #EXTRA_TIMESTAMP}, a long for the timestamp at which the error occurred,
+     *   <li>{@link #EXTRA_TIMESTAMP_MILLIS}, a long for the timestamp at which the error occurred,
      *       in milliseconds since the epoch, as returned by
      *       {@link java.lang.System#currentTimeMillis}.
      *   <li>{@link #EXTRA_UNDERLYING_NETWORK}, a {@link Network} containing the underlying
@@ -196,7 +196,7 @@
      * This is a number of milliseconds since the epoch, suitable to be compared with
      * {@link java.lang.System#currentTimeMillis}.
      */
-    public static final String EXTRA_TIMESTAMP = "android.net.extra.TIMESTAMP";
+    public static final String EXTRA_TIMESTAMP_MILLIS = "android.net.extra.TIMESTAMP_MILLIS";
 
     /**
      * Extra for the error class, as an {@code int}.
diff --git a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
index 9772bde..2dd3aaa1 100644
--- a/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
+++ b/core/java/android/net/netstats/NetworkStatsDataMigrationUtils.java
@@ -24,6 +24,7 @@
 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
 import static android.net.NetworkStats.SET_DEFAULT;
 import static android.net.NetworkStats.TAG_NONE;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
@@ -108,6 +109,7 @@
         static final int VERSION_ADD_METERED = 4;
         static final int VERSION_ADD_DEFAULT_NETWORK = 5;
         static final int VERSION_ADD_OEM_MANAGED_NETWORK = 6;
+        static final int VERSION_ADD_SUB_ID = 7;
     }
 
     /**
@@ -448,6 +450,13 @@
                 oemNetCapabilities = NetworkTemplate.OEM_MANAGED_NO;
             }
 
+            final int subId;
+            if (version >= IdentitySetVersion.VERSION_ADD_SUB_ID) {
+                subId = in.readInt();
+            } else {
+                subId = INVALID_SUBSCRIPTION_ID;
+            }
+
             // Legacy files might contain TYPE_MOBILE_* types which were deprecated in later
             // releases. For backward compatibility, record them as TYPE_MOBILE instead.
             final int collapsedLegacyType = getCollapsedLegacyType(type);
@@ -457,7 +466,8 @@
                     .setWifiNetworkKey(networkId)
                     .setRoaming(roaming).setMetered(metered)
                     .setDefaultNetwork(defaultNetwork)
-                    .setOemManaged(oemNetCapabilities);
+                    .setOemManaged(oemNetCapabilities)
+                    .setSubId(subId);
             if (type == TYPE_MOBILE && ratType != NetworkTemplate.NETWORK_TYPE_ALL) {
                 builder.setRatType(ratType);
             }
@@ -501,10 +511,10 @@
      * This is copied from {@code NetworkStatsCollection#readLegacyUid}.
      * See {@code NetworkStatsService#maybeUpgradeLegacyStatsLocked}.
      *
-     * @param taggedData whether to read tagged data. For legacy uid files, the tagged
-     *                   data was stored in the same binary file with non-tagged data.
-     *                   But in later releases, these data should be kept in different
-     *                   recorders.
+     * @param taggedData whether to read only tagged data (true) or only non-tagged data
+     *                   (false). For legacy uid files, the tagged data was stored in
+     *                   the same binary file with non-tagged data. But in later releases,
+     *                   these data should be kept in different recorders.
      * @hide
      */
     @VisibleForTesting
diff --git a/core/java/android/nfc/cardemulation/CardEmulation.java b/core/java/android/nfc/cardemulation/CardEmulation.java
index 9a780c8..2b34d86 100644
--- a/core/java/android/nfc/cardemulation/CardEmulation.java
+++ b/core/java/android/nfc/cardemulation/CardEmulation.java
@@ -25,6 +25,7 @@
 import android.app.ActivityThread;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.nfc.INfcCardEmulation;
@@ -62,7 +63,9 @@
      * replace the current default service with the service
      * identified with the ComponentName specified in
      * {@link #EXTRA_SERVICE_COMPONENT}, for the category
-     * specified in {@link #EXTRA_CATEGORY}
+     * specified in {@link #EXTRA_CATEGORY}. There is an optional
+     * extra field using {@link Intent#EXTRA_USER} to specify
+     * the {@link UserHandle} of the user that owns the app.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_CHANGE_DEFAULT =
diff --git a/core/java/android/os/BaseBundle.java b/core/java/android/os/BaseBundle.java
index 45812e5..e5dab05 100644
--- a/core/java/android/os/BaseBundle.java
+++ b/core/java/android/os/BaseBundle.java
@@ -1453,7 +1453,7 @@
 
     @SuppressWarnings("unchecked")
     @Nullable
-    <T> ArrayList<T> getArrayList(@Nullable String key, @NonNull Class<T> clazz) {
+    <T> ArrayList<T> getArrayList(@Nullable String key, @NonNull Class<? extends T> clazz) {
         unparcel();
         try {
             return getValue(key, ArrayList.class, requireNonNull(clazz));
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 545ae38..03492aa 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -285,13 +285,20 @@
         public static final String RELEASE = getString("ro.build.version.release");
 
         /**
-         * The version string we show to the user; may be {@link #RELEASE} or
-         * {@link #CODENAME} if not a final release build.
+         * The version string.  May be {@link #RELEASE} or {@link #CODENAME} if
+         * not a final release build.
          */
         @NonNull public static final String RELEASE_OR_CODENAME = getString(
                 "ro.build.version.release_or_codename");
 
         /**
+         * The version string we show to the user; may be {@link #RELEASE} or
+         * a descriptive string if not a final release build.
+         */
+        @NonNull public static final String RELEASE_OR_PREVIEW_DISPLAY = getString(
+                "ro.build.version.release_or_preview_display");
+
+        /**
          * The base OS build the product is based on.
          */
         public static final String BASE_OS = SystemProperties.get("ro.build.version.base_os", "");
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index edbbb59..a19b51b 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -1059,7 +1059,8 @@
     @SuppressLint("NullableCollection")
     @SuppressWarnings("unchecked")
     @Nullable
-    public <T> ArrayList<T> getParcelableArrayList(@Nullable String key, @NonNull Class<T> clazz) {
+    public <T> ArrayList<T> getParcelableArrayList(@Nullable String key,
+            @NonNull Class<? extends T> clazz) {
         // The reason for not using <T extends Parcelable> is because the caller could provide a
         // super class to restrict the children that doesn't implement Parcelable itself while the
         // children do, more details at b/210800751 (same reasoning applies here).
@@ -1107,7 +1108,7 @@
     @SuppressWarnings("unchecked")
     @Nullable
     public <T> SparseArray<T> getSparseParcelableArray(@Nullable String key,
-            @NonNull Class<T> clazz) {
+            @NonNull Class<? extends T> clazz) {
         // The reason for not using <T extends Parcelable> is because the caller could provide a
         // super class to restrict the children that doesn't implement Parcelable itself while the
         // children do, more details at b/210800751 (same reasoning applies here).
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 2ed0bad..2f2f65b 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -101,6 +101,7 @@
     private static final File DIR_ANDROID_EXPAND = getDirectory(ENV_ANDROID_EXPAND, "/mnt/expand");
     private static final File DIR_ANDROID_STORAGE = getDirectory(ENV_ANDROID_STORAGE, "/storage");
     private static final File DIR_DOWNLOAD_CACHE = getDirectory(ENV_DOWNLOAD_CACHE, "/cache");
+    private static final File DIR_METADATA = new File("/metadata");
     private static final File DIR_OEM_ROOT = getDirectory(ENV_OEM_ROOT, "/oem");
     private static final File DIR_ODM_ROOT = getDirectory(ENV_ODM_ROOT, "/odm");
     private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
@@ -1102,6 +1103,15 @@
     }
 
     /**
+     * Return the metadata directory.
+     *
+     * @hide
+     */
+    public static @NonNull File getMetadataDirectory() {
+        return DIR_METADATA;
+    }
+
+    /**
      * Unknown storage state, such as when a path isn't backed by known storage
      * media.
      *
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 5d9f2189..8e5ed8f 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -52,6 +52,9 @@
 per-file *Telephony* = file:/telephony/OWNERS
 per-file *Zygote* = file:/ZYGOTE_OWNERS
 
+# Time
+per-file *Clock* = file:/services/core/java/com/android/server/timezonedetector/OWNERS
+
 # RecoverySystem
 per-file *Recovery* = file:/services/core/java/com/android/server/recoverysystem/OWNERS
 
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index d3b35a0..9b03172 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -201,7 +201,7 @@
  * The methods to use are {@link #writeFileDescriptor(FileDescriptor)},
  * {@link #readFileDescriptor()}.
  *
- * <h3>Untyped Containers</h3>
+  * <h3>Parcelable Containers</h3>
  *
  * <p>A final class of methods are for writing and reading standard Java
  * containers of arbitrary types.  These all revolve around the
@@ -213,6 +213,19 @@
  * {@link #writeMap(Map)}, {@link #readMap(Map, ClassLoader)},
  * {@link #writeSparseArray(SparseArray)},
  * {@link #readSparseArray(ClassLoader)}.
+ *
+ * <h3>Restricted Parcelable Containers</h3>
+ *
+ * <p>A final class of methods are for reading standard Java containers of restricted types.
+ * These methods replace methods for reading containers of arbitrary types from previous section
+ * starting from Android {@link Build.VERSION_CODES#TIRAMISU}. The pairing writing methods are
+ * still the same from previous section.
+ * These methods accepts additional {@code clazz} parameters as the required types.
+ * The Restricted Parcelable container methods are {@link #readArray(ClassLoader, Class)},
+ * {@link #readList(List, ClassLoader, Class)},
+ * {@link #readArrayList(ClassLoader, Class)},
+ * {@link #readMap(Map, ClassLoader, Class, Class)},
+ * {@link #readSparseArray(ClassLoader, Class)}.
  */
 public final class Parcel {
 
@@ -3832,7 +3845,7 @@
      */
     @NonNull
     public <T> List<T> readParcelableList(@NonNull List<T> list,
-            @Nullable ClassLoader cl, @NonNull Class<T> clazz) {
+            @Nullable ClassLoader cl, @NonNull Class<? extends T> clazz) {
         Objects.requireNonNull(list);
         Objects.requireNonNull(clazz);
         return readParcelableListInternal(list, cl, clazz);
@@ -3843,7 +3856,7 @@
      */
     @NonNull
     private <T> List<T> readParcelableListInternal(@NonNull List<T> list,
-            @Nullable ClassLoader cl, @Nullable Class<T> clazz) {
+            @Nullable ClassLoader cl, @Nullable Class<? extends T> clazz) {
         final int n = readInt();
         if (n == -1) {
             list.clear();
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 944b717..a3b836a 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -674,10 +674,12 @@
             }
             try {
                 if (!rs.allocateSpaceForUpdate(packageFile)) {
+                    rs.clearBcb();
                     throw new IOException("Failed to allocate space for update "
                             + packageFile.getAbsolutePath());
                 }
             } catch (RemoteException e) {
+                rs.clearBcb();
                 e.rethrowAsRuntimeException();
             }
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d0ef546..e79cc32 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -238,6 +238,20 @@
             "android.settings.TETHER_PROVISIONING_UI";
 
     /**
+     * Activity Action: Show a dialog activity to notify tethering is NOT supported by carrier.
+     *
+     * When {@link android.telephony.CarrierConfigManager#KEY_CARRIER_SUPPORTS_TETHERING_BOOL}
+     * is false, and tethering is started by Settings, this dialog activity will be started to
+     * tell the user that tethering is not supported by carrier.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    @SystemApi
+    public static final String ACTION_TETHER_UNSUPPORTED_CARRIER_UI =
+            "android.settings.TETHER_UNSUPPORTED_CARRIER_UI";
+
+    /**
      * Activity Action: Show settings to allow entering/exiting airplane mode.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 1b26465..b79b3d8 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -3584,6 +3584,23 @@
                 "content://telephony/carriers/enforce_managed");
 
         /**
+         * The {@code content://} style URL for the perferred APN used for internet.
+         *
+         * @hide
+         */
+        public static final Uri PREFERRED_APN_URI = Uri.parse(
+                "content://telephony/carriers/preferapn/subId/");
+
+        /**
+         * The {@code content://} style URL for the perferred APN set id.
+         *
+         * @hide
+         */
+        public static final Uri PREFERRED_APN_SET_URI = Uri.parse(
+                "content://telephony/carriers/preferapnset/subId/");
+
+
+        /**
          * The column name for ENFORCE_MANAGED_URI, indicates whether DPC-owned APNs are enforced.
          * @hide
          */
diff --git a/core/java/android/util/NtpTrustedTime.java b/core/java/android/util/NtpTrustedTime.java
index 4ac3178..aebc5e8 100644
--- a/core/java/android/util/NtpTrustedTime.java
+++ b/core/java/android/util/NtpTrustedTime.java
@@ -33,6 +33,9 @@
 
 import com.android.internal.annotations.GuardedBy;
 
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.time.Instant;
 import java.util.Objects;
 import java.util.function.Supplier;
 
@@ -81,14 +84,23 @@
 
         /** Calculates and returns the age of this result. */
         public long getAgeMillis() {
-            return SystemClock.elapsedRealtime() - mElapsedRealtimeMillis;
+            return getAgeMillis(SystemClock.elapsedRealtime());
+        }
+
+        /**
+         * Calculates and returns the age of this result relative to currentElapsedRealtimeMillis.
+         *
+         * @param currentElapsedRealtimeMillis - reference elapsed real time
+         */
+        public long getAgeMillis(long currentElapsedRealtimeMillis) {
+            return currentElapsedRealtimeMillis - mElapsedRealtimeMillis;
         }
 
         @Override
         public String toString() {
             return "TimeResult{"
-                    + "mTimeMillis=" + mTimeMillis
-                    + ", mElapsedRealtimeMillis=" + mElapsedRealtimeMillis
+                    + "mTimeMillis=" + Instant.ofEpochMilli(mTimeMillis)
+                    + ", mElapsedRealtimeMillis=" + Duration.ofMillis(mElapsedRealtimeMillis)
                     + ", mCertaintyMillis=" + mCertaintyMillis
                     + '}';
         }
@@ -122,6 +134,14 @@
         }
     };
 
+    /** An in-memory config override for use during tests. */
+    @Nullable
+    private String mHostnameForTests;
+
+    /** An in-memory config override for use during tests. */
+    @Nullable
+    private Duration mTimeoutForTests;
+
     // Declared volatile and accessed outside of synchronized blocks to avoid blocking reads during
     // forceRefresh().
     private volatile TimeResult mTimeResult;
@@ -139,12 +159,23 @@
         return sSingleton;
     }
 
+    /**
+     * Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
+     * test value, i.e. so the normal value will be used next time.
+     */
+    public void setServerConfigForTests(@Nullable String hostname, @Nullable Duration timeout) {
+        synchronized (this) {
+            mHostnameForTests = hostname;
+            mTimeoutForTests = timeout;
+        }
+    }
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public boolean forceRefresh() {
         synchronized (this) {
             NtpConnectionInfo connectionInfo = getNtpConnectionInfo();
             if (connectionInfo == null) {
-                // missing server config, so no trusted time available
+                // missing server config, so no NTP time available
                 if (LOGD) Log.d(TAG, "forceRefresh: invalid server config");
                 return false;
             }
@@ -256,6 +287,13 @@
         return mTimeResult;
     }
 
+    /** Clears the last received NTP. Intended for use during tests. */
+    public void clearCachedTimeResult() {
+        synchronized (this) {
+            mTimeResult = null;
+        }
+    }
+
     private static class NtpConnectionInfo {
 
         @NonNull private final String mServer;
@@ -274,6 +312,14 @@
         int getTimeoutMillis() {
             return mTimeoutMillis;
         }
+
+        @Override
+        public String toString() {
+            return "NtpConnectionInfo{"
+                    + "mServer='" + mServer + '\''
+                    + ", mTimeoutMillis=" + mTimeoutMillis
+                    + '}';
+        }
     }
 
     @GuardedBy("this")
@@ -281,17 +327,41 @@
         final ContentResolver resolver = mContext.getContentResolver();
 
         final Resources res = mContext.getResources();
-        final String defaultServer = res.getString(
-                com.android.internal.R.string.config_ntpServer);
-        final int defaultTimeoutMillis = res.getInteger(
-                com.android.internal.R.integer.config_ntpTimeout);
 
-        final String secureServer = Settings.Global.getString(
-                resolver, Settings.Global.NTP_SERVER);
-        final int timeoutMillis = Settings.Global.getInt(
-                resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
+        final String hostname;
+        if (mHostnameForTests != null) {
+            hostname = mHostnameForTests;
+        } else {
+            String serverGlobalSetting =
+                    Settings.Global.getString(resolver, Settings.Global.NTP_SERVER);
+            if (serverGlobalSetting != null) {
+                hostname = serverGlobalSetting;
+            } else {
+                hostname = res.getString(com.android.internal.R.string.config_ntpServer);
+            }
+        }
 
-        final String server = secureServer != null ? secureServer : defaultServer;
-        return TextUtils.isEmpty(server) ? null : new NtpConnectionInfo(server, timeoutMillis);
+        final int timeoutMillis;
+        if (mTimeoutForTests != null) {
+            timeoutMillis = (int) mTimeoutForTests.toMillis();
+        } else {
+            int defaultTimeoutMillis =
+                    res.getInteger(com.android.internal.R.integer.config_ntpTimeout);
+            timeoutMillis = Settings.Global.getInt(
+                    resolver, Settings.Global.NTP_TIMEOUT, defaultTimeoutMillis);
+        }
+        return TextUtils.isEmpty(hostname) ? null : new NtpConnectionInfo(hostname, timeoutMillis);
+    }
+
+    /** Prints debug information. */
+    public void dump(PrintWriter pw) {
+        synchronized (this) {
+            pw.println("getNtpConnectionInfo()=" + getNtpConnectionInfo());
+            pw.println("mTimeResult=" + mTimeResult);
+            if (mTimeResult != null) {
+                pw.println("mTimeResult.getAgeMillis()="
+                        + Duration.ofMillis(mTimeResult.getAgeMillis()));
+            }
+        }
     }
 }
diff --git a/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java b/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java
index 615e4b79..a03bac4 100644
--- a/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java
+++ b/core/java/com/android/internal/os/SystemServerClassLoaderFactory.java
@@ -29,22 +29,66 @@
     private static final ArrayMap<String, PathClassLoader> sLoadedPaths = new ArrayMap<>();
 
     /**
-     * Creates and caches a ClassLoader for the jar at the given path, or returns a cached
-     * ClassLoader if it exists.
+     * Creates and caches a ClassLoader for the jar at the given path.
+     *
+     * This method should only be called by ZygoteInit to prefetch jars. For other users, use
+     * {@link getOrCreateClassLoader} instead.
      *
      * The parent class loader should always be the system server class loader. Changing it has
      * implications that require discussion with the mainline team.
      *
      * @hide for internal use only
      */
-    public static PathClassLoader getOrCreateClassLoader(String path, ClassLoader parent) {
-        PathClassLoader pathClassLoader = sLoadedPaths.get(path);
-        if (pathClassLoader == null) {
-            pathClassLoader = (PathClassLoader) ClassLoaderFactory.createClassLoader(
-                    path, /*librarySearchPath=*/null, /*libraryPermittedPath=*/null, parent,
-                    Build.VERSION.SDK_INT, /*isNamespaceShared=*/true , /*classLoaderName=*/null);
-            sLoadedPaths.put(path, pathClassLoader);
+    /* package */ static PathClassLoader createClassLoader(String path, ClassLoader parent) {
+        if (sLoadedPaths.containsKey(path)) {
+            throw new IllegalStateException("A ClassLoader for " + path + " already exists");
         }
+        PathClassLoader pathClassLoader = (PathClassLoader) ClassLoaderFactory.createClassLoader(
+                path, /*librarySearchPath=*/null, /*libraryPermittedPath=*/null, parent,
+                Build.VERSION.SDK_INT, /*isNamespaceShared=*/true , /*classLoaderName=*/null);
+        sLoadedPaths.put(path, pathClassLoader);
         return pathClassLoader;
     }
+
+    /**
+     * Returns a cached ClassLoader to be used at runtime for the jar at the given path. Or, creates
+     * one if it is not prefetched and is allowed to be created at runtime.
+     *
+     * The parent class loader should always be the system server class loader. Changing it has
+     * implications that require discussion with the mainline team.
+     *
+     * @hide for internal use only
+     */
+    public static PathClassLoader getOrCreateClassLoader(
+            String path, ClassLoader parent, boolean isTestOnly) {
+        PathClassLoader pathClassLoader = sLoadedPaths.get(path);
+        if (pathClassLoader != null) {
+            return pathClassLoader;
+        }
+        if (!allowClassLoaderCreation(path, isTestOnly)) {
+            throw new RuntimeException("Creating a ClassLoader from " + path + " is not allowed. "
+                    + "Please make sure that the jar is listed in "
+                    + "`PRODUCT_APEX_STANDALONE_SYSTEM_SERVER_JARS` in the Makefile and added as a "
+                    + "`standalone_contents` of a `systemserverclasspath_fragment` in "
+                    + "`Android.bp`.");
+        }
+        return createClassLoader(path, parent);
+    }
+
+    /**
+     * Returns whether a class loader for the jar is allowed to be created at runtime.
+     */
+    private static boolean allowClassLoaderCreation(String path, boolean isTestOnly) {
+        // Currently, we only enforce prefetching for APEX jars.
+        if (!path.startsWith("/apex/")) {
+            return true;
+        }
+        // APEXes for testing only are okay to ignore.
+        if (isTestOnly) {
+            return true;
+        }
+        return false;
+    }
+
+
 }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index f258f84..e5e6949 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -586,7 +586,7 @@
         }
         for (String jar : envStr.split(":")) {
             try {
-                SystemServerClassLoaderFactory.getOrCreateClassLoader(
+                SystemServerClassLoaderFactory.createClassLoader(
                         jar, getOrCreateSystemServerClassLoader());
             } catch (Error e) {
                 // We don't want the process to crash for this error because prefetching is just an
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index ae9d716..fb0b7fd 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -112,17 +112,74 @@
         public final String name;
         public final String filename;
         public final String[] dependencies;
+
+        /**
+         * SDK version this library was added to the BOOTCLASSPATH.
+         *
+         * <p>At the SDK level specified in this field and higher, the apps' uses-library tags for
+         * this library will be ignored, since the library is always available on BOOTCLASSPATH.
+         *
+         * <p>0 means not specified.
+         */
+        public final int onBootclasspathSince;
+
+        /**
+         * SDK version this library was removed from the BOOTCLASSPATH.
+         *
+         * <p>At the SDK level specified in this field and higher, this library needs to be
+         * explicitly added by apps. For compatibility reasons, when an app
+         * targets an SDK less than the value of this attribute, this library is automatically
+         * added.
+         *
+         * <p>0 means not specified.
+         */
+        public final int onBootclasspathBefore;
+
+        /**
+         * Declares whether this library can be safely ignored from <uses-library> tags.
+         *
+         * <p> This can happen if the library initially had to be explicitly depended-on using that
+         * tag but has since been moved to the BOOTCLASSPATH which means now is always available
+         * and the tag is no longer required.
+         */
+        public final boolean canBeSafelyIgnored;
+
         public final boolean isNative;
 
-        SharedLibraryEntry(String name, String filename, String[] dependencies) {
-            this(name, filename, dependencies, false /* isNative */);
+
+        @VisibleForTesting
+        public SharedLibraryEntry(String name, String filename, String[] dependencies,
+                boolean isNative) {
+            this(name, filename, dependencies, 0 /* onBootclasspathSince */,
+                    0 /* onBootclasspathBefore */, isNative);
         }
 
-        SharedLibraryEntry(String name, String filename, String[] dependencies, boolean isNative) {
+        @VisibleForTesting
+        public SharedLibraryEntry(String name, String filename, String[] dependencies,
+                int onBootclasspathSince, int onBootclassPathBefore) {
+            this(name, filename, dependencies, onBootclasspathSince, onBootclassPathBefore,
+                    false /* isNative */);
+        }
+
+        SharedLibraryEntry(String name, String filename, String[] dependencies,
+                int onBootclasspathSince, int onBootclasspathBefore, boolean isNative) {
             this.name = name;
             this.filename = filename;
             this.dependencies = dependencies;
+            this.onBootclasspathSince = onBootclasspathSince;
+            this.onBootclasspathBefore = onBootclasspathBefore;
             this.isNative = isNative;
+
+            canBeSafelyIgnored = this.onBootclasspathSince != 0
+                    && isSdkAtLeast(this.onBootclasspathSince);
+        }
+
+        private static boolean isSdkAtLeast(int level) {
+            if ("REL".equals(Build.VERSION.CODENAME)) {
+                return Build.VERSION.SDK_INT >= level;
+            }
+            return level == Build.VERSION_CODES.CUR_DEVELOPMENT
+                    || Build.VERSION.SDK_INT >= level;
         }
     }
 
@@ -509,12 +566,14 @@
     }
 
     private void readAllPermissions() {
+        final XmlPullParser parser = Xml.newPullParser();
+
         // Read configuration from system
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getRootDirectory(), "etc", "sysconfig"), ALLOW_ALL);
 
         // Read configuration from the old permissions dir
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getRootDirectory(), "etc", "permissions"), ALLOW_ALL);
 
         // Vendors are only allowed to customize these
@@ -524,18 +583,18 @@
             // For backward compatibility
             vendorPermissionFlag |= (ALLOW_PERMISSIONS | ALLOW_APP_CONFIGS);
         }
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getVendorDirectory(), "etc", "sysconfig"), vendorPermissionFlag);
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getVendorDirectory(), "etc", "permissions"), vendorPermissionFlag);
 
         String vendorSkuProperty = SystemProperties.get(VENDOR_SKU_PROPERTY, "");
         if (!vendorSkuProperty.isEmpty()) {
             String vendorSkuDir = "sku_" + vendorSkuProperty;
-            readPermissions(Environment.buildPath(
+            readPermissions(parser, Environment.buildPath(
                     Environment.getVendorDirectory(), "etc", "sysconfig", vendorSkuDir),
                     vendorPermissionFlag);
-            readPermissions(Environment.buildPath(
+            readPermissions(parser, Environment.buildPath(
                     Environment.getVendorDirectory(), "etc", "permissions", vendorSkuDir),
                     vendorPermissionFlag);
         }
@@ -543,18 +602,18 @@
         // Allow ODM to customize system configs as much as Vendor, because /odm is another
         // vendor partition other than /vendor.
         int odmPermissionFlag = vendorPermissionFlag;
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getOdmDirectory(), "etc", "sysconfig"), odmPermissionFlag);
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag);
 
         String skuProperty = SystemProperties.get(SKU_PROPERTY, "");
         if (!skuProperty.isEmpty()) {
             String skuDir = "sku_" + skuProperty;
 
-            readPermissions(Environment.buildPath(
+            readPermissions(parser, Environment.buildPath(
                     Environment.getOdmDirectory(), "etc", "sysconfig", skuDir), odmPermissionFlag);
-            readPermissions(Environment.buildPath(
+            readPermissions(parser, Environment.buildPath(
                     Environment.getOdmDirectory(), "etc", "permissions", skuDir),
                     odmPermissionFlag);
         }
@@ -562,9 +621,9 @@
         // Allow OEM to customize these
         int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS | ALLOW_ASSOCIATIONS
                 | ALLOW_VENDOR_APEX;
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getOemDirectory(), "etc", "sysconfig"), oemPermissionFlag);
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getOemDirectory(), "etc", "permissions"), oemPermissionFlag);
 
         // Allow Product to customize these configs
@@ -579,15 +638,15 @@
             // DEVICE_INITIAL_SDK_INT for the devices without product interface enforcement.
             productPermissionFlag = ALLOW_ALL;
         }
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getProductDirectory(), "etc", "sysconfig"), productPermissionFlag);
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getProductDirectory(), "etc", "permissions"), productPermissionFlag);
 
         // Allow /system_ext to customize all system configs
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getSystemExtDirectory(), "etc", "sysconfig"), ALLOW_ALL);
-        readPermissions(Environment.buildPath(
+        readPermissions(parser, Environment.buildPath(
                 Environment.getSystemExtDirectory(), "etc", "permissions"), ALLOW_ALL);
 
         // Skip loading configuration from apex if it is not a system process.
@@ -601,12 +660,14 @@
             if (f.isFile() || f.getPath().contains("@")) {
                 continue;
             }
-            readPermissions(Environment.buildPath(f, "etc", "permissions"), apexPermissionFlag);
+            readPermissions(parser, Environment.buildPath(f, "etc", "permissions"),
+                    apexPermissionFlag);
         }
+        pruneVendorApexPrivappAllowlists();
     }
 
     @VisibleForTesting
-    public void readPermissions(File libraryDir, int permissionFlag) {
+    public void readPermissions(final XmlPullParser parser, File libraryDir, int permissionFlag) {
         // Read permissions from given directory.
         if (!libraryDir.exists() || !libraryDir.isDirectory()) {
             if (permissionFlag == ALLOW_ALL) {
@@ -641,12 +702,12 @@
                 continue;
             }
 
-            readPermissionsFromXml(f, permissionFlag);
+            readPermissionsFromXml(parser, f, permissionFlag);
         }
 
         // Read platform permissions last so it will take precedence
         if (platformFile != null) {
-            readPermissionsFromXml(platformFile, permissionFlag);
+            readPermissionsFromXml(parser, platformFile, permissionFlag);
         }
     }
 
@@ -655,8 +716,9 @@
                 + permFile + " at " + parser.getPositionDescription());
     }
 
-    private void readPermissionsFromXml(File permFile, int permissionFlag) {
-        FileReader permReader = null;
+    private void readPermissionsFromXml(final XmlPullParser parser, File permFile,
+            int permissionFlag) {
+        final FileReader permReader;
         try {
             permReader = new FileReader(permFile);
         } catch (FileNotFoundException e) {
@@ -668,7 +730,6 @@
         final boolean lowRam = ActivityManager.isLowRamDeviceStatic();
 
         try {
-            XmlPullParser parser = Xml.newPullParser();
             parser.setInput(permReader);
 
             int type;
@@ -789,11 +850,17 @@
                             XmlUtils.skipCurrentTag(parser);
                         }
                     } break;
+                    case "apex-library":
+                        // "apex-library" is meant to behave exactly like "library"
                     case "library": {
                         if (allowLibs) {
                             String lname = parser.getAttributeValue(null, "name");
                             String lfile = parser.getAttributeValue(null, "file");
                             String ldependency = parser.getAttributeValue(null, "dependency");
+                            int minDeviceSdk = XmlUtils.readIntAttribute(parser, "min-device-sdk",
+                                    0);
+                            int maxDeviceSdk = XmlUtils.readIntAttribute(parser, "max-device-sdk",
+                                    0);
                             if (lname == null) {
                                 Slog.w(TAG, "<" + name + "> without name in " + permFile + " at "
                                         + parser.getPositionDescription());
@@ -801,10 +868,34 @@
                                 Slog.w(TAG, "<" + name + "> without file in " + permFile + " at "
                                         + parser.getPositionDescription());
                             } else {
-                                //Log.i(TAG, "Got library " + lname + " in " + lfile);
-                                SharedLibraryEntry entry = new SharedLibraryEntry(lname, lfile,
-                                        ldependency == null ? new String[0] : ldependency.split(":"));
-                                mSharedLibraries.put(lname, entry);
+                                boolean allowedMinSdk = minDeviceSdk <= Build.VERSION.SDK_INT;
+                                boolean allowedMaxSdk =
+                                        maxDeviceSdk == 0 || maxDeviceSdk >= Build.VERSION.SDK_INT;
+                                final boolean exists = new File(lfile).exists();
+                                if (allowedMinSdk && allowedMaxSdk && exists) {
+                                    int bcpSince = XmlUtils.readIntAttribute(parser,
+                                            "on-bootclasspath-since", 0);
+                                    int bcpBefore = XmlUtils.readIntAttribute(parser,
+                                            "on-bootclasspath-before", 0);
+                                    SharedLibraryEntry entry = new SharedLibraryEntry(lname, lfile,
+                                            ldependency == null
+                                                    ? new String[0] : ldependency.split(":"),
+                                            bcpSince, bcpBefore);
+                                    mSharedLibraries.put(lname, entry);
+                                } else {
+                                    final StringBuilder msg = new StringBuilder(
+                                            "Ignore shared library ").append(lname).append(":");
+                                    if (!allowedMinSdk) {
+                                        msg.append(" min-device-sdk=").append(minDeviceSdk);
+                                    }
+                                    if (!allowedMaxSdk) {
+                                        msg.append(" max-device-sdk=").append(maxDeviceSdk);
+                                    }
+                                    if (!exists) {
+                                        msg.append(" ").append(lfile).append(" does not exist");
+                                    }
+                                    Slog.i(TAG, msg.toString());
+                                }
                             }
                         } else {
                             logNotAllowedInPartition(name, permFile, parser);
@@ -1085,7 +1176,8 @@
                                 readPrivAppPermissions(parser, mSystemExtPrivAppPermissions,
                                         mSystemExtPrivAppDenyPermissions);
                             } else if (apex) {
-                                readApexPrivAppPermissions(parser, permFile);
+                                readApexPrivAppPermissions(parser, permFile,
+                                        Environment.getApexDirectory().toPath());
                             } else {
                                 readPrivAppPermissions(parser, mPrivAppPermissions,
                                         mPrivAppDenyPermissions);
@@ -1435,6 +1527,21 @@
         }
     }
 
+    /**
+     * Prunes out any privileged permission allowlists bundled in vendor apexes.
+     */
+    @VisibleForTesting
+    public void pruneVendorApexPrivappAllowlists() {
+        for (String moduleName: mAllowedVendorApexes.keySet()) {
+            if (mApexPrivAppPermissions.containsKey(moduleName)
+                    || mApexPrivAppDenyPermissions.containsKey(moduleName)) {
+                Slog.w(TAG, moduleName + " is a vendor apex, ignore its priv-app allowlist");
+                mApexPrivAppPermissions.remove(moduleName);
+                mApexPrivAppDenyPermissions.remove(moduleName);
+            }
+        }
+    }
+
     private void readInstallInUserType(XmlPullParser parser,
             Map<String, Set<String>> doInstallMap,
             Map<String, Set<String>> nonInstallMap)
@@ -1645,8 +1752,7 @@
     /**
      * Returns the module name for a file in the apex module's partition.
      */
-    private String getApexModuleNameFromFilePath(Path path) {
-        final Path apexDirectoryPath = Environment.getApexDirectory().toPath();
+    private String getApexModuleNameFromFilePath(Path path, Path apexDirectoryPath) {
         if (!path.startsWith(apexDirectoryPath)) {
             throw new IllegalArgumentException("File " + path + " is not part of an APEX.");
         }
@@ -1658,9 +1764,14 @@
         return path.getName(apexDirectoryPath.getNameCount()).toString();
     }
 
-    private void readApexPrivAppPermissions(XmlPullParser parser, File permFile)
-            throws IOException, XmlPullParserException {
-        final String moduleName = getApexModuleNameFromFilePath(permFile.toPath());
+    /**
+     * Reads the contents of the privileged permission allowlist stored inside an APEX.
+     */
+    @VisibleForTesting
+    public void readApexPrivAppPermissions(XmlPullParser parser, File permFile,
+            Path apexDirectoryPath) throws IOException, XmlPullParserException {
+        final String moduleName =
+                getApexModuleNameFromFilePath(permFile.toPath(), apexDirectoryPath);
         final ArrayMap<String, ArraySet<String>> privAppPermissions;
         if (mApexPrivAppPermissions.containsKey(moduleName)) {
             privAppPermissions = mApexPrivAppPermissions.get(moduleName);
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 57a0b48..1d181dd 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -297,8 +297,6 @@
                 "libdl_android",
                 "libtimeinstate",
                 "server_configurable_flags",
-                // TODO: delete when ConnectivityT moves to APEX.
-                "libframework-connectivity-tiramisu-jni",
             ],
             export_shared_lib_headers: [
                 // our headers include libnativewindow's public headers
diff --git a/core/proto/android/service/diskstats.proto b/core/proto/android/service/diskstats.proto
index f79de39..ad3d673 100644
--- a/core/proto/android/service/diskstats.proto
+++ b/core/proto/android/service/diskstats.proto
@@ -99,6 +99,8 @@
         FOLDER_CACHE = 1;
         // System folder
         FOLDER_SYSTEM = 2;
+        // Metadata folder
+        FOLDER_METADATA = 3;
     }
     // Which folder?
     optional Folder folder = 1;
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 590fcf4..ad368a8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1277,6 +1277,8 @@
   <java-symbol type="array" name="vendor_required_apps_managed_user" />
   <java-symbol type="array" name="vendor_required_apps_managed_profile" />
   <java-symbol type="array" name="vendor_required_apps_managed_device" />
+  <java-symbol type="array" name="vendor_required_attestation_certificates" />
+  <java-symbol type="string" name="vendor_required_attestation_revocation_list_url" />
   <java-symbol type="array" name="vendor_disallowed_apps_managed_user" />
   <java-symbol type="array" name="vendor_disallowed_apps_managed_profile" />
   <java-symbol type="array" name="vendor_disallowed_apps_managed_device" />
diff --git a/core/res/res/values/vendor_required_attestation_certificates.xml b/core/res/res/values/vendor_required_attestation_certificates.xml
new file mode 100644
index 0000000..ff7313e
--- /dev/null
+++ b/core/res/res/values/vendor_required_attestation_certificates.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (C) 2022 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.
+ */
+-->
+<resources>
+  <!-- The PEM-encoded certificates added here are used for verifying attestations.
+    The trustworthiness of the attestation depends on the root certificate of the chain.
+
+    Certificates that can be used can be retrieved from:
+    https://developer.android.com/training/articles/security-key-attestation#root_certificate.
+
+    If not already present in resource overlay, please add
+    vendor_required_attestation_certificates.xml (matching this file) in vendor overlay
+    with <item></item> of the PEM-encoded root certificates.
+  -->
+    <string-array translatable="false" name="vendor_required_attestation_certificates">
+    </string-array>
+
+    <!-- Url to mapping of revoked certificates' hex encoded serial numbers. Example format
+      can be found at:
+      https://developer.android.com/training/articles/security-key-attestation#certificate_status
+    -->
+    <string translatable="false" name="vendor_required_attestation_revocation_list_url"></string>
+</resources>
diff --git a/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java b/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java
index 4b64dfc..cc75579 100644
--- a/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java
+++ b/core/tests/coretests/src/android/app/timedetector/TelephonyTimeSuggestionTest.java
@@ -45,13 +45,13 @@
             assertEquals(two, one);
         }
 
-        builder1.setUtcTime(new TimestampedValue<>(1111L, 2222L));
+        builder1.setUnixEpochTime(new TimestampedValue<>(1111L, 2222L));
         {
             TelephonyTimeSuggestion one = builder1.build();
             assertEquals(one, one);
         }
 
-        builder2.setUtcTime(new TimestampedValue<>(1111L, 2222L));
+        builder2.setUnixEpochTime(new TimestampedValue<>(1111L, 2222L));
         {
             TelephonyTimeSuggestion one = builder1.build();
             TelephonyTimeSuggestion two = builder2.build();
@@ -61,7 +61,7 @@
 
         TelephonyTimeSuggestion.Builder builder3 =
                 new TelephonyTimeSuggestion.Builder(SLOT_INDEX + 1);
-        builder3.setUtcTime(new TimestampedValue<>(1111L, 2222L));
+        builder3.setUnixEpochTime(new TimestampedValue<>(1111L, 2222L));
         {
             TelephonyTimeSuggestion one = builder1.build();
             TelephonyTimeSuggestion three = builder3.build();
@@ -84,7 +84,7 @@
         TelephonyTimeSuggestion.Builder builder = new TelephonyTimeSuggestion.Builder(SLOT_INDEX);
         assertRoundTripParcelable(builder.build());
 
-        builder.setUtcTime(new TimestampedValue<>(1111L, 2222L));
+        builder.setUnixEpochTime(new TimestampedValue<>(1111L, 2222L));
         assertRoundTripParcelable(builder.build());
 
         // DebugInfo should also be stored (but is not checked by equals()
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 191d400..82aff60 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -20,13 +20,6 @@
 applications that come with the platform
 -->
 <permissions>
-    <privapp-permissions package="android.ext.services">
-        <permission name="android.permission.PROVIDE_RESOLVER_RANKER_SERVICE" />
-        <permission name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE" />
-        <permission name="android.permission.REQUEST_NOTIFICATION_ASSISTANT_SERVICE" />
-        <permission name="android.permission.INTERACT_ACROSS_USERS" />
-    </privapp-permissions>
-
     <!-- Needed for Build.getSerial(), which is used to send a unique number for serial, per HUIG. -->
     <privapp-permissions package="android.car.usb.handler">
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
@@ -274,6 +267,7 @@
     <privapp-permissions package="com.android.server.telecom">
         <permission name="android.permission.BIND_CONNECTION_SERVICE"/>
         <permission name="android.permission.BIND_INCALL_SERVICE"/>
+        <permission name="android.permission.BLUETOOTH_PRIVILEGED"/>
         <permission name="android.permission.CALL_PRIVILEGED"/>
         <permission name="android.permission.HANDLE_CAR_MODE_CHANGES"/>
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
index 2e85b30..31dd10a 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -66,6 +66,7 @@
 import java.security.UnrecoverableKeyException;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.ECGenParameterSpec;
+import java.security.spec.NamedParameterSpec;
 import java.security.spec.RSAKeyGenParameterSpec;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -119,36 +120,42 @@
     private static final int RSA_MIN_KEY_SIZE = 512;
     private static final int RSA_MAX_KEY_SIZE = 8192;
 
-    private static final Map<String, Integer> SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE =
+    private static final Map<String, Integer> SUPPORTED_EC_CURVE_NAME_TO_SIZE =
             new HashMap<String, Integer>();
-    private static final List<String> SUPPORTED_EC_NIST_CURVE_NAMES = new ArrayList<String>();
-    private static final List<Integer> SUPPORTED_EC_NIST_CURVE_SIZES = new ArrayList<Integer>();
+    private static final List<String> SUPPORTED_EC_CURVE_NAMES = new ArrayList<String>();
+    private static final List<Integer> SUPPORTED_EC_CURVE_SIZES = new ArrayList<Integer>();
+    private static final String CURVE_X_25519 = NamedParameterSpec.X25519.getName();
+    private static final String CURVE_ED_25519 = NamedParameterSpec.ED25519.getName();
+
 
     static {
         // Aliases for NIST P-224
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-224", 224);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp224r1", 224);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("p-224", 224);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("secp224r1", 224);
 
 
         // Aliases for NIST P-256
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-256", 256);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp256r1", 256);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("prime256v1", 256);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("p-256", 256);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("secp256r1", 256);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("prime256v1", 256);
+        // Aliases for Curve 25519
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put(CURVE_X_25519.toLowerCase(Locale.US), 256);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put(CURVE_ED_25519.toLowerCase(Locale.US), 256);
 
         // Aliases for NIST P-384
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-384", 384);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp384r1", 384);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("p-384", 384);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("secp384r1", 384);
 
         // Aliases for NIST P-521
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("p-521", 521);
-        SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.put("secp521r1", 521);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("p-521", 521);
+        SUPPORTED_EC_CURVE_NAME_TO_SIZE.put("secp521r1", 521);
 
-        SUPPORTED_EC_NIST_CURVE_NAMES.addAll(SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.keySet());
-        Collections.sort(SUPPORTED_EC_NIST_CURVE_NAMES);
+        SUPPORTED_EC_CURVE_NAMES.addAll(SUPPORTED_EC_CURVE_NAME_TO_SIZE.keySet());
+        Collections.sort(SUPPORTED_EC_CURVE_NAMES);
 
-        SUPPORTED_EC_NIST_CURVE_SIZES.addAll(
-                new HashSet<Integer>(SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.values()));
-        Collections.sort(SUPPORTED_EC_NIST_CURVE_SIZES);
+        SUPPORTED_EC_CURVE_SIZES.addAll(
+                new HashSet<Integer>(SUPPORTED_EC_CURVE_NAME_TO_SIZE.values()));
+        Collections.sort(SUPPORTED_EC_CURVE_SIZES);
     }
 
     private final int mOriginalKeymasterAlgorithm;
@@ -164,6 +171,7 @@
     private int mKeySizeBits;
     private SecureRandom mRng;
     private KeyDescriptor mAttestKeyDescriptor;
+    private String mEcCurveName;
 
     private int[] mKeymasterPurposes;
     private int[] mKeymasterBlockModes;
@@ -177,12 +185,15 @@
         mOriginalKeymasterAlgorithm = keymasterAlgorithm;
     }
 
-    private @EcCurve int keySize2EcCurve(int keySizeBits)
+    private static @EcCurve int keySizeAndNameToEcCurve(int keySizeBits, String ecCurveName)
             throws InvalidAlgorithmParameterException {
         switch (keySizeBits) {
             case 224:
                 return EcCurve.P_224;
             case 256:
+                if (isCurve25519(ecCurveName)) {
+                    return EcCurve.CURVE_25519;
+                }
                 return EcCurve.P_256;
             case 384:
                 return EcCurve.P_384;
@@ -247,7 +258,8 @@
             if (mKeySizeBits == -1) {
                 mKeySizeBits = getDefaultKeySize(keymasterAlgorithm);
             }
-            checkValidKeySize(keymasterAlgorithm, mKeySizeBits, mSpec.isStrongBoxBacked());
+            checkValidKeySize(keymasterAlgorithm, mKeySizeBits, mSpec.isStrongBoxBacked(),
+                    mEcCurveName);
 
             if (spec.getKeystoreAlias() == null) {
                 throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
@@ -299,6 +311,7 @@
 
             mAttestKeyDescriptor = buildAndCheckAttestKeyDescriptor(spec);
             checkAttestKeyPurpose(spec);
+            checkCorrectKeyPurposeForCurve(spec);
 
             success = true;
         } finally {
@@ -317,6 +330,42 @@
         }
     }
 
+    private void checkCorrectKeyPurposeForCurve(KeyGenParameterSpec spec)
+            throws InvalidAlgorithmParameterException {
+        // Validate the key usage purposes against the curve. x25519 should be
+        // key exchange only, ed25519 signing and attesting.
+
+        if (!isCurve25519(mEcCurveName)) {
+            return;
+        }
+
+        if (mEcCurveName.equalsIgnoreCase(CURVE_X_25519)
+                && spec.getPurposes() != KeyProperties.PURPOSE_AGREE_KEY) {
+            throw new InvalidAlgorithmParameterException(
+                    "x25519 may only be used for key agreement.");
+        } else if (mEcCurveName.equalsIgnoreCase(CURVE_ED_25519)
+                && !hasOnlyAllowedPurposeForEd25519(spec.getPurposes())) {
+            throw new InvalidAlgorithmParameterException(
+                    "ed25519 may not be used for key agreement.");
+        }
+    }
+
+    private static boolean isCurve25519(String ecCurveName) {
+        if (ecCurveName == null) {
+            return false;
+        }
+        return ecCurveName.equalsIgnoreCase(CURVE_X_25519)
+                || ecCurveName.equalsIgnoreCase(CURVE_ED_25519);
+    }
+
+    private static boolean hasOnlyAllowedPurposeForEd25519(@KeyProperties.PurposeEnum int purpose) {
+        final int allowedPurposes = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
+                | KeyProperties.PURPOSE_ATTEST_KEY;
+        boolean hasAllowedPurpose = (purpose & allowedPurposes) != 0;
+        boolean hasDisallowedPurpose = (purpose & ~allowedPurposes) != 0;
+        return hasAllowedPurpose && !hasDisallowedPurpose;
+    }
+
     private KeyDescriptor buildAndCheckAttestKeyDescriptor(KeyGenParameterSpec spec)
             throws InvalidAlgorithmParameterException {
         if (spec.getAttestKeyAlias() != null) {
@@ -473,6 +522,7 @@
         mRSAPublicExponent = null;
         mRng = null;
         mKeyStore = null;
+        mEcCurveName = null;
     }
 
     private void initAlgorithmSpecificParameters() throws InvalidAlgorithmParameterException {
@@ -514,13 +564,13 @@
             case KeymasterDefs.KM_ALGORITHM_EC:
                 if (algSpecificSpec instanceof ECGenParameterSpec) {
                     ECGenParameterSpec ecSpec = (ECGenParameterSpec) algSpecificSpec;
-                    String curveName = ecSpec.getName();
-                    Integer ecSpecKeySizeBits = SUPPORTED_EC_NIST_CURVE_NAME_TO_SIZE.get(
-                            curveName.toLowerCase(Locale.US));
+                    mEcCurveName = ecSpec.getName();
+                    final Integer ecSpecKeySizeBits = SUPPORTED_EC_CURVE_NAME_TO_SIZE.get(
+                            mEcCurveName.toLowerCase(Locale.US));
                     if (ecSpecKeySizeBits == null) {
                         throw new InvalidAlgorithmParameterException(
-                                "Unsupported EC curve name: " + curveName
-                                        + ". Supported: " + SUPPORTED_EC_NIST_CURVE_NAMES);
+                                "Unsupported EC curve name: " + mEcCurveName
+                                        + ". Supported: " + SUPPORTED_EC_CURVE_NAMES);
                     }
                     if (mKeySizeBits == -1) {
                         mKeySizeBits = ecSpecKeySizeBits;
@@ -744,7 +794,7 @@
 
         if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_EC) {
             params.add(KeyStore2ParameterUtils.makeEnum(
-                    Tag.EC_CURVE, keySize2EcCurve(mKeySizeBits)
+                    Tag.EC_CURVE, keySizeAndNameToEcCurve(mKeySizeBits, mEcCurveName)
             ));
         }
 
@@ -864,7 +914,8 @@
     private static void checkValidKeySize(
             int keymasterAlgorithm,
             int keySize,
-            boolean isStrongBoxBacked)
+            boolean isStrongBoxBacked,
+            String mEcCurveName)
             throws InvalidAlgorithmParameterException {
         switch (keymasterAlgorithm) {
             case KeymasterDefs.KM_ALGORITHM_EC:
@@ -873,9 +924,13 @@
                             "Unsupported StrongBox EC key size: "
                                     + keySize + " bits. Supported: 256");
                 }
-                if (!SUPPORTED_EC_NIST_CURVE_SIZES.contains(keySize)) {
+                if (isStrongBoxBacked && isCurve25519(mEcCurveName)) {
+                    throw new InvalidAlgorithmParameterException(
+                            "Unsupported StrongBox EC: " + mEcCurveName);
+                }
+                if (!SUPPORTED_EC_CURVE_SIZES.contains(keySize)) {
                     throw new InvalidAlgorithmParameterException("Unsupported EC key size: "
-                            + keySize + " bits. Supported: " + SUPPORTED_EC_NIST_CURVE_SIZES);
+                            + keySize + " bits. Supported: " + SUPPORTED_EC_CURVE_SIZES);
                 }
                 break;
             case KeymasterDefs.KM_ALGORITHM_RSA:
diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
index 72a145f..358104f 100644
--- a/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
+++ b/keystore/java/android/security/keystore2/AndroidKeyStoreProvider.java
@@ -66,6 +66,11 @@
     private static final String DESEDE_SYSTEM_PROPERTY =
             "ro.hardware.keystore_desede";
 
+    // Conscrypt returns the Ed25519 OID as the JCA key algorithm.
+    private static final String ED25519_OID = "1.3.101.112";
+    // Conscrypt returns "XDH" as the X25519 JCA key algorithm.
+    private static final String X25519_ALIAS = "XDH";
+
     /** @hide **/
     public AndroidKeyStoreProvider() {
         super(PROVIDER_NAME, 1.0, "Android KeyStore security provider");
@@ -78,10 +83,16 @@
         // java.security.KeyPairGenerator
         put("KeyPairGenerator.EC", PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$EC");
         put("KeyPairGenerator.RSA", PACKAGE_NAME +  ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
+        put("KeyPairGenerator." + X25519_ALIAS,
+                PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
+        put("KeyPairGenerator." + ED25519_OID,
+                PACKAGE_NAME + ".AndroidKeyStoreKeyPairGeneratorSpi$RSA");
 
         // java.security.KeyFactory
         putKeyFactoryImpl("EC");
         putKeyFactoryImpl("RSA");
+        putKeyFactoryImpl(X25519_ALIAS);
+        putKeyFactoryImpl(ED25519_OID);
 
         // javax.crypto.KeyGenerator
         put("KeyGenerator.AES", PACKAGE_NAME + ".AndroidKeyStoreKeyGeneratorSpi$AES");
@@ -219,12 +230,17 @@
 
         KeyStoreSecurityLevel securityLevel = iSecurityLevel;
         if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(jcaKeyAlgorithm)) {
-
             return new AndroidKeyStoreECPublicKey(descriptor, metadata,
                     iSecurityLevel, (ECPublicKey) publicKey);
         } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(jcaKeyAlgorithm)) {
             return new AndroidKeyStoreRSAPublicKey(descriptor, metadata,
                     iSecurityLevel, (RSAPublicKey) publicKey);
+        } else if (ED25519_OID.equalsIgnoreCase(jcaKeyAlgorithm)) {
+            //TODO(b/214203951) missing classes in conscrypt
+            throw new ProviderException("Curve " + ED25519_OID + " not supported yet");
+        } else if (X25519_ALIAS.equalsIgnoreCase(jcaKeyAlgorithm)) {
+            //TODO(b/214203951) missing classes in conscrypt
+            throw new ProviderException("Curve " + X25519_ALIAS + " not supported yet");
         } else {
             throw new ProviderException("Unsupported Android Keystore public key algorithm: "
                     + jcaKeyAlgorithm);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BluetoothProfileConnectionInfoTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BluetoothProfileConnectionInfoTest.java
deleted file mode 100644
index f23794b..0000000
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/BluetoothProfileConnectionInfoTest.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.mediaframeworktest.unit;
-
-import static org.junit.Assert.assertEquals;
-
-import android.bluetooth.BluetoothProfile;
-import android.media.BluetoothProfileConnectionInfo;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class BluetoothProfileConnectionInfoTest {
-
-    @Test
-    public void testCoverageA2dp() {
-        final boolean supprNoisy = false;
-        final int volume = 42;
-        final BluetoothProfileConnectionInfo info = BluetoothProfileConnectionInfo
-                .createA2dpInfo(supprNoisy, volume);
-        assertEquals(info.getProfile(), BluetoothProfile.A2DP);
-        assertEquals(info.isSuppressNoisyIntent(), supprNoisy);
-        assertEquals(info.getVolume(), volume);
-    }
-
-    @Test
-    public void testCoverageA2dpSink() {
-        final int volume = 42;
-        final BluetoothProfileConnectionInfo info = BluetoothProfileConnectionInfo
-                .createA2dpSinkInfo(volume);
-        assertEquals(info.getProfile(), BluetoothProfile.A2DP_SINK);
-        assertEquals(info.getVolume(), volume);
-    }
-
-    @Test
-    public void testCoveragehearingAid() {
-        final boolean supprNoisy = true;
-        final BluetoothProfileConnectionInfo info = BluetoothProfileConnectionInfo
-                .createHearingAidInfo(supprNoisy);
-        assertEquals(info.getProfile(), BluetoothProfile.HEARING_AID);
-        assertEquals(info.isSuppressNoisyIntent(), supprNoisy);
-    }
-
-    @Test
-    public void testCoverageLeAudio() {
-        final boolean supprNoisy = false;
-        final boolean isLeOutput = true;
-        final BluetoothProfileConnectionInfo info = BluetoothProfileConnectionInfo
-                .createLeAudioInfo(supprNoisy, isLeOutput);
-        assertEquals(info.getProfile(), BluetoothProfile.LE_AUDIO);
-        assertEquals(info.isSuppressNoisyIntent(), supprNoisy);
-        assertEquals(info.isLeOutput(), isLeOutput);
-    }
-}
-
diff --git a/packages/ConnectivityT/framework-t/Android.bp b/packages/ConnectivityT/framework-t/Android.bp
index 6329565..6652780 100644
--- a/packages/ConnectivityT/framework-t/Android.bp
+++ b/packages/ConnectivityT/framework-t/Android.bp
@@ -158,7 +158,6 @@
     name: "framework-connectivity-tiramisu-sources",
     srcs: [
         ":framework-connectivity-ethernet-sources",
-        ":framework-connectivity-netstats-sources",
     ],
     visibility: ["//frameworks/base"],
 }
@@ -167,6 +166,7 @@
     name: "framework-connectivity-tiramisu-updatable-sources",
     srcs: [
         ":framework-connectivity-ipsec-sources",
+        ":framework-connectivity-netstats-sources",
         ":framework-connectivity-nsd-sources",
         ":framework-connectivity-tiramisu-internal-sources",
     ],
@@ -194,15 +194,12 @@
         "jni/onload.cpp",
     ],
     shared_libs: [
+        "libandroid",
         "liblog",
-    ],
-    static_libs: [
-        "libnativehelper_compat_libc++",
+        "libnativehelper",
     ],
     stl: "none",
     apex_available: [
         "com.android.tethering",
-        // TODO: remove when ConnectivityT moves to APEX.
-        "//apex_available:platform",
     ],
 }
diff --git a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
index 5ce7e59..ca080ce 100644
--- a/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
+++ b/packages/ConnectivityT/framework-t/src/android/app/usage/NetworkStatsManager.java
@@ -27,7 +27,6 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
-import android.annotation.TestApi;
 import android.annotation.WorkerThread;
 import android.app.usage.NetworkStats.Bucket;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -192,9 +191,13 @@
         }
     }
 
-    /** @hide */
+    /**
+     * Set poll force flag to indicate that calling any subsequent query method will force a stats
+     * poll.
+     * @hide
+     */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    @TestApi
+    @SystemApi(client = MODULE_LIBRARIES)
     public void setPollForce(boolean pollForce) {
         if (pollForce) {
             mFlags |= FLAG_POLL_FORCE;
@@ -696,7 +699,9 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
     @NonNull public android.net.NetworkStats getMobileUidStats() {
         try {
             return mService.getUidStatsForTransport(TRANSPORT_CELLULAR);
@@ -720,7 +725,9 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK})
     @NonNull public android.net.NetworkStats getWifiUidStats() {
         try {
             return mService.getUidStatsForTransport(TRANSPORT_WIFI);
@@ -737,8 +744,9 @@
      * {@link #unregisterUsageCallback} is called.
      *
      * @param template Template used to match networks. See {@link NetworkTemplate}.
-     * @param thresholdBytes Threshold in bytes to be notified on. The provided value that lower
-     *                       than 2MiB will be clamped for non-privileged callers.
+     * @param thresholdBytes Threshold in bytes to be notified on. Provided values lower than 2MiB
+     *                       will be clamped for callers except callers with the NETWORK_STACK
+     *                       permission.
      * @param executor The executor on which callback will be invoked. The provided {@link Executor}
      *                 must run callback sequentially, otherwise the order of callbacks cannot be
      *                 guaranteed.
@@ -747,6 +755,9 @@
      * @hide
      */
     @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(anyOf = {
+            NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+            android.Manifest.permission.NETWORK_STACK}, conditional = true)
     public void registerUsageCallback(@NonNull NetworkTemplate template, long thresholdBytes,
             @NonNull @CallbackExecutor Executor executor, @NonNull UsageCallback callback) {
         Objects.requireNonNull(template, "NetworkTemplate cannot be null");
diff --git a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java b/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
index 577ac54..9bffbfb 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/ConnectivityFrameworkInitializerTiramisu.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SystemApi;
 import android.app.SystemServiceRegistry;
+import android.app.usage.NetworkStatsManager;
 import android.content.Context;
 import android.net.nsd.INsdManager;
 import android.net.nsd.NsdManager;
@@ -57,5 +58,15 @@
                     return new IpSecManager(context, service);
                 }
         );
+
+        SystemServiceRegistry.registerContextAwareService(
+                Context.NETWORK_STATS_SERVICE,
+                NetworkStatsManager.class,
+                (context, serviceBinder) -> {
+                    INetworkStatsService service =
+                            INetworkStatsService.Stub.asInterface(serviceBinder);
+                    return new NetworkStatsManager(context, service);
+                }
+        );
     }
 }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
index e879e40..a626971 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/EthernetNetworkUpdateRequest.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -27,13 +28,13 @@
 @SystemApi
 public final class EthernetNetworkUpdateRequest implements Parcelable {
     @NonNull
-    private final StaticIpConfiguration mIpConfig;
+    private final IpConfiguration mIpConfig;
     @NonNull
     private final NetworkCapabilities mNetworkCapabilities;
 
     @NonNull
-    public StaticIpConfiguration getIpConfig() {
-        return new StaticIpConfiguration(mIpConfig);
+    public IpConfiguration getIpConfiguration() {
+        return new IpConfiguration(mIpConfig);
     }
 
     @NonNull
@@ -41,20 +42,75 @@
         return new NetworkCapabilities(mNetworkCapabilities);
     }
 
-    public EthernetNetworkUpdateRequest(@NonNull final StaticIpConfiguration ipConfig,
+    private EthernetNetworkUpdateRequest(@NonNull final IpConfiguration ipConfig,
             @NonNull final NetworkCapabilities networkCapabilities) {
         Objects.requireNonNull(ipConfig);
         Objects.requireNonNull(networkCapabilities);
-        mIpConfig = new StaticIpConfiguration(ipConfig);
+        mIpConfig = new IpConfiguration(ipConfig);
         mNetworkCapabilities = new NetworkCapabilities(networkCapabilities);
     }
 
     private EthernetNetworkUpdateRequest(@NonNull final Parcel source) {
         Objects.requireNonNull(source);
-        mIpConfig = StaticIpConfiguration.CREATOR.createFromParcel(source);
+        mIpConfig = IpConfiguration.CREATOR.createFromParcel(source);
         mNetworkCapabilities = NetworkCapabilities.CREATOR.createFromParcel(source);
     }
 
+    /**
+     * Builder used to create {@link EthernetNetworkUpdateRequest} objects.
+     */
+    public static final class Builder {
+        @Nullable
+        private IpConfiguration mBuilderIpConfig;
+        @Nullable
+        private NetworkCapabilities mBuilderNetworkCapabilities;
+
+        public Builder(){}
+
+        /**
+         * Constructor to populate the builder's values with an already built
+         * {@link EthernetNetworkUpdateRequest}.
+         * @param request the {@link EthernetNetworkUpdateRequest} to populate with.
+         */
+        public Builder(@NonNull final EthernetNetworkUpdateRequest request) {
+            Objects.requireNonNull(request);
+            mBuilderIpConfig = new IpConfiguration(request.mIpConfig);
+            mBuilderNetworkCapabilities = new NetworkCapabilities(request.mNetworkCapabilities);
+        }
+
+        /**
+         * Set the {@link IpConfiguration} to be used with the {@code Builder}.
+         * @param ipConfig the {@link IpConfiguration} to set.
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setIpConfiguration(@NonNull final IpConfiguration ipConfig) {
+            Objects.requireNonNull(ipConfig);
+            mBuilderIpConfig = new IpConfiguration(ipConfig);
+            return this;
+        }
+
+        /**
+         * Set the {@link NetworkCapabilities} to be used with the {@code Builder}.
+         * @param nc the {@link NetworkCapabilities} to set.
+         * @return The builder to facilitate chaining.
+         */
+        @NonNull
+        public Builder setNetworkCapabilities(@NonNull final NetworkCapabilities nc) {
+            Objects.requireNonNull(nc);
+            mBuilderNetworkCapabilities = new NetworkCapabilities(nc);
+            return this;
+        }
+
+        /**
+         * Build {@link EthernetNetworkUpdateRequest} return the current update request.
+         */
+        @NonNull
+        public EthernetNetworkUpdateRequest build() {
+            return new EthernetNetworkUpdateRequest(mBuilderIpConfig, mBuilderNetworkCapabilities);
+        }
+    }
+
     @Override
     public String toString() {
         return "EthernetNetworkUpdateRequest{"
@@ -68,7 +124,7 @@
         if (o == null || getClass() != o.getClass()) return false;
         EthernetNetworkUpdateRequest that = (EthernetNetworkUpdateRequest) o;
 
-        return Objects.equals(that.getIpConfig(), mIpConfig)
+        return Objects.equals(that.getIpConfiguration(), mIpConfig)
                 && Objects.equals(that.getNetworkCapabilities(), mNetworkCapabilities);
     }
 
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
index 56faa52..a48f94b 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentity.java
@@ -20,6 +20,7 @@
 import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.NetworkTemplate.NETWORK_TYPE_ALL;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -86,6 +87,7 @@
 
     final int mType;
     final int mRatType;
+    final int mSubId;
     final String mSubscriberId;
     final String mWifiNetworkKey;
     final boolean mRoaming;
@@ -96,7 +98,7 @@
     /** @hide */
     public NetworkIdentity(
             int type, int ratType, @Nullable String subscriberId, @Nullable String wifiNetworkKey,
-            boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged) {
+            boolean roaming, boolean metered, boolean defaultNetwork, int oemManaged, int subId) {
         mType = type;
         mRatType = ratType;
         mSubscriberId = subscriberId;
@@ -105,12 +107,13 @@
         mMetered = metered;
         mDefaultNetwork = defaultNetwork;
         mOemManaged = oemManaged;
+        mSubId = subId;
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mType, mRatType, mSubscriberId, mWifiNetworkKey, mRoaming, mMetered,
-                mDefaultNetwork, mOemManaged);
+                mDefaultNetwork, mOemManaged, mSubId);
     }
 
     @Override
@@ -122,7 +125,8 @@
                     && Objects.equals(mWifiNetworkKey, ident.mWifiNetworkKey)
                     && mMetered == ident.mMetered
                     && mDefaultNetwork == ident.mDefaultNetwork
-                    && mOemManaged == ident.mOemManaged;
+                    && mOemManaged == ident.mOemManaged
+                    && mSubId == ident.mSubId;
         }
         return false;
     }
@@ -150,6 +154,7 @@
         builder.append(", metered=").append(mMetered);
         builder.append(", defaultNetwork=").append(mDefaultNetwork);
         builder.append(", oemManaged=").append(getOemManagedNames(mOemManaged));
+        builder.append(", subId=").append(mSubId);
         return builder.append("}").toString();
     }
 
@@ -184,14 +189,14 @@
     public void dumpDebug(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
 
-        proto.write(NetworkIdentityProto.TYPE, mType);
+        proto.write(NetworkIdentityProto.TYPE_FIELD_NUMBER, mType);
 
         // TODO: dump mRatType as well.
 
-        proto.write(NetworkIdentityProto.ROAMING, mRoaming);
-        proto.write(NetworkIdentityProto.METERED, mMetered);
-        proto.write(NetworkIdentityProto.DEFAULT_NETWORK, mDefaultNetwork);
-        proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK, mOemManaged);
+        proto.write(NetworkIdentityProto.ROAMING_FIELD_NUMBER, mRoaming);
+        proto.write(NetworkIdentityProto.METERED_FIELD_NUMBER, mMetered);
+        proto.write(NetworkIdentityProto.DEFAULT_NETWORK_FIELD_NUMBER, mDefaultNetwork);
+        proto.write(NetworkIdentityProto.OEM_MANAGED_NETWORK_FIELD_NUMBER, mOemManaged);
 
         proto.end(start);
     }
@@ -256,6 +261,11 @@
         return mOemManaged;
     }
 
+    /** Get the SubId of this instance. */
+    public int getSubId() {
+        return mSubId;
+    }
+
     /**
      * Assemble a {@link NetworkIdentity} from the passed arguments.
      *
@@ -276,7 +286,8 @@
     public static NetworkIdentity buildNetworkIdentity(Context context,
             @NonNull NetworkStateSnapshot snapshot, boolean defaultNetwork, int ratType) {
         final NetworkIdentity.Builder builder = new NetworkIdentity.Builder()
-                .setNetworkStateSnapshot(snapshot).setDefaultNetwork(defaultNetwork);
+                .setNetworkStateSnapshot(snapshot).setDefaultNetwork(defaultNetwork)
+                .setSubId(snapshot.getSubId());
         if (snapshot.getLegacyType() == TYPE_MOBILE && ratType != NETWORK_TYPE_ALL) {
             builder.setRatType(ratType);
         }
@@ -325,6 +336,9 @@
         if (res == 0) {
             res = Integer.compare(left.mOemManaged, right.mOemManaged);
         }
+        if (res == 0) {
+            res = Integer.compare(left.mSubId, right.mSubId);
+        }
         return res;
     }
 
@@ -345,6 +359,7 @@
         private boolean mMetered;
         private boolean mDefaultNetwork;
         private int mOemManaged;
+        private int mSubId;
 
         /**
          * Creates a new Builder.
@@ -359,6 +374,7 @@
             mMetered = false;
             mDefaultNetwork = false;
             mOemManaged = NetworkTemplate.OEM_MANAGED_NO;
+            mSubId = INVALID_SUBSCRIPTION_ID;
         }
 
         /**
@@ -537,6 +553,19 @@
             return this;
         }
 
+        /**
+         * Set the Subscription Id.
+         *
+         * @param subId the Subscription Id of the network. Or INVALID_SUBSCRIPTION_ID if not
+         *              applicable.
+         * @return this builder.
+         */
+        @NonNull
+        public Builder setSubId(int subId) {
+            mSubId = subId;
+            return this;
+        }
+
         private void ensureValidParameters() {
             // Assert non-mobile network cannot have a ratType.
             if (mType != TYPE_MOBILE && mRatType != NetworkTemplate.NETWORK_TYPE_ALL) {
@@ -559,7 +588,7 @@
         public NetworkIdentity build() {
             ensureValidParameters();
             return new NetworkIdentity(mType, mRatType, mSubscriberId, mWifiNetworkKey,
-                    mRoaming, mMetered, mDefaultNetwork, mOemManaged);
+                    mRoaming, mMetered, mDefaultNetwork, mOemManaged, mSubId);
         }
     }
 }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
index dfa347f..56461ba 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkIdentitySet.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import android.annotation.NonNull;
 import android.service.NetworkIdentitySetProto;
@@ -42,6 +43,7 @@
     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;
+    private static final int VERSION_ADD_SUB_ID = 7;
 
     /**
      * Construct a {@link NetworkIdentitySet} object.
@@ -103,8 +105,15 @@
                 oemNetCapabilities = NetworkIdentity.OEM_NONE;
             }
 
+            final int subId;
+            if (version >= VERSION_ADD_SUB_ID) {
+                subId = in.readInt();
+            } else {
+                subId = INVALID_SUBSCRIPTION_ID;
+            }
+
             add(new NetworkIdentity(type, ratType, subscriberId, networkId, roaming, metered,
-                    defaultNetwork, oemNetCapabilities));
+                    defaultNetwork, oemNetCapabilities, subId));
         }
     }
 
@@ -113,7 +122,7 @@
      * @hide
      */
     public void writeToStream(DataOutput out) throws IOException {
-        out.writeInt(VERSION_ADD_OEM_MANAGED_NETWORK);
+        out.writeInt(VERSION_ADD_SUB_ID);
         out.writeInt(size());
         for (NetworkIdentity ident : this) {
             out.writeInt(ident.getType());
@@ -124,6 +133,7 @@
             out.writeBoolean(ident.isMetered());
             out.writeBoolean(ident.isDefaultNetwork());
             out.writeInt(ident.getOemManaged());
+            out.writeInt(ident.getSubId());
         }
     }
 
@@ -212,7 +222,7 @@
         final long start = proto.start(tag);
 
         for (NetworkIdentity ident : this) {
-            ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES);
+            ident.dumpDebug(proto, NetworkIdentitySetProto.IDENTITIES_FIELD_NUMBER);
         }
 
         proto.end(start);
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java
index 3915634..d3f785a 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java
@@ -17,6 +17,8 @@
 package android.net;
 
 import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -98,12 +100,29 @@
         return mLinkProperties;
     }
 
-    /** Get the Subscriber Id of the network associated with this snapshot. */
+    /**
+     * Get the Subscriber Id of the network associated with this snapshot.
+     * @deprecated Please use #getSubId, which doesn't return personally identifiable
+     * information.
+     */
+    @Deprecated
     @Nullable
     public String getSubscriberId() {
         return mSubscriberId;
     }
 
+    /** Get the subId of the network associated with this snapshot. */
+    public int getSubId() {
+        if (mNetworkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
+            final NetworkSpecifier spec = mNetworkCapabilities.getNetworkSpecifier();
+            if (spec instanceof TelephonyNetworkSpecifier) {
+                return ((TelephonyNetworkSpecifier) spec).getSubscriptionId();
+            }
+        }
+        return INVALID_SUBSCRIPTION_ID;
+    }
+
+
     /**
      * Get the legacy type of the network associated with this snapshot.
      * @return the legacy network type. See {@code ConnectivityManager#TYPE_*}.
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
index 735c44d..67d48f0 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsCollection.java
@@ -732,19 +732,19 @@
         final long start = proto.start(tag);
 
         for (Key key : getSortedKeys()) {
-            final long startStats = proto.start(NetworkStatsCollectionProto.STATS);
+            final long startStats = proto.start(NetworkStatsCollectionProto.STATS_FIELD_NUMBER);
 
             // Key
-            final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY);
-            key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY);
-            proto.write(NetworkStatsCollectionKeyProto.UID, key.uid);
-            proto.write(NetworkStatsCollectionKeyProto.SET, key.set);
-            proto.write(NetworkStatsCollectionKeyProto.TAG, key.tag);
+            final long startKey = proto.start(NetworkStatsCollectionStatsProto.KEY_FIELD_NUMBER);
+            key.ident.dumpDebug(proto, NetworkStatsCollectionKeyProto.IDENTITY_FIELD_NUMBER);
+            proto.write(NetworkStatsCollectionKeyProto.UID_FIELD_NUMBER, key.uid);
+            proto.write(NetworkStatsCollectionKeyProto.SET_FIELD_NUMBER, key.set);
+            proto.write(NetworkStatsCollectionKeyProto.TAG_FIELD_NUMBER, key.tag);
             proto.end(startKey);
 
             // Value
             final NetworkStatsHistory history = mStats.get(key);
-            history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY);
+            history.dumpDebug(proto, NetworkStatsCollectionStatsProto.HISTORY_FIELD_NUMBER);
             proto.end(startStats);
         }
 
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
index 78c1370..822a16e 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStatsHistory.java
@@ -915,17 +915,18 @@
     public void dumpDebug(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
 
-        proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS, bucketDuration);
+        proto.write(NetworkStatsHistoryProto.BUCKET_DURATION_MS_FIELD_NUMBER, bucketDuration);
 
         for (int i = 0; i < bucketCount; i++) {
-            final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS);
+            final long startBucket = proto.start(NetworkStatsHistoryProto.BUCKETS_FIELD_NUMBER);
 
-            proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS, bucketStart[i]);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES, rxBytes, i);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS, rxPackets, i);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES, txBytes, i);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS, txPackets, i);
-            dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS, operations, i);
+            proto.write(NetworkStatsHistoryBucketProto.BUCKET_START_MS_FIELD_NUMBER,
+                    bucketStart[i]);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_BYTES_FIELD_NUMBER, rxBytes, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.RX_PACKETS_FIELD_NUMBER, rxPackets, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_BYTES_FIELD_NUMBER, txBytes, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.TX_PACKETS_FIELD_NUMBER, txPackets, i);
+            dumpDebug(proto, NetworkStatsHistoryBucketProto.OPERATIONS_FIELD_NUMBER, operations, i);
 
             proto.end(startBucket);
         }
diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
index 9b58b01..7b5afd7 100644
--- a/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
+++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkTemplate.java
@@ -79,7 +79,8 @@
             MATCH_WIFI,
             MATCH_ETHERNET,
             MATCH_BLUETOOTH,
-            MATCH_CARRIER
+            MATCH_PROXY,
+            MATCH_CARRIER,
     })
     public @interface TemplateMatchRule{}
 
@@ -104,9 +105,8 @@
     /** Match rule to match bluetooth networks. */
     public static final int MATCH_BLUETOOTH = 8;
     /**
-     * Match rule to match networks with {@link Connectivity#TYPE_PROXY} as the legacy network type.
-     *
-     * @hide
+     * Match rule to match networks with {@link ConnectivityManager#TYPE_PROXY} as the legacy
+     * network type.
      */
     public static final int MATCH_PROXY = 9;
     /**
diff --git a/packages/ConnectivityT/service/Android.bp b/packages/ConnectivityT/service/Android.bp
index c3049da..5100e7c 100644
--- a/packages/ConnectivityT/service/Android.bp
+++ b/packages/ConnectivityT/service/Android.bp
@@ -40,6 +40,30 @@
     ],
 }
 
+// For test code only.
+filegroup {
+    name: "lib_networkStatsFactory_native",
+    srcs: [
+        "jni/com_android_server_net_NetworkStatsFactory.cpp",
+    ],
+    path: "jni",
+    visibility: [
+        "//packages/modules/Connectivity:__subpackages__",
+    ],
+}
+
+filegroup {
+    name: "services.connectivity-netstats-jni-sources",
+    srcs: [
+        "jni/com_android_server_net_NetworkStatsFactory.cpp",
+        "jni/com_android_server_net_NetworkStatsService.cpp",
+    ],
+    path: "jni",
+    visibility: [
+        "//packages/modules/Connectivity:__subpackages__",
+    ],
+}
+
 // Nsd related libraries.
 
 filegroup {
@@ -88,7 +112,6 @@
     name: "services.connectivity-tiramisu-sources",
     srcs: [
         ":services.connectivity-ethernet-sources",
-        ":services.connectivity-netstats-sources",
     ],
     path: "src",
     visibility: ["//frameworks/base/services/core"],
@@ -98,6 +121,7 @@
     name: "services.connectivity-tiramisu-updatable-sources",
     srcs: [
         ":services.connectivity-ipsec-sources",
+        ":services.connectivity-netstats-sources",
         ":services.connectivity-nsd-sources",
     ],
     path: "src",
diff --git a/services/core/jni/com_android_server_net_NetworkStatsFactory.cpp b/packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsFactory.cpp
similarity index 100%
rename from services/core/jni/com_android_server_net_NetworkStatsFactory.cpp
rename to packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsFactory.cpp
diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsService.cpp
similarity index 100%
rename from services/core/jni/com_android_server_net_NetworkStatsService.cpp
rename to packages/ConnectivityT/service/jni/com_android_server_net_NetworkStatsService.cpp
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
index 668d1cb..151c90d 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsFactory.java
@@ -54,6 +54,10 @@
  * @hide
  */
 public class NetworkStatsFactory {
+    static {
+        System.loadLibrary("service-connectivity");
+    }
+
     private static final String TAG = "NetworkStatsFactory";
 
     private static final boolean USE_NATIVE_PARSING = true;
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java
index 1953624..fdfc893 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsObservers.java
@@ -19,8 +19,11 @@
 import static android.app.usage.NetworkStatsManager.MIN_THRESHOLD_BYTES;
 
 import android.app.usage.NetworkStatsManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.net.DataUsageRequest;
 import android.net.NetworkIdentitySet;
+import android.net.NetworkStack;
 import android.net.NetworkStats;
 import android.net.NetworkStatsAccess;
 import android.net.NetworkStatsCollection;
@@ -74,9 +77,9 @@
      *
      * @return the normalized request wrapped within {@link RequestInfo}.
      */
-    public DataUsageRequest register(DataUsageRequest inputRequest, IUsageCallback callback,
-            int callingUid, @NetworkStatsAccess.Level int accessLevel) {
-        DataUsageRequest request = buildRequest(inputRequest, callingUid);
+    public DataUsageRequest register(Context context, DataUsageRequest inputRequest,
+            IUsageCallback callback, int callingUid, @NetworkStatsAccess.Level int accessLevel) {
+        DataUsageRequest request = buildRequest(context, inputRequest, callingUid);
         RequestInfo requestInfo = buildRequestInfo(request, callback, callingUid,
                 accessLevel);
 
@@ -194,10 +197,13 @@
         }
     }
 
-    private DataUsageRequest buildRequest(DataUsageRequest request, int callingUid) {
-        // For non-system uid, cap the minimum threshold to a safe default to avoid too
-        // many callbacks.
-        long thresholdInBytes = (callingUid == Process.SYSTEM_UID ? request.thresholdInBytes
+    private DataUsageRequest buildRequest(Context context, DataUsageRequest request,
+                int callingUid) {
+        // For non-NETWORK_STACK permission uid, cap the minimum threshold to a safe default to
+        // avoid too many callbacks.
+        final long thresholdInBytes = (context.checkPermission(
+                NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, Process.myPid(), callingUid)
+                == PackageManager.PERMISSION_GRANTED ? request.thresholdInBytes
                 : Math.max(MIN_THRESHOLD_BYTES, request.thresholdInBytes));
         if (thresholdInBytes > request.thresholdInBytes) {
             Log.w(TAG, "Threshold was too low for " + request
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
index c371f08..a006cd5 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsRecorder.java
@@ -471,9 +471,11 @@
     public void dumpDebugLocked(ProtoOutputStream proto, long tag) {
         final long start = proto.start(tag);
         if (mPending != null) {
-            proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES, mPending.getTotalBytes());
+            proto.write(NetworkStatsRecorderProto.PENDING_TOTAL_BYTES_FIELD_NUMBER,
+                    mPending.getTotalBytes());
         }
-        getOrLoadCompleteLocked().dumpDebug(proto, NetworkStatsRecorderProto.COMPLETE_HISTORY);
+        getOrLoadCompleteLocked().dumpDebug(proto,
+                NetworkStatsRecorderProto.COMPLETE_HISTORY_FIELD_NUMBER);
         proto.end(start);
     }
 
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
index b193623..ef6f39a 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsService.java
@@ -63,6 +63,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.TargetApi;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.app.usage.NetworkStatsManager;
@@ -103,6 +104,7 @@
 import android.net.netstats.provider.INetworkStatsProviderCallback;
 import android.net.netstats.provider.NetworkStatsProvider;
 import android.os.Binder;
+import android.os.Build;
 import android.os.DropBoxManager;
 import android.os.Environment;
 import android.os.Handler;
@@ -169,7 +171,12 @@
  * Collect and persist detailed network statistics, and provide this data to
  * other system services.
  */
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
 public class NetworkStatsService extends INetworkStatsService.Stub {
+    static {
+        System.loadLibrary("service-connectivity");
+    }
+
     static final String TAG = "NetworkStats";
     static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
     static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
@@ -1116,7 +1123,7 @@
 
     @Override
     public NetworkStats getUidStatsForTransport(int transport) {
-        enforceAnyPermissionOf(NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK);
+        PermissionUtils.enforceNetworkStackPermission(mContext);
         try {
             final String[] relevantIfaces =
                     transport == TRANSPORT_WIFI ? mWifiIfaces : mMobileIfaces;
@@ -1278,7 +1285,7 @@
         DataUsageRequest normalizedRequest;
         final long token = Binder.clearCallingIdentity();
         try {
-            normalizedRequest = mStatsObservers.register(
+            normalizedRequest = mStatsObservers.register(mContext,
                     request, callback, callingUid, accessLevel);
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -1533,10 +1540,15 @@
                         NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.isMetered()) {
 
                     // Copy the identify from IMS one but mark it as metered.
-                    NetworkIdentity vtIdent = new NetworkIdentity(ident.getType(),
-                            ident.getRatType(), ident.getSubscriberId(), ident.getWifiNetworkKey(),
-                            ident.isRoaming(), true /* metered */,
-                            true /* onDefaultNetwork */, ident.getOemManaged());
+                    NetworkIdentity vtIdent = new NetworkIdentity.Builder()
+                            .setType(ident.getType())
+                            .setRatType(ident.getRatType())
+                            .setSubscriberId(ident.getSubscriberId())
+                            .setWifiNetworkKey(ident.getWifiNetworkKey())
+                            .setRoaming(ident.isRoaming()).setMetered(true)
+                            .setDefaultNetwork(true)
+                            .setOemManaged(ident.getOemManaged())
+                            .setSubId(ident.getSubId()).build();
                     final String ifaceVt = IFACE_VT + getSubIdForMobile(snapshot);
                     findOrCreateNetworkIdentitySet(mActiveIfaces, ifaceVt).add(vtIdent);
                     findOrCreateNetworkIdentitySet(mActiveUidIfaces, ifaceVt).add(vtIdent);
@@ -2120,12 +2132,15 @@
 
         // TODO Right now it writes all history.  Should it limit to the "since-boot" log?
 
-        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES, mActiveIfaces);
-        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES, mActiveUidIfaces);
-        mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS);
-        mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS);
-        mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS);
-        mUidTagRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_TAG_STATS);
+        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_INTERFACES_FIELD_NUMBER,
+                mActiveIfaces);
+        dumpInterfaces(proto, NetworkStatsServiceDumpProto.ACTIVE_UID_INTERFACES_FIELD_NUMBER,
+                mActiveUidIfaces);
+        mDevRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.DEV_STATS_FIELD_NUMBER);
+        mXtRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.XT_STATS_FIELD_NUMBER);
+        mUidRecorder.dumpDebugLocked(proto, NetworkStatsServiceDumpProto.UID_STATS_FIELD_NUMBER);
+        mUidTagRecorder.dumpDebugLocked(proto,
+                NetworkStatsServiceDumpProto.UID_TAG_STATS_FIELD_NUMBER);
 
         proto.flush();
     }
@@ -2135,8 +2150,8 @@
         for (int i = 0; i < ifaces.size(); i++) {
             final long start = proto.start(tag);
 
-            proto.write(NetworkInterfaceProto.INTERFACE, ifaces.keyAt(i));
-            ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES);
+            proto.write(NetworkInterfaceProto.INTERFACE_FIELD_NUMBER, ifaces.keyAt(i));
+            ifaces.valueAt(i).dumpDebug(proto, NetworkInterfaceProto.IDENTITIES_FIELD_NUMBER);
 
             proto.end(start);
         }
diff --git a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
index 5bba0b1..65ccd20 100644
--- a/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
+++ b/packages/ConnectivityT/service/src/com/android/server/net/NetworkStatsSubscriptionsMonitor.java
@@ -23,7 +23,9 @@
 import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
 
 import android.annotation.NonNull;
+import android.annotation.TargetApi;
 import android.content.Context;
+import android.os.Build;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyDisplayInfo;
@@ -43,6 +45,7 @@
 /**
  * Helper class that watches for events that are triggered per subscription.
  */
+@TargetApi(Build.VERSION_CODES.TIRAMISU)
 public class NetworkStatsSubscriptionsMonitor extends
         SubscriptionManager.OnSubscriptionsChangedListener {
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index b44d914..7e5c124 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -140,13 +140,6 @@
         return (activeDevices.size() > 0) ? activeDevices.get(0) : null;
     }
 
-    public boolean isAudioOn() {
-        if (mService == null) {
-            return false;
-        }
-        return mService.isAudioOn();
-    }
-
     public int getAudioState(BluetoothDevice device) {
         if (mService == null) {
             return BluetoothHeadset.STATE_AUDIO_DISCONNECTED;
diff --git a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
index 2c2be03..c7eb682 100644
--- a/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
+++ b/packages/SettingsLib/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXml.java
@@ -70,7 +70,7 @@
             + "</style>\n"
             + "</head>"
             + "<body topmargin=\"0\" leftmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">\n"
-            + "<div class=\"toc\">\n";
+            + "<div class=\"toc\">";
     private static final String LIBRARY_HEAD_STRING =
             "<strong>Libraries</strong>\n<ul class=\"libraries\">";
     private static final String LIBRARY_TAIL_STRING = "</ul>\n<strong>Files</strong>";
@@ -324,6 +324,8 @@
             writer.println(LIBRARY_TAIL_STRING);
         }
 
+        writer.println(FILES_HEAD_STRING);
+
         // Prints all the file list with a link to its license file content.
         for (String fileName : fileNameList) {
             for (Map.Entry<String, Set<String>> libToContentId :
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java
index 30182c4..f5ce664 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HeadsetProfileTest.java
@@ -55,15 +55,6 @@
     }
 
     @Test
-    public void bluetoothProfile_shouldReturnTheAudioStatusFromBlueToothHeadsetService() {
-        when(mService.isAudioOn()).thenReturn(true);
-        assertThat(mProfile.isAudioOn()).isTrue();
-
-        when(mService.isAudioOn()).thenReturn(false);
-        assertThat(mProfile.isAudioOn()).isFalse();
-    }
-
-    @Test
     public void testHeadsetProfile_shouldReturnAudioState() {
         when(mService.getAudioState(mBluetoothDevice)).
                 thenReturn(BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
index e348865..09b0d7f 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/license/LicenseHtmlGeneratorFromXmlTest.java
@@ -120,7 +120,7 @@
             + "</div><!-- table of contents -->\n"
             + "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n"
             + "<tr id=\"id0\"><td class=\"same-license\">\n"
-            + "<div class=\"label\">Notices for file(s):</div>\n"
+            + "<div class=\"label\"><strong>libA</strong> used by:</div>\n"
             + "<div class=\"file-list\">\n"
             + "/file0 <br/>\n"
             + "/file1 <br/>\n"
@@ -130,7 +130,7 @@
             + "</pre><!-- license-text -->\n"
             + "</td></tr><!-- same-license -->\n"
             + "<tr id=\"id1\"><td class=\"same-license\">\n"
-            + "<div class=\"label\">Notices for file(s):</div>\n"
+            + "<div class=\"label\"><strong>libB</strong> used by:</div>\n"
             + "<div class=\"file-list\">\n"
             + "/file0 <br/>\n"
             + "</div><!-- file-list -->\n"
@@ -158,10 +158,12 @@
         LicenseHtmlGeneratorFromXml.parse(
                 new InputStreamReader(new ByteArrayInputStream(VALID_OLD_XML_STRING.getBytes())),
                 fileNameToLibraryToContentIdMap, contentIdToFileContentMap);
-        assertThat(fileNameToLibraryToContentIdMap.size()).isEqualTo(1);
-        assertThat(fileNameToLibraryToContentIdMap.get("").size()).isEqualTo(2);
-        assertThat(fileNameToLibraryToContentIdMap.get("").get("/file0")).containsExactly("0");
-        assertThat(fileNameToLibraryToContentIdMap.get("").get("/file1")).containsExactly("0");
+
+        assertThat(fileNameToLibraryToContentIdMap).hasSize(2);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file0")).hasSize(1);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file1")).hasSize(1);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file0").get(null)).containsExactly("0");
+        assertThat(fileNameToLibraryToContentIdMap.get("/file1").get(null)).containsExactly("0");
         assertThat(contentIdToFileContentMap.size()).isEqualTo(1);
         assertThat(contentIdToFileContentMap.get("0")).isEqualTo("license content #0");
     }
@@ -174,11 +176,12 @@
         LicenseHtmlGeneratorFromXml.parse(
                 new InputStreamReader(new ByteArrayInputStream(VALID_NEW_XML_STRING.getBytes())),
                 fileNameToLibraryToContentIdMap, contentIdToFileContentMap);
-        assertThat(fileNameToLibraryToContentIdMap.size()).isEqualTo(2);
-        assertThat(fileNameToLibraryToContentIdMap.get("libA").size()).isEqualTo(1);
-        assertThat(fileNameToLibraryToContentIdMap.get("libB").size()).isEqualTo(1);
-        assertThat(fileNameToLibraryToContentIdMap.get("libA").get("/file0")).containsExactly("0");
-        assertThat(fileNameToLibraryToContentIdMap.get("libB").get("/file1")).containsExactly("0");
+
+        assertThat(fileNameToLibraryToContentIdMap).hasSize(2);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file0")).hasSize(1);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file1")).hasSize(1);
+        assertThat(fileNameToLibraryToContentIdMap.get("/file0").get("libA")).containsExactly("0");
+        assertThat(fileNameToLibraryToContentIdMap.get("/file1").get("libB")).containsExactly("0");
         assertThat(contentIdToFileContentMap.size()).isEqualTo(1);
         assertThat(contentIdToFileContentMap.get("0")).isEqualTo("license content #0");
     }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 8b27522..ca4dcbb 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -559,6 +559,9 @@
 
     <uses-permission android:name="android.permission.MANAGE_APP_HIBERNATION"/>
 
+    <!-- Permission required for CTS test - MediaCodecResourceTest -->
+    <uses-permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID" />
+
     <!-- Permission required for CTS test - ResourceObserverNativeTest -->
     <uses-permission android:name="android.permission.REGISTER_MEDIA_RESOURCE_OBSERVER" />
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index cd6a778..70e4fb5 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -33,7 +33,6 @@
 import android.media.AudioSystem;
 import android.media.IAudioService;
 import android.media.IVolumeController;
-import android.media.MediaRoute2Info;
 import android.media.MediaRouter2Manager;
 import android.media.RoutingSessionInfo;
 import android.media.VolumePolicy;
@@ -462,11 +461,15 @@
     private boolean checkRoutedToBluetoothW(int stream) {
         boolean changed = false;
         if (stream == AudioManager.STREAM_MUSIC) {
+            // Note: Here we didn't use DEVICE_OUT_BLE_SPEAKER and DEVICE_OUT_BLE_BROADCAST
+            //       Since their values overlap with DEVICE_OUT_EARPIECE and DEVICE_OUT_SPEAKER.
+            //       Anyway, we can check BLE devices by using just DEVICE_OUT_BLE_HEADSET.
             final boolean routedToBluetooth =
                     (mAudio.getDevicesForStream(AudioManager.STREAM_MUSIC) &
                             (AudioManager.DEVICE_OUT_BLUETOOTH_A2DP |
                             AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
-                            AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0;
+                            AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER |
+                            AudioManager.DEVICE_OUT_BLE_HEADSET)) != 0;
             changed |= updateStreamRoutedToBluetoothW(stream, routedToBluetooth);
         }
         return changed;
diff --git a/services/Android.bp b/services/Android.bp
index 536dc5d..e730321 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -178,10 +178,6 @@
     name: "libandroid_servers",
     defaults: ["libservices.core-libs"],
     whole_static_libs: ["libservices.core"],
-    required: [
-        // TODO: remove after NetworkStatsService is moved to the mainline module.
-        "libcom_android_net_module_util_jni",
-    ],
 }
 
 platform_compat_config {
diff --git a/services/core/java/com/android/server/DiskStatsService.java b/services/core/java/com/android/server/DiskStatsService.java
index 8ea3dd6..1095ba3 100644
--- a/services/core/java/com/android/server/DiskStatsService.java
+++ b/services/core/java/com/android/server/DiskStatsService.java
@@ -125,6 +125,8 @@
                 DiskStatsFreeSpaceProto.FOLDER_CACHE);
         reportFreeSpace(new File("/system"), "System", pw, proto,
                 DiskStatsFreeSpaceProto.FOLDER_SYSTEM);
+        reportFreeSpace(Environment.getMetadataDirectory(), "Metadata", pw, proto,
+                DiskStatsFreeSpaceProto.FOLDER_METADATA);
 
         boolean fileBased = StorageManager.isFileEncryptedNativeOnly();
         boolean blockBased = fileBased ? false : StorageManager.isBlockEncrypted();
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateService.java b/services/core/java/com/android/server/NetworkTimeUpdateService.java
index ff2308c..186ff62 100644
--- a/services/core/java/com/android/server/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/NetworkTimeUpdateService.java
@@ -16,6 +16,8 @@
 
 package com.android.server;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.app.timedetector.NetworkTimeSuggestion;
@@ -35,17 +37,21 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
 import android.os.SystemClock;
 import android.os.TimestampedValue;
 import android.provider.Settings;
+import android.util.LocalLog;
 import android.util.Log;
 import android.util.NtpTrustedTime;
-import android.util.TimeUtils;
+import android.util.NtpTrustedTime.TimeResult;
 
 import com.android.internal.util.DumpUtils;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.time.Duration;
 
 /**
  * Monitors the network time. If looking up the network time fails for some reason, it tries a few
@@ -95,6 +101,13 @@
     // connection to happen.
     private int mTryAgainCounter;
 
+    /**
+     * A log that records the decisions to fetch a network time update.
+     * This is logged in bug reports to assist with debugging issues with network time suggestions.
+     */
+    @NonNull
+    private final LocalLog mLocalLog = new LocalLog(30, false /* useLocalTimestamps */);
+
     public NetworkTimeUpdateService(Context context) {
         mContext = context;
         mTime = NtpTrustedTime.getInstance(context);
@@ -143,6 +156,55 @@
                 }, new IntentFilter(ACTION_POLL));
     }
 
+    /**
+     * Clears the cached NTP time. For use during tests to simulate when no NTP time is available.
+     *
+     * <p>This operation takes place in the calling thread rather than the service's handler thread.
+     */
+    void clearTimeForTests() {
+        mContext.enforceCallingPermission(
+                android.Manifest.permission.SET_TIME, "clear latest network time");
+
+        mTime.clearCachedTimeResult();
+
+        mLocalLog.log("clearTimeForTests");
+    }
+
+    /**
+     * Forces the service to refresh the NTP time.
+     *
+     * <p>This operation takes place in the calling thread rather than the service's handler thread.
+     * This method does not affect currently scheduled refreshes. If the NTP request is successful
+     * it will make an (asynchronously handled) suggestion to the time detector.
+     */
+    boolean forceRefreshForTests() {
+        mContext.enforceCallingPermission(
+                android.Manifest.permission.SET_TIME, "force network time refresh");
+
+        boolean success = mTime.forceRefresh();
+        mLocalLog.log("forceRefreshForTests: success=" + success);
+
+        if (success) {
+            makeNetworkTimeSuggestion(mTime.getCachedTimeResult(),
+                    "Origin: NetworkTimeUpdateService: forceRefreshForTests");
+        }
+
+        return success;
+    }
+
+    /**
+     * Overrides the NTP server config for tests. Passing {@code null} to a parameter clears the
+     * test value, i.e. so the normal value will be used next time.
+     */
+    void setServerConfigForTests(@Nullable String hostname, @Nullable Duration timeout) {
+        mContext.enforceCallingPermission(
+                android.Manifest.permission.SET_TIME, "set NTP server config for tests");
+
+        mLocalLog.log("Setting server config for tests: hostname=" + hostname
+                + ", timeout=" + timeout);
+        mTime.setServerConfigForTests(hostname, timeout);
+    }
+
     private void onPollNetworkTime(int event) {
         // If we don't have any default network, don't bother.
         if (mDefaultNetwork == null) return;
@@ -155,24 +217,37 @@
     }
 
     private void onPollNetworkTimeUnderWakeLock(int event) {
+        long currentElapsedRealtimeMillis = SystemClock.elapsedRealtime();
         // Force an NTP fix when outdated
         NtpTrustedTime.TimeResult cachedNtpResult = mTime.getCachedTimeResult();
-        if (cachedNtpResult == null || cachedNtpResult.getAgeMillis() >= mPollingIntervalMs) {
+        if (cachedNtpResult == null || cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)
+                >= mPollingIntervalMs) {
             if (DBG) Log.d(TAG, "Stale NTP fix; forcing refresh");
-            mTime.forceRefresh();
+            boolean isSuccessful = mTime.forceRefresh();
+            if (isSuccessful) {
+                mTryAgainCounter = 0;
+            } else {
+                String logMsg = "forceRefresh() returned false: cachedNtpResult=" + cachedNtpResult
+                        + ", currentElapsedRealtimeMillis=" + currentElapsedRealtimeMillis;
+
+                if (DBG) {
+                    Log.d(TAG, logMsg);
+                }
+                mLocalLog.log(logMsg);
+            }
+
             cachedNtpResult = mTime.getCachedTimeResult();
         }
 
-        if (cachedNtpResult != null && cachedNtpResult.getAgeMillis() < mPollingIntervalMs) {
+        if (cachedNtpResult != null
+                && cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis)
+                < mPollingIntervalMs) {
             // Obtained fresh fix; schedule next normal update
-            resetAlarm(mPollingIntervalMs);
+            resetAlarm(mPollingIntervalMs
+                    - cachedNtpResult.getAgeMillis(currentElapsedRealtimeMillis));
 
-            // Suggest the time to the time detector. It may choose use it to set the system clock.
-            TimestampedValue<Long> timeSignal = new TimestampedValue<>(
-                    cachedNtpResult.getElapsedRealtimeMillis(), cachedNtpResult.getTimeMillis());
-            NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
-            timeSuggestion.addDebugInfo("Origin: NetworkTimeUpdateService. event=" + event);
-            mTimeDetector.suggestNetworkTime(timeSuggestion);
+            makeNetworkTimeSuggestion(cachedNtpResult,
+                    "Origin: NetworkTimeUpdateService. event=" + event);
         } else {
             // No fresh fix; schedule retry
             mTryAgainCounter++;
@@ -180,12 +255,26 @@
                 resetAlarm(mPollingIntervalShorterMs);
             } else {
                 // Try much later
+                String logMsg = "mTryAgainTimesMax exceeded, cachedNtpResult=" + cachedNtpResult;
+                if (DBG) {
+                    Log.d(TAG, logMsg);
+                }
+                mLocalLog.log(logMsg);
                 mTryAgainCounter = 0;
                 resetAlarm(mPollingIntervalMs);
             }
         }
     }
 
+    /** Suggests the time to the time detector. It may choose use it to set the system clock. */
+    private void makeNetworkTimeSuggestion(TimeResult ntpResult, String debugInfo) {
+        TimestampedValue<Long> timeSignal = new TimestampedValue<>(
+                ntpResult.getElapsedRealtimeMillis(), ntpResult.getTimeMillis());
+        NetworkTimeSuggestion timeSuggestion = new NetworkTimeSuggestion(timeSignal);
+        timeSuggestion.addDebugInfo(debugInfo);
+        mTimeDetector.suggestNetworkTime(timeSuggestion);
+    }
+
     /**
      * Cancel old alarm and starts a new one for the specified interval.
      *
@@ -274,17 +363,23 @@
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-        pw.print("PollingIntervalMs: ");
-        TimeUtils.formatDuration(mPollingIntervalMs, pw);
-        pw.print("\nPollingIntervalShorterMs: ");
-        TimeUtils.formatDuration(mPollingIntervalShorterMs, pw);
-        pw.println("\nTryAgainTimesMax: " + mTryAgainTimesMax);
-        pw.println("\nTryAgainCounter: " + mTryAgainCounter);
-        NtpTrustedTime.TimeResult ntpResult = mTime.getCachedTimeResult();
-        pw.println("NTP cache result: " + ntpResult);
-        if (ntpResult != null) {
-            pw.println("NTP result age: " + ntpResult.getAgeMillis());
-        }
+        pw.println("mPollingIntervalMs=" + Duration.ofMillis(mPollingIntervalMs));
+        pw.println("mPollingIntervalShorterMs=" + Duration.ofMillis(mPollingIntervalShorterMs));
+        pw.println("mTryAgainTimesMax=" + mTryAgainTimesMax);
+        pw.println("mTryAgainCounter=" + mTryAgainCounter);
         pw.println();
+        pw.println("NtpTrustedTime:");
+        mTime.dump(pw);
+        pw.println();
+        pw.println("Local logs:");
+        mLocalLog.dump(fd, pw, args);
+        pw.println();
+    }
+
+    @Override
+    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+            String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
+        new NetworkTimeUpdateServiceShellCommand(this).exec(
+                this, in, out, err, args, callback, resultReceiver);
     }
 }
diff --git a/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java b/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java
new file mode 100644
index 0000000..464af01
--- /dev/null
+++ b/services/core/java/com/android/server/NetworkTimeUpdateServiceShellCommand.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2022 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.os.ShellCommand;
+
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.util.Objects;
+
+/** Implements the shell command interface for {@link NetworkTimeUpdateService}. */
+class NetworkTimeUpdateServiceShellCommand extends ShellCommand {
+
+    /**
+     * The name of the service.
+     */
+    private static final String SHELL_COMMAND_SERVICE_NAME = "network_time_update_service";
+
+    /**
+     * A shell command that clears the time signal received from the network.
+     */
+    private static final String SHELL_COMMAND_CLEAR_TIME = "clear_time";
+
+    /**
+     * A shell command that forces the time signal to be refreshed from the network.
+     */
+    private static final String SHELL_COMMAND_FORCE_REFRESH = "force_refresh";
+
+    /**
+     * A shell command that sets the NTP server config for tests. Config is cleared on reboot.
+     */
+    private static final String SHELL_COMMAND_SET_SERVER_CONFIG = "set_server_config";
+    private static final String SET_SERVER_CONFIG_HOSTNAME_ARG = "--hostname";
+    private static final String SET_SERVER_CONFIG_TIMEOUT_ARG = "--timeout_millis";
+
+    @NonNull
+    private final NetworkTimeUpdateService mNetworkTimeUpdateService;
+
+    NetworkTimeUpdateServiceShellCommand(NetworkTimeUpdateService networkTimeUpdateService) {
+        mNetworkTimeUpdateService = Objects.requireNonNull(networkTimeUpdateService);
+    }
+
+    @Override
+    public int onCommand(String cmd) {
+        if (cmd == null) {
+            return handleDefaultCommands(cmd);
+        }
+
+        switch (cmd) {
+            case SHELL_COMMAND_CLEAR_TIME:
+                return runClearTime();
+            case SHELL_COMMAND_FORCE_REFRESH:
+                return runForceRefresh();
+            case SHELL_COMMAND_SET_SERVER_CONFIG:
+                return runSetServerConfig();
+            default: {
+                return handleDefaultCommands(cmd);
+            }
+        }
+    }
+
+    private int runClearTime() {
+        mNetworkTimeUpdateService.clearTimeForTests();
+        return 0;
+    }
+
+    private int runForceRefresh() {
+        boolean success = mNetworkTimeUpdateService.forceRefreshForTests();
+        getOutPrintWriter().println(success);
+        return 0;
+    }
+
+    private int runSetServerConfig() {
+        String hostname = null;
+        Duration timeout = null;
+        String opt;
+        while ((opt = getNextArg()) != null) {
+            switch (opt) {
+                case SET_SERVER_CONFIG_HOSTNAME_ARG: {
+                    hostname = getNextArgRequired();
+                    break;
+                }
+                case SET_SERVER_CONFIG_TIMEOUT_ARG: {
+                    timeout = Duration.ofMillis(Integer.parseInt(getNextArgRequired()));
+                    break;
+                }
+                default: {
+                    throw new IllegalArgumentException("Unknown option: " + opt);
+                }
+            }
+        }
+        mNetworkTimeUpdateService.setServerConfigForTests(hostname, timeout);
+        return 0;
+    }
+
+    @Override
+    public void onHelp() {
+        final PrintWriter pw = getOutPrintWriter();
+        pw.printf("Network Time Update Service (%s) commands:\n", SHELL_COMMAND_SERVICE_NAME);
+        pw.printf("  help\n");
+        pw.printf("    Print this help text.\n");
+        pw.printf("  %s\n", SHELL_COMMAND_CLEAR_TIME);
+        pw.printf("    Clears the latest time.\n");
+        pw.printf("  %s\n", SHELL_COMMAND_FORCE_REFRESH);
+        pw.printf("    Refreshes the latest time. Prints whether it was successful.\n");
+        pw.printf("  %s\n", SHELL_COMMAND_SET_SERVER_CONFIG);
+        pw.printf("    Sets the NTP server config for tests. The config is not persisted.\n");
+        pw.printf("      Options: [%s <hostname>] [%s <millis>]\n",
+                SET_SERVER_CONFIG_HOSTNAME_ARG, SET_SERVER_CONFIG_TIMEOUT_ARG);
+        pw.printf("      Each key/value is optional and must be specified to override the\n");
+        pw.printf("      normal value, not specifying a key causes it to reset to the original.\n");
+        pw.println();
+    }
+}
diff --git a/services/core/java/com/android/server/OWNERS b/services/core/java/com/android/server/OWNERS
index 71b463a..f4b8f5d 100644
--- a/services/core/java/com/android/server/OWNERS
+++ b/services/core/java/com/android/server/OWNERS
@@ -23,14 +23,13 @@
 per-file *AppOp* = file:/core/java/android/permission/OWNERS
 per-file *Battery* = file:/BATTERY_STATS_OWNERS
 per-file *Binder* = file:/core/java/com/android/internal/os/BINDER_OWNERS
-per-file *Bluetooth* = file:/core/java/android/bluetooth/OWNERS
 per-file *Gnss* = file:/services/core/java/com/android/server/location/OWNERS
 per-file **IpSec* = file:/services/core/java/com/android/server/net/OWNERS
 per-file **IpSec* = file:/services/core/java/com/android/server/vcn/OWNERS
 per-file *Location* = file:/services/core/java/com/android/server/location/OWNERS
 per-file *Network* = file:/services/core/java/com/android/server/net/OWNERS
 per-file *Storage* = file:/core/java/android/os/storage/OWNERS
-per-file *TimeUpdate* = file:/core/java/android/app/timezone/OWNERS
+per-file *TimeUpdate* = file:/services/core/java/com/android/server/timezonedetector/OWNERS
 per-file DynamicSystemService.java = file:/packages/DynamicSystemInstallationService/OWNERS
 per-file GestureLauncherService.java = file:platform/packages/apps/EmergencyInfo:/OWNERS
 per-file MmsServiceBroker.java = file:/telephony/OWNERS
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index 3cc8e76..f36d11e 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -20,6 +20,8 @@
 import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
 import android.content.pm.UserInfo;
 import android.os.Environment;
 import android.os.SystemClock;
@@ -34,6 +36,7 @@
 import com.android.internal.util.Preconditions;
 import com.android.server.SystemService.TargetUser;
 import com.android.server.am.EventLogTags;
+import com.android.server.pm.ApexManager;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.utils.TimingsTraceAndSlog;
 
@@ -42,6 +45,8 @@
 import java.io.File;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 
 /**
@@ -114,12 +119,31 @@
      * @return The service instance.
      */
     public SystemService startServiceFromJar(String className, String path) {
-        PathClassLoader pathClassLoader = SystemServerClassLoaderFactory.getOrCreateClassLoader(
-                path, this.getClass().getClassLoader());
+        PathClassLoader pathClassLoader =
+                SystemServerClassLoaderFactory.getOrCreateClassLoader(
+                        path, this.getClass().getClassLoader(), isJarInTestApex(path));
         final Class<SystemService> serviceClass = loadClassFromLoader(className, pathClassLoader);
         return startService(serviceClass);
     }
 
+    /**
+     * Returns true if the jar is in a test APEX.
+     */
+    private static boolean isJarInTestApex(String pathStr) {
+        Path path = Paths.get(pathStr);
+        if (path.getNameCount() >= 2 && path.getName(0).toString().equals("apex")) {
+            String apexModuleName = path.getName(1).toString();
+            ApexManager apexManager = ApexManager.getInstance();
+            String packageName = apexManager.getActivePackageNameForApexModuleName(apexModuleName);
+            PackageInfo packageInfo = apexManager.getPackageInfo(
+                    packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
+            if (packageInfo != null) {
+                return (packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0;
+            }
+        }
+        return false;
+    }
+
     /*
      * Loads and initializes a class from the given classLoader. Returns the class.
      */
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index b8ca7c7..4485c5b 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -102,8 +102,6 @@
     /*package*/  static final int SCO_MODE_UNDEFINED = -1;
     // SCO audio mode is virtual voice call (BluetoothHeadset.startScoUsingVirtualVoiceCall())
     /*package*/  static final int SCO_MODE_VIRTUAL_CALL = 0;
-    // SCO audio mode is raw audio (BluetoothHeadset.connectAudio())
-    private  static final int SCO_MODE_RAW = 1;
     // SCO audio mode is Voice Recognition (BluetoothHeadset.startVoiceRecognition())
     private  static final int SCO_MODE_VR = 2;
     // max valid SCO audio mode values
@@ -122,8 +120,6 @@
                 return "SCO_MODE_UNDEFINED";
             case SCO_MODE_VIRTUAL_CALL:
                 return "SCO_MODE_VIRTUAL_CALL";
-            case SCO_MODE_RAW:
-                return "SCO_MODE_RAW";
             case SCO_MODE_VR:
                 return "SCO_MODE_VR";
             default:
@@ -814,8 +810,6 @@
     private static boolean disconnectBluetoothScoAudioHelper(BluetoothHeadset bluetoothHeadset,
             BluetoothDevice device, int scoAudioMode) {
         switch (scoAudioMode) {
-            case SCO_MODE_RAW:
-                return bluetoothHeadset.disconnectAudio();
             case SCO_MODE_VIRTUAL_CALL:
                 return bluetoothHeadset.stopScoUsingVirtualVoiceCall();
             case SCO_MODE_VR:
@@ -828,8 +822,6 @@
     private static boolean connectBluetoothScoAudioHelper(BluetoothHeadset bluetoothHeadset,
             BluetoothDevice device, int scoAudioMode) {
         switch (scoAudioMode) {
-            case SCO_MODE_RAW:
-                return bluetoothHeadset.connectAudio();
             case SCO_MODE_VIRTUAL_CALL:
                 return bluetoothHeadset.startScoUsingVirtualVoiceCall();
             case SCO_MODE_VR:
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 603f206..108e7bc 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -25,7 +25,6 @@
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
 import static android.provider.Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES;
-import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
 import static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN;
@@ -191,6 +190,7 @@
     class MultipathTracker {
         final Network network;
         final String subscriberId;
+        private final int mSubId;
 
         private long mQuota;
         /** Current multipath budget. Nonzero iff we have budget and a UsageCallback is armed. */
@@ -204,9 +204,8 @@
             this.network = network;
             this.mNetworkCapabilities = new NetworkCapabilities(nc);
             NetworkSpecifier specifier = nc.getNetworkSpecifier();
-            int subId = INVALID_SUBSCRIPTION_ID;
             if (specifier instanceof TelephonyNetworkSpecifier) {
-                subId = ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
+                mSubId = ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
             } else {
                 throw new IllegalStateException(String.format(
                         "Can't get subId from mobile network %s (%s)",
@@ -217,14 +216,14 @@
             if (tele == null) {
                 throw new IllegalStateException(String.format("Missing TelephonyManager"));
             }
-            tele = tele.createForSubscriptionId(subId);
+            tele = tele.createForSubscriptionId(mSubId);
             if (tele == null) {
                 throw new IllegalStateException(String.format(
-                        "Can't get TelephonyManager for subId %d", subId));
+                        "Can't get TelephonyManager for subId %d", mSubId));
             }
 
             subscriberId = Objects.requireNonNull(tele.getSubscriberId(),
-                    "Null subscriber Id for subId " + subId);
+                    "Null subscriber Id for subId " + mSubId);
             mNetworkTemplate = new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
                     .setSubscriberIds(Set.of(subscriberId))
                     .setMeteredness(NetworkStats.METERED_YES)
@@ -282,6 +281,7 @@
                     .setSubscriberId(subscriberId)
                     .setRoaming(!nc.hasCapability(NET_CAPABILITY_NOT_ROAMING))
                     .setMetered(!nc.hasCapability(NET_CAPABILITY_NOT_METERED))
+                    .setSubId(mSubId)
                     .build();
         }
 
diff --git a/services/core/java/com/android/server/infra/OWNERS b/services/core/java/com/android/server/infra/OWNERS
new file mode 100644
index 0000000..0466d8a
--- /dev/null
+++ b/services/core/java/com/android/server/infra/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 655446
+
+include /core/java/android/service/cloudsearch/OWNERS
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
index a102406..1203769 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStrongAuth.java
@@ -262,7 +262,7 @@
         long nextAlarmTime = strongAuthTime + dpm.getRequiredStrongAuthTimeout(null, userId);
 
         // schedule a new alarm listener for the user
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime,
+        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextAlarmTime,
                 STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm, mHandler);
     }
 
@@ -303,7 +303,7 @@
             alarm = new NonStrongBiometricTimeoutAlarmListener(userId);
             mNonStrongBiometricTimeoutAlarmListener.put(userId, alarm);
             // schedule a new alarm listener for the user
-            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime,
+            mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextAlarmTime,
                     NON_STRONG_BIOMETRIC_TIMEOUT_ALARM_TAG, alarm, mHandler);
         }
 
@@ -394,7 +394,7 @@
         }
         // schedule a new alarm listener for the user
         if (DEBUG) Slog.d(TAG, "Schedule a new alarm for non-strong biometric idle timeout");
-        mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime,
+        mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextAlarmTime,
                 NON_STRONG_BIOMETRIC_IDLE_TIMEOUT_ALARM_TAG, alarm, mHandler);
     }
 
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 4822d6a..b482d18 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -62,6 +62,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.NoSuchElementException;
 
 /**
  * This is the system implementation of a Session. Apps will interact with the
@@ -792,7 +793,10 @@
         }
         for (ISessionControllerCallbackHolder holder : mControllerCallbackHolders) {
             try {
+                holder.mCallback.asBinder().unlinkToDeath(holder.mDeathMonitor, 0);
                 holder.mCallback.onSessionDestroyed();
+            } catch (NoSuchElementException e) {
+                logCallbackException("error unlinking to binder death", holder, e);
             } catch (DeadObjectException e) {
                 logCallbackException("Removing dead callback in pushSessionDestroyed", holder, e);
             } catch (RemoteException e) {
@@ -1375,12 +1379,22 @@
                     return;
                 }
                 if (getControllerHolderIndexForCb(cb) < 0) {
-                    mControllerCallbackHolders.add(new ISessionControllerCallbackHolder(cb,
-                            packageName, Binder.getCallingUid()));
+                    ISessionControllerCallbackHolder holder = new ISessionControllerCallbackHolder(
+                        cb, packageName, Binder.getCallingUid(), () -> unregisterCallback(cb));
+                    mControllerCallbackHolders.add(holder);
                     if (DEBUG) {
                         Log.d(TAG, "registering controller callback " + cb + " from controller"
                                 + packageName);
                     }
+                    // Avoid callback leaks
+                    try {
+                        // cb is not referenced outside of the MediaSessionRecord, so the death
+                        // handler won't prevent MediaSessionRecord to be garbage collected.
+                        cb.asBinder().linkToDeath(holder.mDeathMonitor, 0);
+                    } catch (RemoteException e) {
+                        unregisterCallback(cb);
+                        Log.w(TAG, "registerCallback failed to linkToDeath", e);
+                    }
                 }
             }
         }
@@ -1390,6 +1404,12 @@
             synchronized (mLock) {
                 int index = getControllerHolderIndexForCb(cb);
                 if (index != -1) {
+                    try {
+                        cb.asBinder().unlinkToDeath(
+                          mControllerCallbackHolders.get(index).mDeathMonitor, 0);
+                    } catch (NoSuchElementException e) {
+                        Log.w(TAG, "error unlinking to binder death", e);
+                    }
                     mControllerCallbackHolders.remove(index);
                 }
                 if (DEBUG) {
@@ -1600,12 +1620,14 @@
         private final ISessionControllerCallback mCallback;
         private final String mPackageName;
         private final int mUid;
+        private final IBinder.DeathRecipient mDeathMonitor;
 
         ISessionControllerCallbackHolder(ISessionControllerCallback callback, String packageName,
-                int uid) {
+                int uid, IBinder.DeathRecipient deathMonitor) {
             mCallback = callback;
             mPackageName = packageName;
             mUid = uid;
+            mDeathMonitor = deathMonitor;
         }
     }
 
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 6a00d06..0a77430 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -61,7 +61,6 @@
 import static android.net.INetd.FIREWALL_RULE_DENY;
 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.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.SNOOZE_NEVER;
 import static android.net.NetworkPolicy.WARNING_DISABLED;
@@ -173,11 +172,9 @@
 import android.net.NetworkPolicyManager;
 import android.net.NetworkPolicyManager.UidState;
 import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
 import android.net.NetworkStack;
 import android.net.NetworkStateSnapshot;
 import android.net.NetworkTemplate;
-import android.net.TelephonyNetworkSpecifier;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiManager;
 import android.os.BestClock;
@@ -284,6 +281,7 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.function.IntConsumer;
 
@@ -993,10 +991,10 @@
             final IntentFilter packageFilter = new IntentFilter();
             packageFilter.addAction(ACTION_PACKAGE_ADDED);
             packageFilter.addDataScheme("package");
-            mContext.registerReceiver(mPackageReceiver, packageFilter, null, mHandler);
+            mContext.registerReceiverForAllUsers(mPackageReceiver, packageFilter, null, mHandler);
 
             // listen for UID changes to update policy
-            mContext.registerReceiver(
+            mContext.registerReceiverForAllUsers(
                     mUidRemovedReceiver, new IntentFilter(ACTION_UID_REMOVED), null, mHandler);
 
             // listen for user changes to update policy
@@ -1006,10 +1004,11 @@
             mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
 
             // listen for stats updated callbacks for interested network types.
+            final Executor executor = new HandlerExecutor(mHandler);
             mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_MOBILE).build(),
-                    0 /* thresholdBytes */, new HandlerExecutor(mHandler), mStatsCallback);
+                    0 /* thresholdBytes */, executor, mStatsCallback);
             mNetworkStats.registerUsageCallback(new NetworkTemplate.Builder(MATCH_WIFI).build(),
-                    0 /* thresholdBytes */, new HandlerExecutor(mHandler), mStatsCallback);
+                    0 /* thresholdBytes */, executor, mStatsCallback);
 
             // listen for restrict background changes from notifications
             final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
@@ -1237,6 +1236,12 @@
          * Used to determine if NetworkStatsService is ready.
          */
         public boolean isAnyCallbackReceived() {
+            // Warning : threading for this member is broken. It should only be read
+            // and written on the handler thread ; furthermore, the constructor
+            // is called on a different thread, so this stops working if the default
+            // value is not false or if this member ever goes back to false after
+            // being set to true.
+            // TODO : fix threading for this member.
             return mIsAnyCallbackReceived;
         }
     };
@@ -1512,7 +1517,8 @@
                     .setType(TYPE_MOBILE)
                     .setSubscriberId(subscriberId)
                     .setMetered(true)
-                    .setDefaultNetwork(true).build();
+                    .setDefaultNetwork(true)
+                    .setSubId(subId).build();
             if (template.matches(probeIdent)) {
                 return subId;
             }
@@ -1749,7 +1755,8 @@
                 .setType(TYPE_MOBILE)
                 .setSubscriberId(subscriberId)
                 .setMetered(true)
-                .setDefaultNetwork(true).build();
+                .setDefaultNetwork(true)
+                .setSubId(subId).build();
         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
             if (template.matches(probeIdent)) {
@@ -1981,7 +1988,8 @@
                             .setType(TYPE_MOBILE)
                             .setSubscriberId(subscriberId)
                             .setMetered(true)
-                            .setDefaultNetwork(true).build();
+                            .setDefaultNetwork(true)
+                            .setSubId(subId).build();
                     // Template is matched when subscriber id matches.
                     if (template.matches(probeIdent)) {
                         matchingSubIds.add(subId);
@@ -2083,7 +2091,8 @@
         mNetIdToSubId.clear();
         final ArrayMap<NetworkStateSnapshot, NetworkIdentity> identified = new ArrayMap<>();
         for (final NetworkStateSnapshot snapshot : snapshots) {
-            mNetIdToSubId.put(snapshot.getNetwork().getNetId(), parseSubId(snapshot));
+            final int subId = snapshot.getSubId();
+            mNetIdToSubId.put(snapshot.getNetwork().getNetId(), subId);
 
             // Policies matched by NPMS only match by subscriber ID or by network ID.
             final NetworkIdentity ident = new NetworkIdentity.Builder()
@@ -2288,7 +2297,8 @@
                 .setType(TYPE_MOBILE)
                 .setSubscriberId(subscriberId)
                 .setMetered(true)
-                .setDefaultNetwork(true).build();
+                .setDefaultNetwork(true)
+                .setSubId(subId).build();
         for (int i = mNetworkPolicy.size() - 1; i >= 0; i--) {
             final NetworkTemplate template = mNetworkPolicy.keyAt(i);
             if (template.matches(probeIdent)) {
@@ -5807,17 +5817,6 @@
         }
     }
 
-    private int parseSubId(@NonNull NetworkStateSnapshot snapshot) {
-        int subId = INVALID_SUBSCRIPTION_ID;
-        if (snapshot.getNetworkCapabilities().hasTransport(TRANSPORT_CELLULAR)) {
-            NetworkSpecifier spec = snapshot.getNetworkCapabilities().getNetworkSpecifier();
-            if (spec instanceof TelephonyNetworkSpecifier) {
-                subId = ((TelephonyNetworkSpecifier) spec).getSubscriptionId();
-            }
-        }
-        return subId;
-    }
-
     @GuardedBy("mNetworkPoliciesSecondLock")
     private int getSubIdLocked(Network network) {
         return mNetIdToSubId.get(network.getNetId(), INVALID_SUBSCRIPTION_ID);
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 31b1860..e7e691c 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -343,6 +343,13 @@
     public abstract String getApexModuleNameForPackageName(String apexPackageName);
 
     /**
+     * Returns the package name of the active APEX whose name is {@code apexModuleName}. If not
+     * found, returns {@code null}.
+     */
+    @Nullable
+    public abstract String getActivePackageNameForApexModuleName(String apexModuleName);
+
+    /**
      * Copies the CE apex data directory for the given {@code userId} to a backup location, for use
      * in case of rollback.
      *
@@ -467,6 +474,12 @@
         private ArrayMap<String, String> mPackageNameToApexModuleName;
 
         /**
+         * Reverse mapping of {@link #mPackageNameToApexModuleName}, for active packages only.
+         */
+        @GuardedBy("mLock")
+        private ArrayMap<String, String> mApexModuleNameToActivePackageName;
+
+        /**
          * Whether an APEX package is active or not.
          *
          * @param packageInfo the package to check
@@ -534,6 +547,7 @@
             try {
                 mAllPackagesCache = new ArrayList<>();
                 mPackageNameToApexModuleName = new ArrayMap<>();
+                mApexModuleNameToActivePackageName = new ArrayMap<>();
                 allPkgs = waitForApexService().getAllPackages();
             } catch (RemoteException re) {
                 Slog.e(TAG, "Unable to retrieve packages from apexservice: " + re.toString());
@@ -580,6 +594,13 @@
                                             + packageInfo.packageName);
                         }
                         activePackagesSet.add(packageInfo.packageName);
+                        if (mApexModuleNameToActivePackageName.containsKey(ai.moduleName)) {
+                            throw new IllegalStateException(
+                                    "Two active packages have the same APEX module name: "
+                                            + ai.moduleName);
+                        }
+                        mApexModuleNameToActivePackageName.put(
+                                ai.moduleName, packageInfo.packageName);
                     }
                     if (ai.isFactory) {
                         // Don't throw when the duplicating APEX is VNDK APEX
@@ -913,6 +934,16 @@
         }
 
         @Override
+        @Nullable
+        public String getActivePackageNameForApexModuleName(String apexModuleName) {
+            synchronized (mLock) {
+                Preconditions.checkState(mApexModuleNameToActivePackageName != null,
+                        "APEX packages have not been scanned");
+                return mApexModuleNameToActivePackageName.get(apexModuleName);
+            }
+        }
+
+        @Override
         public boolean snapshotCeData(int userId, int rollbackId, String apexPackageName) {
             String apexModuleName;
             synchronized (mLock) {
@@ -1330,6 +1361,12 @@
         }
 
         @Override
+        @Nullable
+        public String getActivePackageNameForApexModuleName(String apexModuleName) {
+            return null;
+        }
+
+        @Override
         public boolean snapshotCeData(int userId, int rollbackId, String apexPackageName) {
             throw new UnsupportedOperationException();
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2d3cbfe..bc6c306 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -12908,7 +12908,8 @@
                 DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
                 DexoptOptions.DEXOPT_BOOT_COMPLETE |
                 (force ? DexoptOptions.DEXOPT_FORCE : 0);
-        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
+        return performDexOpt(new DexoptOptions(packageName, REASON_CMDLINE,
+                compilerFilter, /* splitName */ null, flags));
     }
 
     /*package*/ boolean performDexOpt(DexoptOptions options) {
diff --git a/services/core/java/com/android/server/pm/parsing/library/ApexSharedLibraryUpdater.java b/services/core/java/com/android/server/pm/parsing/library/ApexSharedLibraryUpdater.java
new file mode 100644
index 0000000..0418afb
--- /dev/null
+++ b/services/core/java/com/android/server/pm/parsing/library/ApexSharedLibraryUpdater.java
@@ -0,0 +1,67 @@
+/*
+ * 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.parsing.library;
+
+import android.util.ArrayMap;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.SystemConfig;
+import com.android.server.pm.parsing.pkg.ParsedPackage;
+
+/**
+ * Updates packages to add or remove dependencies on shared libraries as per attributes
+ * in the library declaration
+ *
+ * @hide
+ */
+@VisibleForTesting
+public class ApexSharedLibraryUpdater extends PackageSharedLibraryUpdater {
+
+    /**
+     * ArrayMap like the one you find in {@link SystemConfig}. The keys are the library names.
+     */
+    private final ArrayMap<String, SystemConfig.SharedLibraryEntry> mSharedLibraries;
+
+    public ApexSharedLibraryUpdater(
+            ArrayMap<String, SystemConfig.SharedLibraryEntry> sharedLibraries) {
+        mSharedLibraries = sharedLibraries;
+    }
+
+    @Override
+    public void updatePackage(ParsedPackage parsedPackage, boolean isUpdatedSystemApp) {
+        final int builtInLibCount = mSharedLibraries.size();
+        for (int i = 0; i < builtInLibCount; i++) {
+            updateSharedLibraryForPackage(mSharedLibraries.valueAt(i), parsedPackage);
+        }
+    }
+
+    private void updateSharedLibraryForPackage(SystemConfig.SharedLibraryEntry entry,
+            ParsedPackage parsedPackage) {
+        if (entry.onBootclasspathBefore != 0
+                && parsedPackage.getTargetSdkVersion() < entry.onBootclasspathBefore) {
+            // this package targets an API where this library was in the BCP, so add
+            // the library transparently in case the package is using it
+            prefixRequiredLibrary(parsedPackage, entry.name);
+        }
+
+        if (entry.canBeSafelyIgnored) {
+            // the library is now present in the BCP and always available; we don't need to add
+            // it a second time
+            removeLibrary(parsedPackage, entry.name);
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/parsing/library/PackageBackwardCompatibility.java b/services/core/java/com/android/server/pm/parsing/library/PackageBackwardCompatibility.java
index 8a8a302..d81e7d0 100644
--- a/services/core/java/com/android/server/pm/parsing/library/PackageBackwardCompatibility.java
+++ b/services/core/java/com/android/server/pm/parsing/library/PackageBackwardCompatibility.java
@@ -25,6 +25,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.SystemConfig;
 import com.android.server.pm.parsing.pkg.ParsedPackage;
 
 import java.util.ArrayList;
@@ -63,6 +64,11 @@
 
         boolean bootClassPathContainsATB = !addUpdaterForAndroidTestBase(packageUpdaters);
 
+        // ApexSharedLibraryUpdater should be the last one, to allow modifications introduced by
+        // mainline after dessert release.
+        packageUpdaters.add(new ApexSharedLibraryUpdater(
+                SystemConfig.getInstance().getSharedLibraries()));
+
         PackageSharedLibraryUpdater[] updaterArray = packageUpdaters
                 .toArray(new PackageSharedLibraryUpdater[0]);
         INSTANCE = new PackageBackwardCompatibility(
@@ -106,6 +112,11 @@
 
     private final PackageSharedLibraryUpdater[] mPackageUpdaters;
 
+    @VisibleForTesting
+    PackageSharedLibraryUpdater[] getPackageUpdaters() {
+        return mPackageUpdaters;
+    }
+
     private PackageBackwardCompatibility(
             boolean bootClassPathContainsATB, PackageSharedLibraryUpdater[] packageUpdaters) {
         this.mBootClassPathContainsATB = bootClassPathContainsATB;
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 1fa948c..9cf38e3 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -2609,6 +2609,7 @@
         StatFs statFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
         StatFs statFsSystem = new StatFs(Environment.getRootDirectory().getAbsolutePath());
         StatFs statFsCache = new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
+        StatFs metadataFsSystem = new StatFs(Environment.getMetadataDirectory().getAbsolutePath());
 
         pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag,
                 FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__DATA, statFsData.getAvailableBytes(),
@@ -2621,6 +2622,10 @@
         pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag,
                 FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__SYSTEM,
                 statFsSystem.getAvailableBytes(), statFsSystem.getTotalBytes()));
+
+        pulledData.add(FrameworkStatsLog.buildStatsEvent(atomTag,
+                FrameworkStatsLog.DIRECTORY_USAGE__DIRECTORY__METADATA,
+                metadataFsSystem.getAvailableBytes(), metadataFsSystem.getTotalBytes()));
         return StatsManager.PULL_SUCCESS;
     }
 
diff --git a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
index 357c232..ae4d46c 100644
--- a/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timedetector/TimeDetectorStrategyImpl.java
@@ -69,7 +69,7 @@
      * Telephony and network suggestions older than this value are considered too old to be used.
      */
     @VisibleForTesting
-    static final long MAX_UTC_TIME_AGE_MILLIS =
+    static final long MAX_SUGGESTION_TIME_AGE_MILLIS =
             TELEPHONY_BUCKET_COUNT * TELEPHONY_BUCKET_SIZE_MILLIS;
 
     /**
@@ -204,9 +204,9 @@
 
     @Override
     public synchronized void suggestExternalTime(@NonNull ExternalTimeSuggestion timeSuggestion) {
-        final TimestampedValue<Long> newUtcTime = timeSuggestion.getUtcTime();
+        final TimestampedValue<Long> newUnixEpochTime = timeSuggestion.getUnixEpochTime();
 
-        if (!validateAutoSuggestionTime(newUtcTime, timeSuggestion)) {
+        if (!validateAutoSuggestionTime(newUnixEpochTime, timeSuggestion)) {
             return;
         }
 
@@ -218,9 +218,9 @@
 
     @Override
     public synchronized void suggestGnssTime(@NonNull GnssTimeSuggestion timeSuggestion) {
-        final TimestampedValue<Long> newUtcTime = timeSuggestion.getUtcTime();
+        final TimestampedValue<Long> newUnixEpochTime = timeSuggestion.getUnixEpochTime();
 
-        if (!validateAutoSuggestionTime(newUtcTime, timeSuggestion)) {
+        if (!validateAutoSuggestionTime(newUnixEpochTime, timeSuggestion)) {
             return;
         }
 
@@ -232,19 +232,19 @@
 
     @Override
     public synchronized boolean suggestManualTime(@NonNull ManualTimeSuggestion suggestion) {
-        final TimestampedValue<Long> newUtcTime = suggestion.getUtcTime();
+        final TimestampedValue<Long> newUnixEpochTime = suggestion.getUnixEpochTime();
 
-        if (!validateSuggestionTime(newUtcTime, suggestion)) {
+        if (!validateSuggestionTime(newUnixEpochTime, suggestion)) {
             return false;
         }
 
         String cause = "Manual time suggestion received: suggestion=" + suggestion;
-        return setSystemClockIfRequired(ORIGIN_MANUAL, newUtcTime, cause);
+        return setSystemClockIfRequired(ORIGIN_MANUAL, newUnixEpochTime, cause);
     }
 
     @Override
     public synchronized void suggestNetworkTime(@NonNull NetworkTimeSuggestion timeSuggestion) {
-        if (!validateAutoSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) {
+        if (!validateAutoSuggestionTime(timeSuggestion.getUnixEpochTime(), timeSuggestion)) {
             return;
         }
 
@@ -274,11 +274,11 @@
         // unlike time zone, where a user may lose connectivity when boarding a flight and where we
         // do want to "forget" old signals. Suggestions that are too old are discarded later in the
         // detection algorithm.
-        if (timeSuggestion.getUtcTime() == null) {
+        if (timeSuggestion.getUnixEpochTime() == null) {
             return;
         }
 
-        if (!validateAutoSuggestionTime(timeSuggestion.getUtcTime(), timeSuggestion)) {
+        if (!validateAutoSuggestionTime(timeSuggestion.getUnixEpochTime(), timeSuggestion)) {
             return;
         }
 
@@ -365,14 +365,14 @@
     @GuardedBy("this")
     private boolean storeTelephonySuggestion(
             @NonNull TelephonyTimeSuggestion suggestion) {
-        TimestampedValue<Long> newUtcTime = suggestion.getUtcTime();
+        TimestampedValue<Long> newUnixEpochTime = suggestion.getUnixEpochTime();
 
         int slotIndex = suggestion.getSlotIndex();
         TelephonyTimeSuggestion previousSuggestion = mSuggestionBySlotIndex.get(slotIndex);
         if (previousSuggestion != null) {
             // We can log / discard suggestions with obvious issues with the reference time clock.
-            if (previousSuggestion.getUtcTime() == null
-                    || previousSuggestion.getUtcTime().getValue() == null) {
+            if (previousSuggestion.getUnixEpochTime() == null
+                    || previousSuggestion.getUnixEpochTime().getValue() == null) {
                 // This should be impossible given we only store validated suggestions.
                 Slog.w(LOG_TAG, "Previous suggestion is null or has a null time."
                         + " previousSuggestion=" + previousSuggestion
@@ -381,7 +381,7 @@
             }
 
             long referenceTimeDifference = TimestampedValue.referenceTimeDifference(
-                    newUtcTime, previousSuggestion.getUtcTime());
+                    newUnixEpochTime, previousSuggestion.getUnixEpochTime());
             if (referenceTimeDifference < 0) {
                 // The reference time is before the previously received suggestion. Ignore it.
                 Slog.w(LOG_TAG, "Out of order telephony suggestion received."
@@ -398,15 +398,15 @@
     }
 
     private boolean validateSuggestionTime(
-            @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) {
-        if (newUtcTime.getValue() == null) {
+            @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) {
+        if (newUnixEpochTime.getValue() == null) {
             Slog.w(LOG_TAG, "Suggested time value is null. suggestion=" + suggestion);
             return false;
         }
 
         // We can validate the suggestion against the reference time clock.
         long elapsedRealtimeMillis = mEnvironment.elapsedRealtimeMillis();
-        if (elapsedRealtimeMillis < newUtcTime.getReferenceTimeMillis()) {
+        if (elapsedRealtimeMillis < newUnixEpochTime.getReferenceTimeMillis()) {
             // elapsedRealtime clock went backwards?
             Slog.w(LOG_TAG, "New reference time is in the future? Ignoring."
                     + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
@@ -417,17 +417,17 @@
     }
 
     private boolean validateAutoSuggestionTime(
-            @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion)  {
-        return validateSuggestionTime(newUtcTime, suggestion)
-                && validateSuggestionAgainstLowerBound(newUtcTime, suggestion);
+            @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion)  {
+        return validateSuggestionTime(newUnixEpochTime, suggestion)
+                && validateSuggestionAgainstLowerBound(newUnixEpochTime, suggestion);
     }
 
     private boolean validateSuggestionAgainstLowerBound(
-            @NonNull TimestampedValue<Long> newUtcTime, @NonNull Object suggestion) {
+            @NonNull TimestampedValue<Long> newUnixEpochTime, @NonNull Object suggestion) {
         Instant lowerBound = mEnvironment.autoTimeLowerBound();
 
         // Suggestion is definitely wrong if it comes before lower time bound.
-        if (lowerBound.isAfter(Instant.ofEpochMilli(newUtcTime.getValue()))) {
+        if (lowerBound.isAfter(Instant.ofEpochMilli(newUnixEpochTime.getValue()))) {
             Slog.w(LOG_TAG, "Suggestion points to time before lower bound, skipping it. "
                     + "suggestion=" + suggestion + ", lower bound=" + lowerBound);
             return false;
@@ -446,12 +446,12 @@
         // Try the different origins one at a time.
         int[] originPriorities = mEnvironment.autoOriginPriorities();
         for (int origin : originPriorities) {
-            TimestampedValue<Long> newUtcTime = null;
+            TimestampedValue<Long> newUnixEpochTime = null;
             String cause = null;
             if (origin == ORIGIN_TELEPHONY) {
                 TelephonyTimeSuggestion bestTelephonySuggestion = findBestTelephonySuggestion();
                 if (bestTelephonySuggestion != null) {
-                    newUtcTime = bestTelephonySuggestion.getUtcTime();
+                    newUnixEpochTime = bestTelephonySuggestion.getUnixEpochTime();
                     cause = "Found good telephony suggestion."
                             + ", bestTelephonySuggestion=" + bestTelephonySuggestion
                             + ", detectionReason=" + detectionReason;
@@ -459,7 +459,7 @@
             } else if (origin == ORIGIN_NETWORK) {
                 NetworkTimeSuggestion networkSuggestion = findLatestValidNetworkSuggestion();
                 if (networkSuggestion != null) {
-                    newUtcTime = networkSuggestion.getUtcTime();
+                    newUnixEpochTime = networkSuggestion.getUnixEpochTime();
                     cause = "Found good network suggestion."
                             + ", networkSuggestion=" + networkSuggestion
                             + ", detectionReason=" + detectionReason;
@@ -467,7 +467,7 @@
             } else if (origin == ORIGIN_GNSS) {
                 GnssTimeSuggestion gnssTimeSuggestion = findLatestValidGnssSuggestion();
                 if (gnssTimeSuggestion != null) {
-                    newUtcTime = gnssTimeSuggestion.getUtcTime();
+                    newUnixEpochTime = gnssTimeSuggestion.getUnixEpochTime();
                     cause = "Found good gnss suggestion."
                             + ", gnssTimeSuggestion=" + gnssTimeSuggestion
                             + ", detectionReason=" + detectionReason;
@@ -475,7 +475,7 @@
             } else if (origin == ORIGIN_EXTERNAL) {
                 ExternalTimeSuggestion externalTimeSuggestion = findLatestValidExternalSuggestion();
                 if (externalTimeSuggestion != null) {
-                    newUtcTime = externalTimeSuggestion.getUtcTime();
+                    newUnixEpochTime = externalTimeSuggestion.getUnixEpochTime();
                     cause = "Found good external suggestion."
                             + ", externalTimeSuggestion=" + externalTimeSuggestion
                             + ", detectionReason=" + detectionReason;
@@ -487,8 +487,8 @@
             }
 
             // Update the system clock if a good suggestion has been found.
-            if (newUtcTime != null) {
-                setSystemClockIfRequired(origin, newUtcTime, cause);
+            if (newUnixEpochTime != null) {
+                setSystemClockIfRequired(origin, newUnixEpochTime, cause);
                 return;
             }
         }
@@ -545,7 +545,7 @@
                 Slog.w(LOG_TAG, "Latest suggestion unexpectedly null for slotIndex."
                         + " slotIndex=" + slotIndex);
                 continue;
-            } else if (candidateSuggestion.getUtcTime() == null) {
+            } else if (candidateSuggestion.getUnixEpochTime() == null) {
                 // Unexpected - we do not store empty suggestions.
                 Slog.w(LOG_TAG, "Latest suggestion unexpectedly empty. "
                         + " candidateSuggestion=" + candidateSuggestion);
@@ -579,8 +579,8 @@
             long elapsedRealtimeMillis, @NonNull TelephonyTimeSuggestion timeSuggestion) {
 
         // Validate first.
-        TimestampedValue<Long> utcTime = timeSuggestion.getUtcTime();
-        if (!validateSuggestionUtcTime(elapsedRealtimeMillis, utcTime)) {
+        TimestampedValue<Long> unixEpochTime = timeSuggestion.getUnixEpochTime();
+        if (!validateSuggestionUnixEpochTime(elapsedRealtimeMillis, unixEpochTime)) {
             Slog.w(LOG_TAG, "Existing suggestion found to be invalid"
                     + " elapsedRealtimeMillis=" + elapsedRealtimeMillis
                     + ", timeSuggestion=" + timeSuggestion);
@@ -589,7 +589,7 @@
 
         // The score is based on the age since receipt. Suggestions are bucketed so two
         // suggestions in the same bucket from different slotIndexs are scored the same.
-        long ageMillis = elapsedRealtimeMillis - utcTime.getReferenceTimeMillis();
+        long ageMillis = elapsedRealtimeMillis - unixEpochTime.getReferenceTimeMillis();
 
         // Turn the age into a discrete value: 0 <= bucketIndex < TELEPHONY_BUCKET_COUNT.
         int bucketIndex = (int) (ageMillis / TELEPHONY_BUCKET_SIZE_MILLIS);
@@ -611,9 +611,9 @@
             return null;
         }
 
-        TimestampedValue<Long> utcTime = networkSuggestion.getUtcTime();
+        TimestampedValue<Long> unixEpochTime = networkSuggestion.getUnixEpochTime();
         long elapsedRealTimeMillis = mEnvironment.elapsedRealtimeMillis();
-        if (!validateSuggestionUtcTime(elapsedRealTimeMillis, utcTime)) {
+        if (!validateSuggestionUnixEpochTime(elapsedRealTimeMillis, unixEpochTime)) {
             // The latest suggestion is not valid, usually due to its age.
             return null;
         }
@@ -631,9 +631,9 @@
             return null;
         }
 
-        TimestampedValue<Long> utcTime = gnssTimeSuggestion.getUtcTime();
+        TimestampedValue<Long> unixEpochTime = gnssTimeSuggestion.getUnixEpochTime();
         long elapsedRealTimeMillis = mEnvironment.elapsedRealtimeMillis();
-        if (!validateSuggestionUtcTime(elapsedRealTimeMillis, utcTime)) {
+        if (!validateSuggestionUnixEpochTime(elapsedRealTimeMillis, unixEpochTime)) {
             // The latest suggestion is not valid, usually due to its age.
             return null;
         }
@@ -651,9 +651,9 @@
             return null;
         }
 
-        TimestampedValue<Long> utcTime = externalTimeSuggestion.getUtcTime();
+        TimestampedValue<Long> unixEpochTime = externalTimeSuggestion.getUnixEpochTime();
         long elapsedRealTimeMillis = mEnvironment.elapsedRealtimeMillis();
-        if (!validateSuggestionUtcTime(elapsedRealTimeMillis, utcTime)) {
+        if (!validateSuggestionUnixEpochTime(elapsedRealTimeMillis, unixEpochTime)) {
             // The latest suggestion is not valid, usually due to its age.
             return null;
         }
@@ -844,9 +844,9 @@
         return mLastExternalSuggestion.get();
     }
 
-    private static boolean validateSuggestionUtcTime(
-            long elapsedRealtimeMillis, TimestampedValue<Long> utcTime) {
-        long referenceTimeMillis = utcTime.getReferenceTimeMillis();
+    private static boolean validateSuggestionUnixEpochTime(
+            long elapsedRealtimeMillis, TimestampedValue<Long> unixEpochTime) {
+        long referenceTimeMillis = unixEpochTime.getReferenceTimeMillis();
         if (referenceTimeMillis > elapsedRealtimeMillis) {
             // Future reference times are ignored. They imply the reference time was wrong, or the
             // elapsed realtime clock used to derive it has gone backwards, neither of which are
@@ -860,6 +860,6 @@
         // made and never replaced, it could also mean that the time detection code remains
         // opinionated using a bad invalid suggestion. This caps that edge case at MAX_AGE_MILLIS.
         long ageMillis = elapsedRealtimeMillis - referenceTimeMillis;
-        return ageMillis <= MAX_UTC_TIME_AGE_MILLIS;
+        return ageMillis <= MAX_SUGGESTION_TIME_AGE_MILLIS;
     }
 }
diff --git a/services/core/java/com/android/server/timezonedetector/OWNERS b/services/core/java/com/android/server/timezonedetector/OWNERS
index 0293242..485a0dd 100644
--- a/services/core/java/com/android/server/timezonedetector/OWNERS
+++ b/services/core/java/com/android/server/timezonedetector/OWNERS
@@ -3,5 +3,6 @@
 # ultimately referenced by other OWNERS files for components maintained by the same team.
 nfuller@google.com
 jmorace@google.com
+kanyinsola@google.com
 mingaleev@google.com
 narayan@google.com
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index e48b5e1..e755b9e 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -47,7 +47,6 @@
         "com_android_server_lights_LightsService.cpp",
         "com_android_server_location_GnssLocationProvider.cpp",
         "com_android_server_locksettings_SyntheticPasswordManager.cpp",
-        "com_android_server_net_NetworkStatsService.cpp",
         "com_android_server_power_PowerManagerService.cpp",
         "com_android_server_powerstats_PowerStatsService.cpp",
         "com_android_server_hint_HintManagerService.cpp",
@@ -73,7 +72,6 @@
         "com_android_server_sensor_SensorService.cpp",
         "onload.cpp",
         ":lib_cachedAppOptimizer_native",
-        ":lib_networkStatsFactory_native",
     ],
 
     include_dirs: [
@@ -85,7 +83,6 @@
 
     header_libs: [
         "bionic_libc_platform_headers",
-        "bpf_connectivity_headers",
     ],
 }
 
@@ -140,9 +137,6 @@
         "libhidlbase",
         "libutils",
         "libhwui",
-        "libbpf_android",
-        "libnetdutils",
-        "libnetworkstats",
         "libpsi",
         "libdataloader",
         "libincfs",
@@ -205,13 +199,6 @@
 }
 
 filegroup {
-    name: "lib_networkStatsFactory_native",
-    srcs: [
-        "com_android_server_net_NetworkStatsFactory.cpp",
-    ],
-}
-
-filegroup {
     name: "lib_cachedAppOptimizer_native",
     srcs: [
         "com_android_server_am_CachedAppOptimizer.cpp",
diff --git a/services/core/jni/onload.cpp b/services/core/jni/onload.cpp
index ff61abc..9d3edd6 100644
--- a/services/core/jni/onload.cpp
+++ b/services/core/jni/onload.cpp
@@ -51,8 +51,6 @@
 int register_android_server_HardwarePropertiesManagerService(JNIEnv* env);
 int register_android_server_SyntheticPasswordManager(JNIEnv* env);
 int register_android_hardware_display_DisplayViewport(JNIEnv* env);
-int register_android_server_net_NetworkStatsFactory(JNIEnv* env);
-int register_android_server_net_NetworkStatsService(JNIEnv* env);
 int register_android_server_am_CachedAppOptimizer(JNIEnv* env);
 int register_android_server_am_LowMemDetector(JNIEnv* env);
 int register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(JNIEnv* env);
@@ -107,8 +105,6 @@
     register_android_server_SyntheticPasswordManager(env);
     register_android_graphics_GraphicsStatsService(env);
     register_android_hardware_display_DisplayViewport(env);
-    register_android_server_net_NetworkStatsFactory(env);
-    register_android_server_net_NetworkStatsService(env);
     register_android_server_am_CachedAppOptimizer(env);
     register_android_server_am_LowMemDetector(env);
     register_com_android_server_soundtrigger_middleware_AudioSessionProviderImpl(env);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index ad97dd1..4825f09 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -54,7 +54,6 @@
 import android.net.ConnectivityManager;
 import android.net.ConnectivityModuleConnector;
 import android.net.NetworkStackClient;
-import android.net.TrafficStats;
 import android.os.BaseBundle;
 import android.os.Binder;
 import android.os.Build;
@@ -141,7 +140,6 @@
 import com.android.server.media.metrics.MediaMetricsManagerService;
 import com.android.server.media.projection.MediaProjectionManagerService;
 import com.android.server.net.NetworkPolicyManagerService;
-import com.android.server.net.NetworkStatsService;
 import com.android.server.net.watchlist.NetworkWatchlistService;
 import com.android.server.notification.NotificationManagerService;
 import com.android.server.oemlock.OemLockService;
@@ -379,6 +377,8 @@
             "com.android.server.media.MediaResourceMonitorService";
     private static final String CONNECTIVITY_SERVICE_INITIALIZER_CLASS =
             "com.android.server.ConnectivityServiceInitializer";
+    private static final String NETWORK_STATS_SERVICE_INITIALIZER_CLASS =
+            "com.android.server.NetworkStatsServiceInitializer";
     private static final String IP_CONNECTIVITY_METRICS_CLASS =
             "com.android.server.connectivity.IpConnectivityMetrics";
     private static final String MEDIA_COMMUNICATION_SERVICE_CLASS =
@@ -1336,7 +1336,6 @@
         NetworkManagementService networkManagement = null;
         VpnManagerService vpnManager = null;
         VcnManagementService vcnManagement = null;
-        NetworkStatsService networkStats = null;
         NetworkPolicyManagerService networkPolicy = null;
         WindowManagerService wm = null;
         SerialService serial = null;
@@ -1825,13 +1824,10 @@
             t.traceEnd();
 
             t.traceBegin("StartNetworkStatsService");
-            try {
-                networkStats = NetworkStatsService.create(context);
-                ServiceManager.addService(Context.NETWORK_STATS_SERVICE, networkStats);
-                TrafficStats.init(context);
-            } catch (Throwable e) {
-                reportWtf("starting NetworkStats Service", e);
-            }
+            // This has to be called before NetworkPolicyManager because NetworkPolicyManager
+            // needs to take NetworkStatsService to initialize.
+            mSystemServiceManager.startServiceFromJar(NETWORK_STATS_SERVICE_INITIALIZER_CLASS,
+                    CONNECTIVITY_SERVICE_APEX_PATH);
             t.traceEnd();
 
             t.traceBegin("StartNetworkPolicyManagerService");
@@ -2648,7 +2644,6 @@
 
         // These are needed to propagate to the runnable below.
         final NetworkManagementService networkManagementF = networkManagement;
-        final NetworkStatsService networkStatsF = networkStats;
         final NetworkPolicyManagerService networkPolicyF = networkPolicy;
         final CountryDetectorService countryDetectorF = countryDetector;
         final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
@@ -2745,15 +2740,6 @@
                         .networkScoreAndNetworkManagementServiceReady();
             }
             t.traceEnd();
-            t.traceBegin("MakeNetworkStatsServiceReady");
-            try {
-                if (networkStatsF != null) {
-                    networkStatsF.systemReady();
-                }
-            } catch (Throwable e) {
-                reportWtf("making Network Stats Service ready", e);
-            }
-            t.traceEnd();
             t.traceBegin("MakeConnectivityServiceReady");
             try {
                 if (connectivityF != null) {
diff --git a/services/proguard.flags b/services/proguard.flags
index 0e081f1..425da6c 100644
--- a/services/proguard.flags
+++ b/services/proguard.flags
@@ -40,9 +40,15 @@
 # Global entities normally kept through explicit Manifest entries
 # TODO(b/210510433): Revisit and consider generating from frameworks/base/core/res/AndroidManifest.xml,
 # by including that manifest with the library rule that triggers optimization.
--keep,allowoptimization,allowaccessmodification class * extends android.app.backup.BackupAgent
--keep,allowoptimization,allowaccessmodification class * extends android.content.BroadcastReceiver
--keep,allowoptimization,allowaccessmodification class * extends android.content.ContentProvider
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.app.Activity
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.app.Service
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.app.backup.BackupAgent
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.content.BroadcastReceiver
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.content.ContentProvider
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.preference.Preference
+-keep,allowoptimization,allowaccessmodification class com.android.server.** extends android.view.View {
+  public <init>(...);
+}
 
 # Various classes subclassed in or referenced via JNI in ethernet-service
 -keep public class android.net.** { *; }
@@ -67,6 +73,7 @@
 -keep,allowoptimization,allowaccessmodification class com.android.server.location.gnss.GnssConfiguration$HalInterfaceVersion { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.location.gnss.GnssPowerStats { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.location.gnss.hal.GnssNative { *; }
+-keep,allowoptimization,allowaccessmodification class com.android.server.pm.PackageManagerShellCommandDataLoader { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.sensors.SensorManagerInternal$ProximityActiveListener { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.sensors.SensorService { *; }
 -keep,allowoptimization,allowaccessmodification class com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareImpl$AudioSessionProvider$AudioSession { *; }
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java
index acb20ed..6de7fdd 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStrongAuthTest.java
@@ -229,8 +229,8 @@
     }
 
     private void verifyAlarm(long when, String tag, AlarmManager.OnAlarmListener alarm) {
-        verify(mAlarmManager).set(
-                eq(AlarmManager.ELAPSED_REALTIME),
+        verify(mAlarmManager).setExact(
+                eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
                 eq(when),
                 eq(tag),
                 eq(alarm),
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 94cf20f..1393d39 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -504,6 +504,7 @@
                 ArgumentCaptor.forClass(NetworkStatsManager.UsageCallback.class);
         verify(mStatsManager, times(2))
                 .registerUsageCallback(any(), anyLong(), any(), usageObserver.capture());
+        // It doesn't matter which of the observers is returned here.
         usageObserver.getValue().onThresholdReached(
                 new NetworkTemplate.Builder(MATCH_MOBILE).build());
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
index 2bda120..f99f65e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ApexManagerTest.java
@@ -489,6 +489,20 @@
         assertThat(e).hasMessageThat().contains("Failed to collect certificates from ");
     }
 
+    @Test
+    public void testGetActivePackageNameForApexModuleName() throws Exception {
+        final String moduleName = "com.android.module_name";
+
+        ApexInfo[] apexInfo = createApexInfoForTestPkg(true, false);
+        apexInfo[0].moduleName = moduleName;
+        when(mApexService.getAllPackages()).thenReturn(apexInfo);
+        mApexManager.scanApexPackagesTraced(mPackageParser2,
+                ParallelPackageParser.makeExecutorService());
+
+        assertThat(mApexManager.getActivePackageNameForApexModuleName(moduleName))
+                .isEqualTo(TEST_APEX_PKG);
+    }
+
     private ApexInfo[] createApexInfoForTestPkg(boolean isActive, boolean isFactory) {
         File apexFile = extractResource(TEST_APEX_PKG,  TEST_APEX_FILE_NAME);
         ApexInfo apexInfo = new ApexInfo();
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java
new file mode 100644
index 0000000..1d9ea4b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/library/ApexSharedLibraryUpdaterTest.java
@@ -0,0 +1,281 @@
+/*
+ * 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.parsing.library;
+
+import android.os.Build;
+import android.platform.test.annotations.Presubmit;
+import android.util.ArrayMap;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.server.SystemConfig;
+import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.parsing.pkg.PackageImpl;
+import com.android.server.pm.parsing.pkg.ParsedPackage;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+
+/**
+ * Test for {@link ApexSharedLibraryUpdater}
+ */
+@Presubmit
+@SmallTest
+@RunWith(JUnit4.class)
+public class ApexSharedLibraryUpdaterTest extends PackageSharedLibraryUpdaterTest {
+
+    private final ArrayMap<String, SystemConfig.SharedLibraryEntry> mSharedLibraries =
+            new ArrayMap<>(8);
+
+    @Before
+    public void setUp() throws Exception {
+        installSharedLibraries();
+    }
+
+    private void installSharedLibraries() throws Exception {
+        mSharedLibraries.clear();
+        insertLibrary("foo", 0, 0);
+        insertLibrary("fooBcpSince30", 30, 0);
+        insertLibrary("fooBcpBefore30", 0, 30);
+        insertLibrary("fooFromFuture", Build.VERSION.SDK_INT + 2, 0);
+    }
+
+    private void insertLibrary(String libraryName, int onBootclasspathSince,
+            int onBootclasspathBefore) {
+        mSharedLibraries.put(libraryName, new SystemConfig.SharedLibraryEntry(
+                libraryName,
+                "foo.jar",
+                new String[0] /* dependencies */,
+                onBootclasspathSince,
+                onBootclasspathBefore
+                )
+        );
+    }
+
+    @Test
+    public void testRegularAppOnRPlus() {
+        // platform Q should have changes (tested below)
+
+        // these should have no changes
+        checkNoChanges(Build.VERSION_CODES.R);
+        checkNoChanges(Build.VERSION_CODES.S);
+        checkNoChanges(Build.VERSION_CODES.TIRAMISU);
+        checkNoChanges(Build.VERSION_CODES.CUR_DEVELOPMENT);
+    }
+
+    private void checkNoChanges(int targetSdkVersion) {
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(targetSdkVersion)
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(targetSdkVersion)
+                .hideAsParsed())
+                .hideAsFinal();
+
+        checkBackwardsCompatibility(before, after);
+    }
+
+    @Test
+    public void testBcpSince30Applied() {
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .addUsesLibrary("fooBcpSince30")
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .hideAsParsed())
+                .hideAsFinal();
+
+        // note: target sdk is not what matters in this logic. It's the system SDK
+        // should be removed because on 30+ (R+) it is implicit
+
+        checkBackwardsCompatibility(before, after);
+    }
+
+    @Test
+    public void testBcpSince11kNotAppliedWithoutLibrary() {
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .hideAsParsed())
+                .hideAsFinal();
+
+        // note: target sdk is not what matters in this logic. It's the system SDK
+        // nothing should change because the implicit from is only from a future platform release
+        checkBackwardsCompatibility(before, after);
+    }
+
+    @Test
+    public void testBcpSince11kNotAppliedWithLibrary() {
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .addUsesLibrary("fooFromFuture")
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .addUsesLibrary("fooFromFuture")
+                .hideAsParsed())
+                .hideAsFinal();
+
+        // note: target sdk is not what matters in this logic. It's the system SDK
+        // nothing should change because the implicit from is only from a future platform release
+        checkBackwardsCompatibility(before, after);
+    }
+
+    @Test
+    public void testBcpBefore30NotApplied() {
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .hideAsParsed())
+                .hideAsFinal();
+
+        // should not be affected because it is still in the BCP in 30 / R
+        checkBackwardsCompatibility(before, after);
+    }
+
+    @Test
+    public void testBcpBefore30Applied() {
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.Q)
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.Q)
+                .addUsesLibrary("fooBcpBefore30")
+                .hideAsParsed())
+                .hideAsFinal();
+
+        // should be present because this was in BCP in 29 / Q
+        checkBackwardsCompatibility(before, after);
+    }
+
+    /**
+     * Test a library that was first removed from the BCP [to a mainline module] and later was
+     * moved back to the BCP via a mainline module update. All of this happening before the current
+     * SDK.
+     */
+    @Test
+    public void testBcpRemovedThenAddedPast() {
+        insertLibrary("fooBcpRemovedThenAdded", 30, 28);
+
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.N)
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.N)
+                .addUsesLibrary("fooBcpBefore30")
+                .hideAsParsed())
+                .hideAsFinal();
+
+        // the library is now in the BOOTCLASSPATH (for the second time) so it doesn't need to be
+        // listed
+        checkBackwardsCompatibility(before, after);
+    }
+
+    /**
+     * Test a library that was first removed from the BCP [to a mainline module] and later was
+     * moved back to the BCP via a mainline module update. The first part happening before the
+     * current SDK and the second part after.
+     */
+    @Test
+    public void testBcpRemovedThenAddedMiddle_targetQ() {
+        insertLibrary("fooBcpRemovedThenAdded", Build.VERSION.SDK_INT + 1, 30);
+
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.Q)
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.Q)
+                .addUsesLibrary("fooBcpRemovedThenAdded")
+                .addUsesLibrary("fooBcpBefore30")
+                .hideAsParsed())
+                .hideAsFinal();
+
+        // in this example, we are at the point where the library is not in the BOOTCLASSPATH.
+        // Because the app targets Q / 29 (when this library was in the BCP) then we need to add it
+        checkBackwardsCompatibility(before, after);
+    }
+
+    /**
+     * Test a library that was first removed from the BCP [to a mainline module] and later was
+     * moved back to the BCP via a mainline module update. The first part happening before the
+     * current SDK and the second part after.
+     */
+    @Test
+    public void testBcpRemovedThenAddedMiddle_targetR() {
+        insertLibrary("fooBcpRemovedThenAdded", Build.VERSION.SDK_INT + 1, 30);
+
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .hideAsParsed())
+                .hideAsFinal();
+
+        // in this example, we are at the point where the library is not in the BOOTCLASSPATH.
+        // Because the app targets R/30 (when this library was removed from the BCP) then we don't
+        //need to add it
+        checkBackwardsCompatibility(before, after);
+    }
+
+    /**
+     * Test a library that was first removed from the BCP [to a mainline module] and later was
+     * moved back to the BCP via a mainline module update. The first part happening before the
+     * current SDK and the second part after.
+     */
+    @Test
+    public void testBcpRemovedThenAddedMiddle_targetR_usingLib() {
+        insertLibrary("fooBcpRemovedThenAdded", Build.VERSION.SDK_INT + 1, 30);
+
+        ParsedPackage before = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .addUsesLibrary("fooBcpRemovedThenAdded")
+                .hideAsParsed());
+
+        AndroidPackage after = ((ParsedPackage) PackageImpl.forTesting(PACKAGE_NAME)
+                .setTargetSdkVersion(Build.VERSION_CODES.R)
+                .addUsesLibrary("fooBcpRemovedThenAdded")
+                .hideAsParsed())
+                .hideAsFinal();
+
+        // in this example, we are at the point where the library is not in the BOOTCLASSPATH.
+        // Because the app wants to use the library, it needs to be present
+        checkBackwardsCompatibility(before, after);
+    }
+
+    private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) {
+        checkBackwardsCompatibility(before, after,
+                () -> new ApexSharedLibraryUpdater(mSharedLibraries));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageBackwardCompatibilityTest.java b/services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageBackwardCompatibilityTest.java
index 9768f17..5bcd0f6 100644
--- a/services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageBackwardCompatibilityTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/parsing/library/PackageBackwardCompatibilityTest.java
@@ -21,6 +21,8 @@
 import static com.android.server.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER;
 import static com.android.server.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.content.pm.parsing.ParsingPackage;
 import android.os.Build;
 import android.platform.test.annotations.Presubmit;
@@ -182,6 +184,22 @@
         checkBackwardsCompatibility(before, ((ParsedPackage) after.hideAsParsed()).hideAsFinal());
     }
 
+    /**
+     * Ensures that ApexSharedLibraryUpdater is the last updater in the list of package updaters
+     * used by PackageBackwardCompatibility.
+     *
+     * This is required so mainline can add and remove libraries installed by the platform updaters.
+     */
+    @Test
+    public void testApexPackageUpdaterOrdering() {
+        PackageBackwardCompatibility instance =
+                (PackageBackwardCompatibility) PackageBackwardCompatibility.getInstance();
+        PackageSharedLibraryUpdater[] updaterArray = instance.getPackageUpdaters();
+
+        PackageSharedLibraryUpdater lastUpdater = updaterArray[updaterArray.length - 1];
+        assertThat(lastUpdater).isInstanceOf(ApexSharedLibraryUpdater.class);
+    }
+
     private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) {
         checkBackwardsCompatibility(before, after, PackageBackwardCompatibility::getInstance);
     }
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigNamedActorTest.kt b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigNamedActorTest.kt
index b7199d4..150822b 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigNamedActorTest.kt
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigNamedActorTest.kt
@@ -17,6 +17,7 @@
 package com.android.server.systemconfig
 
 import android.content.Context
+import android.util.Xml
 import androidx.test.InstrumentationRegistry
 import com.android.server.SystemConfig
 import com.google.common.truth.Truth.assertThat
@@ -227,6 +228,7 @@
             .writeText(this.trimIndent())
 
     private fun assertPermissions() = SystemConfig(false).apply {
-        readPermissions(tempFolder.root, 0)
+        val parser = Xml.newPullParser()
+        readPermissions(parser, tempFolder.root, 0)
     }. let { assertThat(it.namedActors) }
 }
diff --git a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
index 5eb21a5..bfdffc0 100644
--- a/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/systemconfig/SystemConfigTest.java
@@ -21,10 +21,12 @@
 import static org.junit.Assert.assertEquals;
 import static org.testng.Assert.expectThrows;
 
+import android.os.Build;
 import android.platform.test.annotations.Presubmit;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.Xml;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -36,9 +38,12 @@
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.util.Arrays;
@@ -59,12 +64,15 @@
     private static final String LOG_TAG = "SystemConfigTest";
 
     private SystemConfig mSysConfig;
+    private File mFooJar;
 
     @Rule public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
 
     @Before
     public void setUp() throws Exception {
         mSysConfig = new SystemConfigTestClass();
+        mFooJar = createTempFile(
+                mTemporaryFolder.getRoot().getCanonicalFile(), "foo.jar", "JAR");
     }
 
     /**
@@ -76,6 +84,11 @@
         }
     }
 
+    private void readPermissions(File libraryDir, int permissionFlag) {
+        final XmlPullParser parser = Xml.newPullParser();
+        mSysConfig.readPermissions(parser, libraryDir, permissionFlag);
+    }
+
     /**
      * Tests that readPermissions works correctly for the tag: install-in-user-type
      */
@@ -126,16 +139,17 @@
                 new ArraySet<>(Arrays.asList("GUEST", "PROFILE")));
 
         final File folder1 = createTempSubfolder("folder1");
-        createTempFile(folder1, "permFile1.xml", contents1);
+        createTempFile(folder1, "permissionFile1.xml", contents1);
 
         final File folder2 = createTempSubfolder("folder2");
-        createTempFile(folder2, "permFile2.xml", contents2);
+        createTempFile(folder2, "permissionFile2.xml", contents2);
 
-        // Also, make a third file, but with the name folder1/permFile2.xml, to prove no conflicts.
-        createTempFile(folder1, "permFile2.xml", contents3);
+        // Also, make a third file, but with the name folder1/permissionFile2.xml, to prove no
+        // conflicts.
+        createTempFile(folder1, "permissionFile2.xml", contents3);
 
-        mSysConfig.readPermissions(folder1, /* No permission needed anyway */ 0);
-        mSysConfig.readPermissions(folder2, /* No permission needed anyway */ 0);
+        readPermissions(folder1, /* No permission needed anyway */ 0);
+        readPermissions(folder2, /* No permission needed anyway */ 0);
 
         Map<String, Set<String>> actualWhite = mSysConfig.getAndClearPackageToUserTypeWhitelist();
         Map<String, Set<String>> actualBlack = mSysConfig.getAndClearPackageToUserTypeBlacklist();
@@ -165,7 +179,7 @@
         final File folder = createTempSubfolder("folder");
         createTempFile(folder, "component-override.xml", contents);
 
-        mSysConfig.readPermissions(folder, /* No permission needed anyway */ 0);
+        readPermissions(folder, /* No permission needed anyway */ 0);
 
         final ArrayMap<String, Boolean> packageOneExpected = new ArrayMap<>();
         packageOneExpected.put("com.android.package1.Full", true);
@@ -197,7 +211,7 @@
         final File folder = createTempSubfolder("folder");
         createTempFile(folder, "staged-installer-whitelist.xml", contents);
 
-        mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0);
+        readPermissions(folder, /* Grant all permission flags */ ~0);
 
         assertThat(mSysConfig.getWhitelistedStagedInstallers())
                 .containsExactly("com.android.package1");
@@ -215,7 +229,7 @@
         final File folder = createTempSubfolder("folder");
         createTempFile(folder, "staged-installer-whitelist.xml", contents);
 
-        mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0);
+        readPermissions(folder, /* Grant all permission flags */ ~0);
 
         assertThat(mSysConfig.getWhitelistedStagedInstallers())
                 .containsExactly("com.android.package1");
@@ -238,7 +252,7 @@
 
         IllegalStateException e = expectThrows(
                 IllegalStateException.class,
-                () -> mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0));
+                () -> readPermissions(folder, /* Grant all permission flags */ ~0));
 
         assertThat(e).hasMessageThat().contains("Multiple modules installers");
     }
@@ -257,7 +271,7 @@
         final File folder = createTempSubfolder("folder");
         createTempFile(folder, "staged-installer-whitelist.xml", contents);
 
-        mSysConfig.readPermissions(folder, /* Grant all but ALLOW_APP_CONFIGS flag */ ~0x08);
+        readPermissions(folder, /* Grant all but ALLOW_APP_CONFIGS flag */ ~0x08);
 
         assertThat(mSysConfig.getWhitelistedStagedInstallers()).isEmpty();
     }
@@ -277,7 +291,7 @@
         final File folder = createTempSubfolder("folder");
         createTempFile(folder, "vendor-apex-allowlist.xml", contents);
 
-        mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0);
+        readPermissions(folder, /* Grant all permission flags */ ~0);
 
         assertThat(mSysConfig.getAllowedVendorApexes())
                 .containsExactly("com.android.apex1", "com.installer");
@@ -297,7 +311,7 @@
         final File folder = createTempSubfolder("folder");
         createTempFile(folder, "vendor-apex-allowlist.xml", contents);
 
-        mSysConfig.readPermissions(folder, /* Grant all permission flags */ ~0);
+        readPermissions(folder, /* Grant all permission flags */ ~0);
 
         assertThat(mSysConfig.getAllowedVendorApexes()).isEmpty();
     }
@@ -317,11 +331,273 @@
         final File folder = createTempSubfolder("folder");
         createTempFile(folder, "vendor-apex-allowlist.xml", contents);
 
-        mSysConfig.readPermissions(folder, /* Grant all but ALLOW_VENDOR_APEX flag */ ~0x400);
+        readPermissions(folder, /* Grant all but ALLOW_VENDOR_APEX flag */ ~0x400);
 
         assertThat(mSysConfig.getAllowedVendorApexes()).isEmpty();
     }
 
+    @Test
+    public void readApexPrivAppPermissions_addAllPermissions()
+            throws Exception {
+        final String contents =
+                "<privapp-permissions package=\"com.android.apk_in_apex\">"
+                        + "<permission name=\"android.permission.FOO\"/>"
+                        + "<deny-permission name=\"android.permission.BAR\"/>"
+                        + "</privapp-permissions>";
+        File apexDir = createTempSubfolder("apex");
+        File permissionFile = createTempFile(
+                createTempSubfolder("apex/com.android.my_module/etc/permissions"),
+                    "permissions.xml", contents);
+        XmlPullParser parser = readXmlUntilStartTag(permissionFile);
+
+        mSysConfig.readApexPrivAppPermissions(parser, permissionFile, apexDir.toPath());
+
+        assertThat(mSysConfig.getApexPrivAppPermissions("com.android.my_module",
+                "com.android.apk_in_apex"))
+            .containsExactly("android.permission.FOO");
+        assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.my_module",
+                "com.android.apk_in_apex"))
+            .containsExactly("android.permission.BAR");
+    }
+
+    @Test
+    public void pruneVendorApexPrivappAllowlists_removeVendor()
+            throws Exception {
+        File apexDir = createTempSubfolder("apex");
+
+        // Read non-vendor apex permission allowlists
+        final String allowlistNonVendorContents =
+                "<privapp-permissions package=\"com.android.apk_in_non_vendor_apex\">"
+                        + "<permission name=\"android.permission.FOO\"/>"
+                        + "<deny-permission name=\"android.permission.BAR\"/>"
+                        + "</privapp-permissions>";
+        File nonVendorPermDir =
+                createTempSubfolder("apex/com.android.non_vendor/etc/permissions");
+        File nonVendorPermissionFile =
+                createTempFile(nonVendorPermDir, "permissions.xml", allowlistNonVendorContents);
+        XmlPullParser nonVendorParser = readXmlUntilStartTag(nonVendorPermissionFile);
+        mSysConfig.readApexPrivAppPermissions(nonVendorParser, nonVendorPermissionFile,
+                apexDir.toPath());
+
+        // Read vendor apex permission allowlists
+        final String allowlistVendorContents =
+                "<privapp-permissions package=\"com.android.apk_in_vendor_apex\">"
+                        + "<permission name=\"android.permission.BAZ\"/>"
+                        + "<deny-permission name=\"android.permission.BAT\"/>"
+                        + "</privapp-permissions>";
+        File vendorPermissionFile =
+                createTempFile(createTempSubfolder("apex/com.android.vendor/etc/permissions"),
+                        "permissions.xml", allowlistNonVendorContents);
+        XmlPullParser vendorParser = readXmlUntilStartTag(vendorPermissionFile);
+        mSysConfig.readApexPrivAppPermissions(vendorParser, vendorPermissionFile,
+                apexDir.toPath());
+
+        // Read allowed vendor apex list
+        final String allowedVendorContents =
+                "<config>\n"
+                        + "    <allowed-vendor-apex package=\"com.android.vendor\" "
+                        + "installerPackage=\"com.installer\" />\n"
+                        + "</config>";
+        final File allowedVendorFolder = createTempSubfolder("folder");
+        createTempFile(allowedVendorFolder, "vendor-apex-allowlist.xml", allowedVendorContents);
+        readPermissions(allowedVendorFolder, /* Grant all permission flags */ ~0);
+
+        // Finally, prune non-vendor allowlists.
+        // There is no guarantee in which order the above reads will be done, however pruning
+        // will always happen last.
+        mSysConfig.pruneVendorApexPrivappAllowlists();
+
+        assertThat(mSysConfig.getApexPrivAppPermissions("com.android.non_vendor",
+                "com.android.apk_in_non_vendor_apex"))
+            .containsExactly("android.permission.FOO");
+        assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.non_vendor",
+                "com.android.apk_in_non_vendor_apex"))
+            .containsExactly("android.permission.BAR");
+        assertThat(mSysConfig.getApexPrivAppPermissions("com.android.vendor",
+                "com.android.apk_in_vendor_apex"))
+            .isNull();
+        assertThat(mSysConfig.getApexPrivAppDenyPermissions("com.android.vendor",
+                "com.android.apk_in_vendor_apex"))
+            .isNull();
+    }
+
+    /**
+     * Tests that readPermissions works correctly for a library with on-bootclasspath-before
+     * and on-bootclasspath-since.
+     */
+    @Test
+    public void readPermissions_allowLibs_parsesSimpleLibrary() throws IOException {
+        String contents =
+                "<permissions>\n"
+                + "    <library \n"
+                + "        name=\"foo\"\n"
+                + "        file=\"" + mFooJar + "\"\n"
+                + "        on-bootclasspath-before=\"10\"\n"
+                + "        on-bootclasspath-since=\"20\"\n"
+                + "     />\n\n"
+                + " </permissions>";
+        parseSharedLibraries(contents);
+        assertFooIsOnlySharedLibrary();
+        SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo");
+        assertThat(entry.onBootclasspathBefore).isEqualTo(10);
+        assertThat(entry.onBootclasspathSince).isEqualTo(20);
+    }
+
+    /**
+     * Tests that readPermissions works correctly for a library using the new
+     * {@code apex-library} tag.
+     */
+    @Test
+    public void readPermissions_allowLibs_parsesUpdatableLibrary() throws IOException {
+        String contents =
+                "<permissions>\n"
+                        + "    <apex-library \n"
+                        + "        name=\"foo\"\n"
+                        + "        file=\"" + mFooJar + "\"\n"
+                        + "        on-bootclasspath-before=\"10\"\n"
+                        + "        on-bootclasspath-since=\"20\"\n"
+                        + "     />\n\n"
+                        + " </permissions>";
+        parseSharedLibraries(contents);
+        assertFooIsOnlySharedLibrary();
+        SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo");
+        assertThat(entry.onBootclasspathBefore).isEqualTo(10);
+        assertThat(entry.onBootclasspathSince).isEqualTo(20);
+    }
+
+    /**
+     * Tests that readPermissions for a library with {@code min-device-sdk} lower than the current
+     * SDK results in the library being added to the shared libraries.
+     */
+    @Test
+    public void readPermissions_allowLibs_allowsOldMinSdk() throws IOException {
+        String contents =
+                "<permissions>\n"
+                + "    <library \n"
+                + "        name=\"foo\"\n"
+                + "        file=\"" + mFooJar + "\"\n"
+                + "        min-device-sdk=\"30\"\n"
+                + "     />\n\n"
+                + " </permissions>";
+        parseSharedLibraries(contents);
+        assertFooIsOnlySharedLibrary();
+    }
+
+    /**
+     * Tests that readPermissions for a library with {@code min-device-sdk} equal to the current
+     * SDK results in the library being added to the shared libraries.
+     */
+    @Test
+    public void readPermissions_allowLibs_allowsCurrentMinSdk() throws IOException {
+        String contents =
+                "<permissions>\n"
+                + "    <library \n"
+                + "        name=\"foo\"\n"
+                + "        file=\"" + mFooJar + "\"\n"
+                + "        min-device-sdk=\"" + Build.VERSION.SDK_INT + "\"\n"
+                + "     />\n\n"
+                + " </permissions>";
+        parseSharedLibraries(contents);
+        assertFooIsOnlySharedLibrary();
+    }
+
+    /**
+     * Tests that readPermissions for a library with {@code min-device-sdk} greater than the current
+     * SDK results in the library being ignored.
+     */
+    @Test
+    public void readPermissions_allowLibs_ignoresMinSdkInFuture() throws IOException {
+        String contents =
+                "<permissions>\n"
+                + "    <library \n"
+                + "        name=\"foo\"\n"
+                + "        file=\"" + mFooJar + "\"\n"
+                + "        min-device-sdk=\"" + (Build.VERSION.SDK_INT + 1) + "\"\n"
+                + "     />\n\n"
+                + " </permissions>";
+        parseSharedLibraries(contents);
+        assertThat(mSysConfig.getSharedLibraries()).isEmpty();
+    }
+
+    /**
+     * Tests that readPermissions for a library with {@code max-device-sdk} less than the current
+     * SDK results in the library being ignored.
+     */
+    @Test
+    public void readPermissions_allowLibs_ignoredOldMaxSdk() throws IOException {
+        String contents =
+                "<permissions>\n"
+                + "    <library \n"
+                + "        name=\"foo\"\n"
+                + "        file=\"" + mFooJar + "\"\n"
+                + "        max-device-sdk=\"30\"\n"
+                + "     />\n\n"
+                + " </permissions>";
+        parseSharedLibraries(contents);
+        assertThat(mSysConfig.getSharedLibraries()).isEmpty();
+    }
+
+    /**
+     * Tests that readPermissions for a library with {@code max-device-sdk} equal to the current
+     * SDK results in the library being added to the shared libraries.
+     */
+    @Test
+    public void readPermissions_allowLibs_allowsCurrentMaxSdk() throws IOException {
+        String contents =
+                "<permissions>\n"
+                + "    <library \n"
+                + "        name=\"foo\"\n"
+                + "        file=\"" + mFooJar + "\"\n"
+                + "        max-device-sdk=\"" + Build.VERSION.SDK_INT + "\"\n"
+                + "     />\n\n"
+                + " </permissions>";
+        parseSharedLibraries(contents);
+        assertFooIsOnlySharedLibrary();
+    }
+
+    /**
+     * Tests that readPermissions for a library with {@code max-device-sdk} greater than the current
+     * SDK results in the library being added to the shared libraries.
+     */
+    @Test
+    public void readPermissions_allowLibs_allowsMaxSdkInFuture() throws IOException {
+        String contents =
+                "<permissions>\n"
+                + "    <library \n"
+                + "        name=\"foo\"\n"
+                + "        file=\"" + mFooJar + "\"\n"
+                + "        max-device-sdk=\"" + (Build.VERSION.SDK_INT + 1) + "\"\n"
+                + "     />\n\n"
+                + " </permissions>";
+        parseSharedLibraries(contents);
+        assertFooIsOnlySharedLibrary();
+    }
+
+    private void parseSharedLibraries(String contents) throws IOException {
+        File folder = createTempSubfolder("permissions_folder");
+        createTempFile(folder, "permissions.xml", contents);
+        readPermissions(folder, /* permissionFlag = ALLOW_LIBS */ 0x02);
+    }
+
+    /**
+     * Create an {@link XmlPullParser} for {@param permissionFile} and begin parsing it until
+     * reaching the root tag.
+     */
+    private XmlPullParser readXmlUntilStartTag(File permissionFile)
+            throws IOException, XmlPullParserException {
+        FileReader permReader = new FileReader(permissionFile);
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(permReader);
+        int type;
+        do {
+            type = parser.next();
+        } while (type != parser.START_TAG && type != parser.END_DOCUMENT);
+        if (type != parser.START_TAG) {
+            throw new XmlPullParserException("No start tag found");
+        }
+        return parser;
+    }
+
     /**
      * Creates folderName/fileName in the mTemporaryFolder and fills it with the contents.
      *
@@ -331,7 +607,7 @@
     private File createTempSubfolder(String folderName)
             throws IOException {
         File folder = new File(mTemporaryFolder.getRoot(), folderName);
-        folder.mkdir();
+        folder.mkdirs();
         return folder;
     }
 
@@ -341,7 +617,7 @@
      * @param folder   pre-existing subdirectory of mTemporaryFolder to put the file
      * @param fileName name of the file (e.g. filename.xml) to create
      * @param contents contents to write to the file
-     * @return the folder containing the newly created file (not the file itself!)
+     * @return the newly created file
      */
     private File createTempFile(File folder, String fileName, String contents)
             throws IOException {
@@ -357,6 +633,13 @@
             Log.d(LOG_TAG, input.nextLine());
         }
 
-        return folder;
+        return file;
+    }
+
+    private void assertFooIsOnlySharedLibrary() {
+        assertThat(mSysConfig.getSharedLibraries().size()).isEqualTo(1);
+        SystemConfig.SharedLibraryEntry entry = mSysConfig.getSharedLibraries().get("foo");
+        assertThat(entry.name).isEqualTo("foo");
+        assertThat(entry.filename).isEqualTo(mFooJar.toString());
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
index 32fed3b..4519890 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorServiceTest.java
@@ -252,7 +252,7 @@
         int slotIndex = 1234;
         TimestampedValue<Long> timeValue = new TimestampedValue<>(100L, 1_000_000L);
         return new TelephonyTimeSuggestion.Builder(slotIndex)
-                .setUtcTime(timeValue)
+                .setUnixEpochTime(timeValue)
                 .build();
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
index 0d5b5a5..2d9903f 100644
--- a/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timedetector/TimeDetectorStrategyImplTest.java
@@ -52,12 +52,12 @@
 @RunWith(AndroidJUnit4.class)
 public class TimeDetectorStrategyImplTest {
 
-    private static final Instant TIME_LOWER_BOUND = createUtcTime(2009, 1, 1, 12, 0, 0);
+    private static final Instant TIME_LOWER_BOUND = createUnixEpochTime(2009, 1, 1, 12, 0, 0);
 
     private static final TimestampedValue<Instant> ARBITRARY_CLOCK_INITIALIZATION_INFO =
             new TimestampedValue<>(
                     123456789L /* realtimeClockMillis */,
-                    createUtcTime(2010, 5, 23, 12, 0, 0));
+                    createUnixEpochTime(2010, 5, 23, 12, 0, 0));
 
     // This is the traditional ordering for time detection on Android.
     private static final @Origin int [] PROVIDERS_PRIORITY = { ORIGIN_TELEPHONY, ORIGIN_NETWORK };
@@ -66,7 +66,7 @@
      * An arbitrary time, very different from the {@link #ARBITRARY_CLOCK_INITIALIZATION_INFO}
      * time. Can be used as the basis for time suggestions.
      */
-    private static final Instant ARBITRARY_TEST_TIME = createUtcTime(2018, 1, 1, 12, 0, 0);
+    private static final Instant ARBITRARY_TEST_TIME = createUnixEpochTime(2018, 1, 1, 12, 0, 0);
 
     private static final int ARBITRARY_SLOT_INDEX = 123456;
 
@@ -91,7 +91,7 @@
                 .simulateTelephonyTimeSuggestion(timeSuggestion);
 
         long expectedSystemClockMillis =
-                mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime());
         mScript.verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
                 .assertLatestTelephonySuggestion(slotIndex, timeSuggestion);
     }
@@ -128,7 +128,7 @@
             mScript.simulateTimePassing(clockIncrementMillis);
 
             long expectedSystemClockMillis1 =
-                    mScript.calculateTimeInMillisForNow(timeSuggestion1.getUtcTime());
+                    mScript.calculateTimeInMillisForNow(timeSuggestion1.getUnixEpochTime());
 
             mScript.simulateTelephonyTimeSuggestion(timeSuggestion1)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1)
@@ -155,7 +155,7 @@
             mScript.simulateTimePassing(clockIncrementMillis);
 
             long expectedSystemClockMillis3 =
-                    mScript.calculateTimeInMillisForNow(timeSuggestion3.getUtcTime());
+                    mScript.calculateTimeInMillisForNow(timeSuggestion3.getUnixEpochTime());
 
             mScript.simulateTelephonyTimeSuggestion(timeSuggestion3)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis3)
@@ -182,8 +182,8 @@
                     mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time);
             mScript.simulateTimePassing();
 
-            long expectedSystemClockMillis =
-                    mScript.calculateTimeInMillisForNow(slotIndex2TimeSuggestion.getUtcTime());
+            long expectedSystemClockMillis = mScript.calculateTimeInMillisForNow(
+                    slotIndex2TimeSuggestion.getUnixEpochTime());
 
             mScript.simulateTelephonyTimeSuggestion(slotIndex2TimeSuggestion)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
@@ -199,8 +199,8 @@
                     mScript.generateTelephonyTimeSuggestion(slotIndex1, slotIndex1Time);
             mScript.simulateTimePassing();
 
-            long expectedSystemClockMillis =
-                    mScript.calculateTimeInMillisForNow(slotIndex1TimeSuggestion.getUtcTime());
+            long expectedSystemClockMillis = mScript.calculateTimeInMillisForNow(
+                    slotIndex1TimeSuggestion.getUnixEpochTime());
 
             mScript.simulateTelephonyTimeSuggestion(slotIndex1TimeSuggestion)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
@@ -232,8 +232,8 @@
                     mScript.generateTelephonyTimeSuggestion(slotIndex2, slotIndex2Time);
             mScript.simulateTimePassing();
 
-            long expectedSystemClockMillis =
-                    mScript.calculateTimeInMillisForNow(slotIndex2TimeSuggestion.getUtcTime());
+            long expectedSystemClockMillis = mScript.calculateTimeInMillisForNow(
+                    slotIndex2TimeSuggestion.getUnixEpochTime());
 
             mScript.simulateTelephonyTimeSuggestion(slotIndex2TimeSuggestion)
                     .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis)
@@ -267,26 +267,27 @@
 
         TelephonyTimeSuggestion timeSuggestion1 =
                 mScript.generateTelephonyTimeSuggestion(slotIndex, testTime);
-        TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime();
+        TimestampedValue<Long> unixEpochTime1 = timeSuggestion1.getUnixEpochTime();
 
         // Initialize the strategy / device with a time set from a telephony suggestion.
         mScript.simulateTimePassing();
-        long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(utcTime1);
+        long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(unixEpochTime1);
         mScript.simulateTelephonyTimeSuggestion(timeSuggestion1)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis1)
                 .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
 
-        // The UTC time increment should be larger than the system clock update threshold so we
-        // know it shouldn't be ignored for other reasons.
-        long validUtcTimeMillis = utcTime1.getValue() + (2 * systemClockUpdateThreshold);
+        // The Unix epoch time increment should be larger than the system clock update threshold so
+        // we know it shouldn't be ignored for other reasons.
+        long validUnixEpochTimeMillis = unixEpochTime1.getValue()
+                + (2 * systemClockUpdateThreshold);
 
         // Now supply a new signal that has an obviously bogus reference time : older than the last
         // one.
-        long referenceTimeBeforeLastSignalMillis = utcTime1.getReferenceTimeMillis() - 1;
-        TimestampedValue<Long> utcTime2 = new TimestampedValue<>(
-                referenceTimeBeforeLastSignalMillis, validUtcTimeMillis);
+        long referenceTimeBeforeLastSignalMillis = unixEpochTime1.getReferenceTimeMillis() - 1;
+        TimestampedValue<Long> unixEpochTime2 = new TimestampedValue<>(
+                referenceTimeBeforeLastSignalMillis, validUnixEpochTimeMillis);
         TelephonyTimeSuggestion timeSuggestion2 =
-                createTelephonyTimeSuggestion(slotIndex, utcTime2);
+                createTelephonyTimeSuggestion(slotIndex, unixEpochTime2);
         mScript.simulateTelephonyTimeSuggestion(timeSuggestion2)
                 .verifySystemClockWasNotSetAndResetCallTracking()
                 .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
@@ -294,22 +295,22 @@
         // Now supply a new signal that has an obviously bogus reference time : substantially in the
         // future.
         long referenceTimeInFutureMillis =
-                utcTime1.getReferenceTimeMillis() + Integer.MAX_VALUE + 1;
-        TimestampedValue<Long> utcTime3 = new TimestampedValue<>(
-                referenceTimeInFutureMillis, validUtcTimeMillis);
+                unixEpochTime1.getReferenceTimeMillis() + Integer.MAX_VALUE + 1;
+        TimestampedValue<Long> unixEpochTime3 = new TimestampedValue<>(
+                referenceTimeInFutureMillis, validUnixEpochTimeMillis);
         TelephonyTimeSuggestion timeSuggestion3 =
-                createTelephonyTimeSuggestion(slotIndex, utcTime3);
+                createTelephonyTimeSuggestion(slotIndex, unixEpochTime3);
         mScript.simulateTelephonyTimeSuggestion(timeSuggestion3)
                 .verifySystemClockWasNotSetAndResetCallTracking()
                 .assertLatestTelephonySuggestion(slotIndex, timeSuggestion1);
 
-        // Just to prove validUtcTimeMillis is valid.
-        long validReferenceTimeMillis = utcTime1.getReferenceTimeMillis() + 100;
-        TimestampedValue<Long> utcTime4 = new TimestampedValue<>(
-                validReferenceTimeMillis, validUtcTimeMillis);
-        long expectedSystemClockMillis4 = mScript.calculateTimeInMillisForNow(utcTime4);
+        // Just to prove validUnixEpochTimeMillis is valid.
+        long validReferenceTimeMillis = unixEpochTime1.getReferenceTimeMillis() + 100;
+        TimestampedValue<Long> unixEpochTime4 = new TimestampedValue<>(
+                validReferenceTimeMillis, validUnixEpochTimeMillis);
+        long expectedSystemClockMillis4 = mScript.calculateTimeInMillisForNow(unixEpochTime4);
         TelephonyTimeSuggestion timeSuggestion4 =
-                createTelephonyTimeSuggestion(slotIndex, utcTime4);
+                createTelephonyTimeSuggestion(slotIndex, unixEpochTime4);
         mScript.simulateTelephonyTimeSuggestion(timeSuggestion4)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis4)
                 .assertLatestTelephonySuggestion(slotIndex, timeSuggestion4);
@@ -344,7 +345,7 @@
         Instant testTime = ARBITRARY_TEST_TIME;
         TelephonyTimeSuggestion timeSuggestion1 =
                 mScript.generateTelephonyTimeSuggestion(slotIndex, testTime);
-        TimestampedValue<Long> utcTime1 = timeSuggestion1.getUtcTime();
+        TimestampedValue<Long> unixEpochTime1 = timeSuggestion1.getUnixEpochTime();
 
         // Simulate time passing.
         mScript.simulateTimePassing(clockIncrementMillis);
@@ -358,7 +359,7 @@
         // Simulate more time passing.
         mScript.simulateTimePassing(clockIncrementMillis);
 
-        long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(utcTime1);
+        long expectedSystemClockMillis1 = mScript.calculateTimeInMillisForNow(unixEpochTime1);
 
         // Turn on auto time detection.
         mScript.simulateAutoTimeDetectionToggle()
@@ -379,7 +380,7 @@
         mScript.simulateTimePassing(clockIncrementMillis);
 
         long expectedSystemClockMillis2 =
-                mScript.calculateTimeInMillisForNow(timeSuggestion2.getUtcTime());
+                mScript.calculateTimeInMillisForNow(timeSuggestion2.getUnixEpochTime());
 
         // The new time, though valid, should not be set in the system clock because auto time is
         // disabled.
@@ -406,7 +407,7 @@
         mScript.simulateTimePassing();
 
         long expectedSystemClockMillis =
-                mScript.calculateTimeInMillisForNow(telephonySuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(telephonySuggestion.getUnixEpochTime());
         mScript.simulateTelephonyTimeSuggestion(telephonySuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(
                         expectedSystemClockMillis  /* expectedNetworkBroadcast */)
@@ -416,7 +417,7 @@
         assertEquals(telephonySuggestion, mScript.peekBestTelephonySuggestion());
 
         // Simulate time passing, long enough that telephonySuggestion is now too old.
-        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS);
+        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS);
 
         // Look inside and check what the strategy considers the current best telephony suggestion.
         // It should still be the, it's just no longer used.
@@ -435,7 +436,7 @@
         mScript.simulateTimePassing();
 
         long expectedSystemClockMillis =
-                mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime());
         mScript.simulateManualTimeSuggestion(timeSuggestion, true /* expectedResult */)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
     }
@@ -457,7 +458,7 @@
         mScript.simulateTimePassing();
 
         long expectedAutoClockMillis =
-                mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUnixEpochTime());
         mScript.simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis)
                 .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
@@ -480,7 +481,7 @@
         mScript.simulateTimePassing();
 
         long expectedManualClockMillis =
-                mScript.calculateTimeInMillisForNow(manualTimeSuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(manualTimeSuggestion.getUnixEpochTime());
         mScript.simulateManualTimeSuggestion(manualTimeSuggestion, true /* expectedResult */)
                 .verifySystemClockWasSetAndResetCallTracking(expectedManualClockMillis)
                 .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
@@ -492,7 +493,7 @@
         mScript.simulateAutoTimeDetectionToggle();
 
         expectedAutoClockMillis =
-                mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUnixEpochTime());
         mScript.verifySystemClockWasSetAndResetCallTracking(expectedAutoClockMillis)
                 .assertLatestTelephonySuggestion(slotIndex, telephonyTimeSuggestion);
 
@@ -540,7 +541,7 @@
         mScript.simulateTimePassing();
 
         long expectedSystemClockMillis =
-                mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime());
         mScript.simulateNetworkTimeSuggestion(timeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
     }
@@ -586,7 +587,7 @@
         mScript.simulateTimePassing();
 
         long expectedSystemClockMillis =
-                mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime());
         mScript.simulateGnssTimeSuggestion(timeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
     }
@@ -617,7 +618,7 @@
         mScript.simulateTimePassing();
 
         long expectedSystemClockMillis =
-                mScript.calculateTimeInMillisForNow(timeSuggestion.getUtcTime());
+                mScript.calculateTimeInMillisForNow(timeSuggestion.getUnixEpochTime());
         mScript.simulateExternalTimeSuggestion(timeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(expectedSystemClockMillis);
     }
@@ -671,7 +672,8 @@
         mScript.simulateTimePassing(smallTimeIncrementMillis)
                 .simulateNetworkTimeSuggestion(networkTimeSuggestion1)
                 .verifySystemClockWasSetAndResetCallTracking(
-                        mScript.calculateTimeInMillisForNow(networkTimeSuggestion1.getUtcTime()));
+                        mScript.calculateTimeInMillisForNow(
+                                networkTimeSuggestion1.getUnixEpochTime()));
 
         // Check internal state.
         mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, null)
@@ -690,7 +692,8 @@
         mScript.simulateTimePassing(smallTimeIncrementMillis)
                 .simulateTelephonyTimeSuggestion(telephonyTimeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(
-                        mScript.calculateTimeInMillisForNow(telephonyTimeSuggestion.getUtcTime()));
+                        mScript.calculateTimeInMillisForNow(
+                                telephonyTimeSuggestion.getUnixEpochTime()));
 
         // Check internal state.
         mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
@@ -700,7 +703,7 @@
 
         // Simulate some significant time passing: half the time allowed before a time signal
         // becomes "too old to use".
-        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2)
+        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
         // Now another network suggestion is made. Telephony suggestions are prioritized over
@@ -720,7 +723,7 @@
         // Simulate some significant time passing: half the time allowed before a time signal
         // becomes "too old to use". This should mean that telephonyTimeSuggestion is now too old to
         // be used but networkTimeSuggestion2 is not.
-        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2);
+        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2);
 
         // NOTE: The TimeDetectorStrategyImpl doesn't set an alarm for the point when the last
         // suggestion it used becomes too old: it requires a new suggestion or an auto-time toggle
@@ -743,7 +746,7 @@
 
         // Verify the latest network time now wins.
         mScript.verifySystemClockWasSetAndResetCallTracking(
-                mScript.calculateTimeInMillisForNow(networkTimeSuggestion2.getUtcTime()));
+                mScript.calculateTimeInMillisForNow(networkTimeSuggestion2.getUnixEpochTime()));
 
         // Check internal state.
         mScript.assertLatestTelephonySuggestion(ARBITRARY_SLOT_INDEX, telephonyTimeSuggestion)
@@ -774,7 +777,8 @@
         mScript.simulateTimePassing(smallTimeIncrementMillis)
                 .simulateGnssTimeSuggestion(gnssTimeSuggestion1)
                 .verifySystemClockWasSetAndResetCallTracking(
-                        mScript.calculateTimeInMillisForNow(gnssTimeSuggestion1.getUtcTime()));
+                        mScript.calculateTimeInMillisForNow(
+                                gnssTimeSuggestion1.getUnixEpochTime()));
 
         // Check internal state.
         mScript.assertLatestNetworkSuggestion(null)
@@ -793,7 +797,8 @@
         mScript.simulateTimePassing(smallTimeIncrementMillis)
                 .simulateNetworkTimeSuggestion(networkTimeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(
-                        mScript.calculateTimeInMillisForNow(networkTimeSuggestion.getUtcTime()));
+                        mScript.calculateTimeInMillisForNow(
+                                networkTimeSuggestion.getUnixEpochTime()));
 
         // Check internal state.
         mScript.assertLatestNetworkSuggestion(networkTimeSuggestion)
@@ -803,7 +808,7 @@
 
         // Simulate some significant time passing: half the time allowed before a time signal
         // becomes "too old to use".
-        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2)
+        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
         // Now another gnss suggestion is made. Network suggestions are prioritized over
@@ -823,7 +828,7 @@
         // Simulate some significant time passing: half the time allowed before a time signal
         // becomes "too old to use". This should mean that telephonyTimeSuggestion is now too old to
         // be used but networkTimeSuggestion2 is not.
-        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2);
+        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2);
 
         // NOTE: The TimeDetectorStrategyImpl doesn't set an alarm for the point when the last
         // suggestion it used becomes too old: it requires a new suggestion or an auto-time toggle
@@ -846,7 +851,7 @@
 
         // Verify the latest gnss time now wins.
         mScript.verifySystemClockWasSetAndResetCallTracking(
-                mScript.calculateTimeInMillisForNow(gnssTimeSuggestion2.getUtcTime()));
+                mScript.calculateTimeInMillisForNow(gnssTimeSuggestion2.getUnixEpochTime()));
 
         // Check internal state.
         mScript.assertLatestNetworkSuggestion(networkTimeSuggestion)
@@ -877,7 +882,8 @@
         mScript.simulateTimePassing(smallTimeIncrementMillis)
                 .simulateExternalTimeSuggestion(externalTimeSuggestion1)
                 .verifySystemClockWasSetAndResetCallTracking(
-                        mScript.calculateTimeInMillisForNow(externalTimeSuggestion1.getUtcTime()));
+                        mScript.calculateTimeInMillisForNow(
+                                externalTimeSuggestion1.getUnixEpochTime()));
 
         // Check internal state.
         mScript.assertLatestNetworkSuggestion(null)
@@ -896,7 +902,8 @@
         mScript.simulateTimePassing(smallTimeIncrementMillis)
                 .simulateNetworkTimeSuggestion(networkTimeSuggestion)
                 .verifySystemClockWasSetAndResetCallTracking(
-                        mScript.calculateTimeInMillisForNow(networkTimeSuggestion.getUtcTime()));
+                        mScript.calculateTimeInMillisForNow(
+                                networkTimeSuggestion.getUnixEpochTime()));
 
         // Check internal state.
         mScript.assertLatestNetworkSuggestion(networkTimeSuggestion)
@@ -906,7 +913,7 @@
 
         // Simulate some significant time passing: half the time allowed before a time signal
         // becomes "too old to use".
-        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2)
+        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2)
                 .verifySystemClockWasNotSetAndResetCallTracking();
 
         // Now another external suggestion is made. Network suggestions are prioritized over
@@ -926,7 +933,7 @@
         // Simulate some significant time passing: half the time allowed before a time signal
         // becomes "too old to use". This should mean that networkTimeSuggestion is now too old to
         // be used but externalTimeSuggestion2 is not.
-        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_UTC_TIME_AGE_MILLIS / 2);
+        mScript.simulateTimePassing(TimeDetectorStrategyImpl.MAX_SUGGESTION_TIME_AGE_MILLIS / 2);
 
         // NOTE: The TimeDetectorStrategyImpl doesn't set an alarm for the point when the last
         // suggestion it used becomes too old: it requires a new suggestion or an auto-time toggle
@@ -949,7 +956,7 @@
 
         // Verify the latest external time now wins.
         mScript.verifySystemClockWasSetAndResetCallTracking(
-                mScript.calculateTimeInMillisForNow(externalTimeSuggestion2.getUtcTime()));
+                mScript.calculateTimeInMillisForNow(externalTimeSuggestion2.getUnixEpochTime()));
 
         // Check internal state.
         mScript.assertLatestNetworkSuggestion(networkTimeSuggestion)
@@ -1438,11 +1445,11 @@
          * reference time.
          */
         ManualTimeSuggestion generateManualTimeSuggestion(Instant suggestedTime) {
-            TimestampedValue<Long> utcTime =
+            TimestampedValue<Long> unixEpochTime =
                     new TimestampedValue<>(
                             mFakeEnvironment.peekElapsedRealtimeMillis(),
                             suggestedTime.toEpochMilli());
-            return new ManualTimeSuggestion(utcTime);
+            return new ManualTimeSuggestion(unixEpochTime);
         }
 
         /**
@@ -1472,11 +1479,11 @@
          * reference time.
          */
         NetworkTimeSuggestion generateNetworkTimeSuggestion(Instant suggestedTime) {
-            TimestampedValue<Long> utcTime =
+            TimestampedValue<Long> unixEpochTime =
                     new TimestampedValue<>(
                             mFakeEnvironment.peekElapsedRealtimeMillis(),
                             suggestedTime.toEpochMilli());
-            return new NetworkTimeSuggestion(utcTime);
+            return new NetworkTimeSuggestion(unixEpochTime);
         }
 
         /**
@@ -1484,11 +1491,11 @@
          * reference time.
          */
         GnssTimeSuggestion generateGnssTimeSuggestion(Instant suggestedTime) {
-            TimestampedValue<Long> utcTime =
+            TimestampedValue<Long> unixEpochTime =
                     new TimestampedValue<>(
                             mFakeEnvironment.peekElapsedRealtimeMillis(),
                             suggestedTime.toEpochMilli());
-            return new GnssTimeSuggestion(utcTime);
+            return new GnssTimeSuggestion(unixEpochTime);
         }
 
         /**
@@ -1504,19 +1511,19 @@
          * Calculates what the supplied time would be when adjusted for the movement of the fake
          * elapsed realtime clock.
          */
-        long calculateTimeInMillisForNow(TimestampedValue<Long> utcTime) {
-            return TimeDetectorStrategy.getTimeAt(utcTime, peekElapsedRealtimeMillis());
+        long calculateTimeInMillisForNow(TimestampedValue<Long> unixEpochTime) {
+            return TimeDetectorStrategy.getTimeAt(unixEpochTime, peekElapsedRealtimeMillis());
         }
     }
 
     private static TelephonyTimeSuggestion createTelephonyTimeSuggestion(int slotIndex,
-            TimestampedValue<Long> utcTime) {
+            TimestampedValue<Long> unixEpochTime) {
         return new TelephonyTimeSuggestion.Builder(slotIndex)
-                .setUtcTime(utcTime)
+                .setUnixEpochTime(unixEpochTime)
                 .build();
     }
 
-    private static Instant createUtcTime(int year, int monthInYear, int day, int hourOfDay,
+    private static Instant createUnixEpochTime(int year, int monthInYear, int day, int hourOfDay,
             int minute, int second) {
         return LocalDateTime.of(year, monthInYear, day, hourOfDay, minute, second)
                 .toInstant(ZoneOffset.UTC);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index 741f33f..87c75be 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -267,7 +267,8 @@
     @Test
     public void testUpdateSleep() {
         doCallRealMethod().when(mWm.mRoot).hasAwakeDisplay();
-        mSupervisor.mGoingToSleepWakeLock = mock(PowerManager.WakeLock.class);
+        mSupervisor.mGoingToSleepWakeLock =
+                mSystemServicesTestRule.createStubbedWakeLock(true /* needVerification */);
         final Task rootHomeTask = mWm.mRoot.getDefaultTaskDisplayArea().getOrCreateRootHomeTask();
         final ActivityRecord homeActivity = new ActivityBuilder(mAtm).setTask(rootHomeTask).build();
         final ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
diff --git a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
index 8e7ba4bc..0b2399b1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SystemServicesTestRule.java
@@ -102,6 +102,10 @@
     static int sNextTaskId = 100;
 
     private static final int[] TEST_USER_PROFILE_IDS = {};
+    /** Use a real static object so there won't be NPE in finalize() after clearInlineMocks(). */
+    private static final PowerManager.WakeLock sWakeLock = getInstrumentation().getContext()
+            .getSystemService(PowerManager.class).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    private PowerManager.WakeLock mStubbedWakeLock;
 
     private Description mDescription;
     private Context mContext;
@@ -196,7 +200,8 @@
         // Prevent "WakeLock finalized while still held: SCREEN_FROZEN".
         final PowerManager pm = mock(PowerManager.class);
         doReturn(pm).when(mContext).getSystemService(eq(Context.POWER_SERVICE));
-        doReturn(mock(PowerManager.WakeLock.class)).when(pm).newWakeLock(anyInt(), anyString());
+        mStubbedWakeLock = createStubbedWakeLock(false /* needVerification */);
+        doReturn(mStubbedWakeLock).when(pm).newWakeLock(anyInt(), anyString());
 
         // DisplayManagerInternal
         final DisplayManagerInternal dmi = mock(DisplayManagerInternal.class);
@@ -403,6 +408,16 @@
         return mPowerManagerWrapper;
     }
 
+    /** Creates a no-op wakelock object. */
+    PowerManager.WakeLock createStubbedWakeLock(boolean needVerification) {
+        if (needVerification) {
+            return mock(PowerManager.WakeLock.class, Mockito.withSettings()
+                    .spiedInstance(sWakeLock).defaultAnswer(Mockito.RETURNS_DEFAULTS));
+        }
+        return mock(PowerManager.WakeLock.class, Mockito.withSettings()
+                .spiedInstance(sWakeLock).stubOnly());
+    }
+
     void setSurfaceFactory(Supplier<Surface> factory) {
         mSurfaceFactory = factory;
     }
@@ -558,7 +573,7 @@
             // unit test version does not handle launch wake lock
             doNothing().when(this).acquireLaunchWakelock();
 
-            mLaunchingActivityWakeLock = mock(PowerManager.WakeLock.class);
+            mLaunchingActivityWakeLock = mStubbedWakeLock;
 
             initialize();
 
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index d94fafc..980ea5c 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -1476,12 +1476,21 @@
         /**
          * Invoked when the RTT session failed to initiate for some reason, including rejection
          * by the remote party.
+         * <p>
+         * This callback will ONLY be invoked to report a failure related to a user initiated
+         * session modification request (i.e. {@link Call#sendRttRequest()}).
+         * <p>
+         * If a call is initiated with {@link TelecomManager#EXTRA_START_CALL_WITH_RTT} specified,
+         * the availability of RTT can be determined by checking {@link Details#PROPERTY_RTT}
+         * once the call enters state {@link Details#STATE_ACTIVE}.
+         *
          * @param call The call which the RTT initiation failure occurred on.
          * @param reason One of the status codes defined in
-         *               {@link android.telecom.Connection.RttModifyStatus}, with the exception of
-         *               {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
+         *      {@link android.telecom.Connection.RttModifyStatus}, with the exception of
+         *      {@link android.telecom.Connection.RttModifyStatus#SESSION_MODIFY_REQUEST_SUCCESS}.
          */
-        public void onRttInitiationFailure(Call call, int reason) {}
+        public void onRttInitiationFailure(Call call,
+                @android.telecom.Connection.RttModifyStatus.RttSessionModifyStatus int reason) {}
 
         /**
          * Invoked when Call handover from one {@link PhoneAccount} to other {@link PhoneAccount}
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 467084a..21c6b47 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -1399,6 +1399,18 @@
          * Session modify request rejected by remote user.
          */
         public static final int SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE = 5;
+
+
+        /**@hide*/
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(prefix = "SESSION_MODIFY_REQUEST_", value = {
+                SESSION_MODIFY_REQUEST_SUCCESS,
+                SESSION_MODIFY_REQUEST_FAIL,
+                SESSION_MODIFY_REQUEST_INVALID,
+                SESSION_MODIFY_REQUEST_TIMED_OUT,
+                SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE
+        })
+        public @interface RttSessionModifyStatus {}
     }
 
     /**
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 23cf511..e88106c 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -1,6 +1,8 @@
 package android.telephony;
 
 import android.annotation.IntDef;
+import android.net.NetworkAgent;
+import android.net.NetworkCapabilities;
 import android.telecom.Connection;
 import android.telephony.data.ApnSetting;
 
@@ -664,4 +666,59 @@
         TelephonyManager.THERMAL_MITIGATION_RESULT_INVALID_STATE,
         TelephonyManager.THERMAL_MITIGATION_RESULT_UNKNOWN_ERROR})
     public @interface ThermalMitigationResult {}
+
+    /**
+     * Per Android API guideline 8.15, annotation can't be public APIs. So duplicate
+     * android.net.NetworkCapabilities.NetCapability here. Must update here when new capabilities
+     * are added in {@link NetworkCapabilities}.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "NET_CAPABILITY_" }, value = {
+            NetworkCapabilities.NET_CAPABILITY_MMS,
+            NetworkCapabilities.NET_CAPABILITY_SUPL,
+            NetworkCapabilities.NET_CAPABILITY_DUN,
+            NetworkCapabilities.NET_CAPABILITY_FOTA,
+            NetworkCapabilities.NET_CAPABILITY_IMS,
+            NetworkCapabilities.NET_CAPABILITY_CBS,
+            NetworkCapabilities.NET_CAPABILITY_WIFI_P2P,
+            NetworkCapabilities.NET_CAPABILITY_IA,
+            NetworkCapabilities.NET_CAPABILITY_RCS,
+            NetworkCapabilities.NET_CAPABILITY_XCAP,
+            NetworkCapabilities.NET_CAPABILITY_EIMS,
+            NetworkCapabilities.NET_CAPABILITY_NOT_METERED,
+            NetworkCapabilities.NET_CAPABILITY_INTERNET,
+            NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED,
+            NetworkCapabilities.NET_CAPABILITY_TRUSTED,
+            NetworkCapabilities.NET_CAPABILITY_NOT_VPN,
+            NetworkCapabilities.NET_CAPABILITY_VALIDATED,
+            NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL,
+            NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING,
+            NetworkCapabilities.NET_CAPABILITY_FOREGROUND,
+            NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED,
+            NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED,
+            NetworkCapabilities.NET_CAPABILITY_OEM_PAID,
+            NetworkCapabilities.NET_CAPABILITY_MCX,
+            NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY,
+            NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED,
+            NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
+            NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL,
+            NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED,
+            NetworkCapabilities.NET_CAPABILITY_ENTERPRISE,
+            NetworkCapabilities.NET_CAPABILITY_VSIM,
+            NetworkCapabilities.NET_CAPABILITY_BIP,
+            NetworkCapabilities.NET_CAPABILITY_HEAD_UNIT,
+    })
+    public @interface NetCapability { }
+
+    /**
+     * Per Android API guideline 8.15, annotation can't be public APIs. So duplicate
+     * android.net.NetworkAgent.ValidationStatus here. Must update here when new validation status
+     * are added in {@link NetworkAgent}.
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "VALIDATION_STATUS_" }, value = {
+            NetworkAgent.VALIDATION_STATUS_VALID,
+            NetworkAgent.VALIDATION_STATUS_NOT_VALID
+    })
+    public @interface ValidationStatus {}
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 8d3eee0..8f957fd 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -28,6 +28,7 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
+import android.net.NetworkCapabilities;
 import android.net.ipsec.ike.SaProposal;
 import android.os.Build;
 import android.os.PersistableBundle;
@@ -3777,30 +3778,42 @@
     public static final String KEY_OPPORTUNISTIC_ESIM_DOWNLOAD_VIA_WIFI_ONLY_BOOL =
             "opportunistic_esim_download_via_wifi_only_bool";
 
-    /**
-     * Controls RSRP threshold at which OpportunisticNetworkService will decide whether
+/**
+     * Controls RSRP threshold, in dBm, at which OpportunisticNetworkService will decide whether
      * the opportunistic network is good enough for internet data.
+     *
+     * <p>The value of {@link CellSignalStrengthLte#getRsrp()} will be compared with this
+     * threshold.
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSRP_INT =
             "opportunistic_network_entry_threshold_rsrp_int";
 
     /**
-     * Controls RSSNR threshold at which OpportunisticNetworkService will decide whether
-     * the opportunistic network is good enough for internet data.
+     * Controls RSSNR threshold, in dB, at which OpportunisticNetworkService will
+     * decide whether the opportunistic network is good enough for internet data.
+     *
+     * <p>The value of {@link CellSignalStrengthLte#getRssnr()} will be compared with this
+     * threshold.
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT =
             "opportunistic_network_entry_threshold_rssnr_int";
 
     /**
-     * Controls RSRP threshold below which OpportunisticNetworkService will decide whether
+     * Controls RSRP threshold, in dBm, below which OpportunisticNetworkService will decide whether
      * the opportunistic network available is not good enough for internet data.
+     *
+     * <p>The value of {@link CellSignalStrengthLte#getRsrp()} will be compared with this
+     * threshold.
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT =
             "opportunistic_network_exit_threshold_rsrp_int";
 
     /**
-     * Controls RSSNR threshold below which OpportunisticNetworkService will decide whether
-     * the opportunistic network available is not good enough for internet data.
+     * Controls RSSNR threshold, in dB, below which OpportunisticNetworkService will
+     * decide whether the opportunistic network available is not good enough for internet data.
+     *
+     * <p>The value of {@link CellSignalStrengthLte#getRssnr()} will be compared with this
+     * threshold.
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT =
             "opportunistic_network_exit_threshold_rssnr_int";
@@ -3898,7 +3911,7 @@
          * good enough for internet data. Note other factors may be considered for the final
          * decision.
          *
-         * <p>The value of {@link CellSignalStrengthNr#getSsRsrp} will be compared with this
+         * <p>The value of {@link CellSignalStrengthNr#getSsRsrp()} will be compared with this
          * threshold.
          *
          * @hide
@@ -3925,7 +3938,7 @@
          * good enough for internet data. Note other factors may be considered for the final
          * decision.
          *
-         * <p>The value of {@link CellSignalStrengthNr#getSsRsrq} will be compared with this
+         * <p>The value of {@link CellSignalStrengthNr#getSsRsrq()} will be compared with this
          * threshold.
          *
          * @hide
@@ -3952,6 +3965,9 @@
          * be considered good enough for internet data. Note other factors may be considered
          * for the final decision.
          *
+         * <p>The value of {@link CellSignalStrengthNr#getSsRsrp()} will be compared with this
+         * threshold.
+         *
          * @hide
          */
         public static final String KEY_EXIT_THRESHOLD_SS_RSRP_INT =
@@ -3975,6 +3991,9 @@
          * be considered good enough for internet data. Note other factors may be considered
          * for the final decision.
          *
+         * <p>The value of {@link CellSignalStrengthNr#getSsRsrq()} will be compared with this
+         * threshold.
+         *
          * @hide
          */
         public static final String KEY_EXIT_THRESHOLD_SS_RSRQ_DOUBLE =
@@ -5446,6 +5465,53 @@
     public static final String KEY_APN_PRIORITY_STRING_ARRAY = "apn_priority_string_array";
 
     /**
+     * Network capability priority for determine the satisfy order in telephony. The priority is
+     * from the lowest 0 to the highest 100. The long-lived network shall have the lowest priority.
+     * This allows other short-lived requests like MMS requests to be established. Emergency request
+     * always has the highest priority.
+     *
+     * @hide
+     */
+    public static final String KEY_TELEPHONY_NETWORK_CAPABILITY_PRIORITIES_STRING_ARRAY =
+            "telephony_network_capability_priorities_string_array";
+
+    /**
+     * Defines the rules for data retry.
+     *
+     * The syntax of the retry rule:
+     * 1. Retry based on {@link NetworkCapabilities}. Note that only APN-type network capabilities
+     *    are supported.
+     * "capabilities=[netCaps1|netCaps2|...], [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
+     *
+     * 2. Retry based on {@link DataFailCause}
+     * "fail_causes=[cause1|cause2|cause3|..], [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
+     *
+     * 3. Retry based on {@link NetworkCapabilities} and {@link DataFailCause}. Note that only
+     *    APN-type network capabilities are supported.
+     * "capabilities=[netCaps1|netCaps2|...], fail_causes=[cause1|cause2|cause3|...],
+     *     [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
+     *
+     * For example,
+     * "capabilities=eims, retry_interval=1000, maximum_retries=20" means if the attached
+     * network request is emergency, then retry data network setup every 1 second for up to 20
+     * times.
+     *
+     * "fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|2253|2254
+     * , maximum_retries=0" means for those fail causes, never retry with timers. Note that
+     * when environment changes, retry can still happen.
+     *
+     * "capabilities=internet|enterprise|dun|ims|fota, retry_interval=2500|3000|"
+     * "5000|10000|15000|20000|40000|60000|120000|240000|600000|1200000|1800000"
+     * "1800000, maximum_retries=20" means for those capabilities, retry happens in 2.5s, 3s, 5s,
+     * 10s, 15s, 20s, 40s, 1m, 2m, 4m, 10m, 20m, 30m, 30m, 30m, until reaching 20 retries.
+     *
+     * // TODO: remove KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS
+     * @hide
+     */
+    public static final String KEY_TELEPHONY_DATA_RETRY_RULES_STRING_ARRAY =
+            "telephony_data_retry_rules_string_array";
+
+    /**
      * The patterns of missed incoming call sms. This is the regular expression used for
      * matching the missed incoming call's date, time, and caller id. The pattern should match
      * fields for at least month, day, hour, and minute. Year is optional although it is encouraged.
@@ -6135,9 +6201,9 @@
         /* Default value is minimum RSRP level needed for SIGNAL_STRENGTH_MODERATE */
         sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT, -118);
         /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_GOOD */
-        sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT, 45);
+        sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT, 5);
         /* Default value is minimum RSSNR level needed for SIGNAL_STRENGTH_MODERATE */
-        sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT, 10);
+        sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT, 1);
         /* Default value is 1024 kbps */
         sDefaults.putInt(KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_BANDWIDTH_INT, 1024);
         /* Default value is 10 seconds */
@@ -6213,6 +6279,24 @@
                 "enterprise:0", "default:1", "mms:2", "supl:2", "dun:2", "hipri:3", "fota:2",
                 "ims:2", "cbs:2", "ia:2", "emergency:2", "mcx:3", "xcap:3"
         });
+
+        // Do not modify the priority unless you know what you are doing. This will have significant
+        // impacts on the order of data network setup.
+        sDefaults.putStringArray(
+                KEY_TELEPHONY_NETWORK_CAPABILITY_PRIORITIES_STRING_ARRAY, new String[] {
+                        "eims:90", "supl:80", "mms:70", "xcap:70", "cbs:50", "mcx:50", "fota:50",
+                        "ims:40", "dun:30", "enterprise:20", "internet:20"
+                });
+        sDefaults.putStringArray(
+                KEY_TELEPHONY_DATA_RETRY_RULES_STRING_ARRAY, new String[] {
+                        "capabilities=eims, retry_interval=1000, maximum_retries=20",
+                        "fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|2253|"
+                                + "2254, maximum_retries=0", // No retry for those causes
+                        "capabilities=mms|supl|cbs, retry_interval=2000",
+                        "capabilities=internet|enterprise|dun|ims|fota, retry_interval=2500|3000|"
+                                + "5000|10000|15000|20000|40000|60000|120000|240000|"
+                                + "600000|1200000|1800000, maximum_retries=20"
+                });
         sDefaults.putStringArray(KEY_MISSED_INCOMING_CALL_SMS_PATTERN_STRING_ARRAY, new String[0]);
         sDefaults.putBoolean(KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, false);
         sDefaults.putString(KEY_DEFAULT_PREFERRED_APN_NAME_STRING, "");
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 947dc01..5e90261 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -125,13 +125,13 @@
     /**
      * Construct a cell signal strength
      *
-     * @param rssi in dBm [-113,-51], UNKNOWN
-     * @param rsrp in dBm [-140,-43], UNKNOWN
-     * @param rsrq in dB [-34, 3], UNKNOWN
-     * @param rssnr in dB [-20, +30], UNKNOWN
-     * @param cqiTableIndex [1, 6], UNKNOWN
-     * @param cqi [0, 15], UNKNOWN
-     * @param timingAdvance [0, 1282], UNKNOWN
+     * @param rssi in dBm [-113,-51], {@link CellInfo#UNAVAILABLE}
+     * @param rsrp in dBm [-140,-43], {@link CellInfo#UNAVAILABLE}
+     * @param rsrq in dB [-34, 3], {@link CellInfo#UNAVAILABLE}
+     * @param rssnr in dB [-20, +30], {@link CellInfo#UNAVAILABLE}
+     * @param cqiTableIndex [1, 6], {@link CellInfo#UNAVAILABLE}
+     * @param cqi [0, 15], {@link CellInfo#UNAVAILABLE}
+     * @param timingAdvance [0, 1282], {@link CellInfo#UNAVAILABLE}
      *
      */
     /** @hide */
@@ -151,12 +151,12 @@
     /**
      * Construct a cell signal strength
      *
-     * @param rssi in dBm [-113,-51], UNKNOWN
-     * @param rsrp in dBm [-140,-43], UNKNOWN
-     * @param rsrq in dB [-34, 3], UNKNOWN
-     * @param rssnr in dB [-20, +30], UNKNOWN
-     * @param cqi [0, 15], UNKNOWN
-     * @param timingAdvance [0, 1282], UNKNOWN
+     * @param rssi in dBm [-113,-51], {@link CellInfo#UNAVAILABLE}
+     * @param rsrp in dBm [-140,-43], {@link CellInfo#UNAVAILABLE}
+     * @param rsrq in dB [-34, 3], {@link CellInfo#UNAVAILABLE}
+     * @param rssnr in dB [-20, +30], {@link CellInfo#UNAVAILABLE}
+     * @param cqi [0, 15], {@link CellInfo#UNAVAILABLE}
+     * @param timingAdvance [0, 1282], {@link CellInfo#UNAVAILABLE}
      *
      */
     /** @hide */
@@ -403,10 +403,11 @@
     }
 
     /**
-     * Get reference signal signal-to-noise ratio
+     * Get reference signal signal-to-noise ratio in dB
+     * Range: -20 dB to +30 dB.
      *
      * @return the RSSNR if available or
-     *         {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable.
+     *         {@link android.telephony.CellInfo#UNAVAILABLE} if unavailable.
      */
     public int getRssnr() {
         return mRssnr;
@@ -414,8 +415,10 @@
 
     /**
      * Get reference signal received power in dBm
+     * Range: -140 dBm to -43 dBm.
      *
-     * @return the RSRP of the measured cell.
+     * @return the RSRP of the measured cell or {@link CellInfo#UNAVAILABLE} if
+     * unavailable.
      */
     public int getRsrp() {
         return mRsrp;
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
index 88efe1f..56bf303 100644
--- a/telephony/java/android/telephony/DataFailCause.java
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -1076,6 +1076,13 @@
      */
     public static final int SERVICE_TEMPORARILY_UNAVAILABLE = 0x10009;
 
+    /**
+     * The request is not supported by the vendor.
+     *
+     * @hide
+     */
+    public static final int REQUEST_NOT_SUPPORTED = 0x1000A;
+
     private static final Map<Integer, String> sFailCauseMap;
     static {
         sFailCauseMap = new HashMap<>();
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index d6dce25..8c02ffe 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -2158,8 +2158,7 @@
                     | TYPE_FOTA | TYPE_IMS | TYPE_CBS | TYPE_IA | TYPE_EMERGENCY | TYPE_MCX
                     | TYPE_XCAP | TYPE_VSIM | TYPE_BIP | TYPE_ENTERPRISE)) == 0
                 || TextUtils.isEmpty(mApnName) || TextUtils.isEmpty(mEntryName)) {
-                throw new IllegalArgumentException("mApName=" + mApnName + ", mEntryName="
-                        + mEntryName + ", mApnTypeBitmask=" + mApnTypeBitmask);
+                return null;
             }
             return new ApnSetting(this);
         }
diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java
index 93903d2..c1d16a9 100644
--- a/telephony/java/android/telephony/data/DataProfile.java
+++ b/telephony/java/android/telephony/data/DataProfile.java
@@ -18,13 +18,16 @@
 
 import static android.telephony.data.ApnSetting.ProtocolType;
 
+import android.annotation.ElapsedRealtimeLong;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.net.NetworkCapabilities;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.Annotation.ApnType;
+import android.telephony.Annotation.NetCapability;
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyManager.NetworkTypeBitMask;
 import android.telephony.data.ApnSetting.AuthType;
@@ -66,7 +69,13 @@
 
     private final @Nullable TrafficDescriptor mTrafficDescriptor;
 
-    private final boolean mPreferred;
+    private boolean mPreferred;
+
+    /**
+     * The last timestamp of this data profile being used for data network setup. Never add this
+     * to {@link #equals(Object)} and {@link #hashCode()}.
+     */
+    private @ElapsedRealtimeLong long mSetupTimestamp;
 
     private DataProfile(@NonNull Builder builder) {
         mApnSetting = builder.mApnSetting;
@@ -99,6 +108,7 @@
         mApnSetting = source.readParcelable(ApnSetting.class.getClassLoader());
         mTrafficDescriptor = source.readParcelable(TrafficDescriptor.class.getClassLoader());
         mPreferred = source.readBoolean();
+        mSetupTimestamp = source.readLong();
     }
 
     /**
@@ -291,6 +301,16 @@
     }
 
     /**
+     * Set the preferred flag for the data profile.
+     *
+     * @param preferred {@code true} if this data profile is preferred for internet.
+     * @hide
+     */
+    public void setPreferred(boolean preferred) {
+        mPreferred = preferred;
+    }
+
+    /**
      * @return {@code true} if this data profile was used to bring up the last default
      * (i.e internet) data connection successfully, or the one chosen by the user in Settings'
      * APN editor. For one carrier there can be only one profiled preferred.
@@ -315,6 +335,94 @@
         return mTrafficDescriptor;
     }
 
+    /**
+     * Check if this data profile can satisfy certain network capabilities
+     *
+     * @param networkCapabilities The network capabilities. Note that the non-APN-type capabilities
+     * will be ignored.
+     *
+     * @return {@code true} if this data profile can satisfy the given network capabilities.
+     * @hide
+     */
+    public boolean canSatisfy(@NonNull @NetCapability int[] networkCapabilities) {
+        if (mApnSetting != null) {
+            for (int netCap : networkCapabilities) {
+                if (!canSatisfy(netCap)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check if this data profile can satisfy a certain network capability.
+     *
+     * @param networkCapability The network capability. Note that the non-APN-type capability
+     * will always be satisfied.
+     * @return {@code true} if this data profile can satisfy the given network capability.
+     * @hide
+     */
+    public boolean canSatisfy(@NetCapability int networkCapability) {
+        return mApnSetting != null && mApnSetting.canHandleType(
+                networkCapabilityToApnType(networkCapability));
+    }
+
+    /**
+     * Convert network capability into APN type.
+     *
+     * @param networkCapability Network capability.
+     * @return APN type.
+     * @hide
+     */
+    private static @ApnType int networkCapabilityToApnType(@NetCapability int networkCapability) {
+        switch (networkCapability) {
+            case NetworkCapabilities.NET_CAPABILITY_MMS:
+                return ApnSetting.TYPE_MMS;
+            case NetworkCapabilities.NET_CAPABILITY_SUPL:
+                return ApnSetting.TYPE_SUPL;
+            case NetworkCapabilities.NET_CAPABILITY_DUN:
+                return ApnSetting.TYPE_DUN;
+            case NetworkCapabilities.NET_CAPABILITY_FOTA:
+                return ApnSetting.TYPE_FOTA;
+            case NetworkCapabilities.NET_CAPABILITY_IMS:
+                return ApnSetting.TYPE_IMS;
+            case NetworkCapabilities.NET_CAPABILITY_CBS:
+                return ApnSetting.TYPE_CBS;
+            case NetworkCapabilities.NET_CAPABILITY_XCAP:
+                return ApnSetting.TYPE_XCAP;
+            case NetworkCapabilities.NET_CAPABILITY_EIMS:
+                return ApnSetting.TYPE_EMERGENCY;
+            case NetworkCapabilities.NET_CAPABILITY_INTERNET:
+                return ApnSetting.TYPE_DEFAULT;
+            case NetworkCapabilities.NET_CAPABILITY_MCX:
+                return ApnSetting.TYPE_MCX;
+            case NetworkCapabilities.NET_CAPABILITY_IA:
+                return ApnSetting.TYPE_IA;
+            default:
+                return ApnSetting.TYPE_NONE;
+        }
+    }
+
+    /**
+     * Set the timestamp of this data profile being used for data network setup.
+     *
+     * @hide
+     */
+    public void setLastSetupTimestamp(@ElapsedRealtimeLong long timestamp) {
+        mSetupTimestamp = timestamp;
+    }
+
+    /**
+     * @return the timestamp of this data profile being used for data network setup.
+     *
+     * @hide
+     */
+    public @ElapsedRealtimeLong long getLastSetupTimestamp() {
+        return mSetupTimestamp;
+    }
+
     @Override
     public int describeContents() {
         return 0;
@@ -323,8 +431,8 @@
     @NonNull
     @Override
     public String toString() {
-        return "DataProfile=" + mApnSetting + ", " + mTrafficDescriptor + ", preferred="
-                + mPreferred;
+        return "[DataProfile=" + mApnSetting + ", " + mTrafficDescriptor + ", preferred="
+                + mPreferred + "]";
     }
 
     @Override
@@ -333,6 +441,7 @@
         dest.writeParcelable(mApnSetting, flags);
         dest.writeParcelable(mTrafficDescriptor, flags);
         dest.writeBoolean(mPreferred);
+        dest.writeLong(mSetupTimestamp);
     }
 
     public static final @android.annotation.NonNull Parcelable.Creator<DataProfile> CREATOR =
diff --git a/tests/TrustTests/OWNERS b/tests/TrustTests/OWNERS
new file mode 100644
index 0000000..e2c6ce1
--- /dev/null
+++ b/tests/TrustTests/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/service/trust/OWNERS
diff --git a/tools/aapt/Android.bp b/tools/aapt/Android.bp
index 01eb4f6..cc10db9 100644
--- a/tools/aapt/Android.bp
+++ b/tools/aapt/Android.bp
@@ -61,16 +61,6 @@
             enabled: true,
         },
     },
-
-    // This tool is prebuilt if we're doing an app-only build.
-    product_variables: {
-        pdk: {
-            enabled: false,
-        },
-        unbundled_build: {
-            enabled: false,
-        },
-    },
 }
 
 // ==========================================================
diff --git a/tools/bit/command.cpp b/tools/bit/command.cpp
index f95ea11..6c68e0b 100644
--- a/tools/bit/command.cpp
+++ b/tools/bit/command.cpp
@@ -192,10 +192,11 @@
     if (strchr(prog, '/') != NULL) {
         return execve(prog, (char*const*)argv, (char*const*)envp);
     } else {
-        char* pathEnv = strdup(getenv("PATH"));
-        if (pathEnv == NULL) {
+        const char* pathEnvRaw = getenv("PATH");
+        if (pathEnvRaw == NULL) {
             return 1;
         }
+        char* pathEnv = strdup(pathEnvRaw);
         char* dir = pathEnv;
         while (dir) {
             char* next = strchr(dir, ':');