Merge "Adding check for HMAC/EC key size for StrongBox"
diff --git a/Android.bp b/Android.bp
index 9a815c6..124f473 100644
--- a/Android.bp
+++ b/Android.bp
@@ -484,6 +484,8 @@
         "telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl",
         "telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl",
         "telecomm/java/com/android/internal/telecom/IInCallService.aidl",
+        "telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionCallback.aidl",
+        "telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionService.aidl",
         "telecomm/java/com/android/internal/telecom/ITelecomService.aidl",
         "telecomm/java/com/android/internal/telecom/RemoteServiceCallback.aidl",
         "telephony/java/android/telephony/data/IDataService.aidl",
@@ -502,6 +504,7 @@
         "telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl",
         "telephony/java/android/telephony/ims/aidl/IImsServiceControllerListener.aidl",
         "telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl",
+        "telephony/java/android/telephony/ims/aidl/IRcs.aidl",
         "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl",
         "telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl",
         "telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl",
@@ -578,7 +581,6 @@
         "telephony/java/com/android/internal/telephony/euicc/ISetDefaultSmdpAddressCallback.aidl",
         "telephony/java/com/android/internal/telephony/euicc/ISetNicknameCallback.aidl",
         "telephony/java/com/android/internal/telephony/euicc/ISwitchToProfileCallback.aidl",
-        "telephony/java/com/android/internal/telephony/rcs/IRcs.aidl",
         "wifi/java/android/net/wifi/ISoftApCallback.aidl",
         "wifi/java/android/net/wifi/IWifiManager.aidl",
         "wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl",
@@ -621,6 +623,8 @@
         "core/java/com/android/server/DropboxLogTags.logtags",
         "core/java/org/chromium/arc/EventLogTags.logtags",
 
+        ":platform-properties",
+
         ":framework-statslog-gen",
     ],
 
@@ -653,7 +657,6 @@
             "frameworks/av/media/libaudioclient/aidl",
             "frameworks/native/aidl/gui",
             "system/core/storaged/binder",
-            "system/netd/server/binder",
             "system/vold/binder",
             "system/bt/binder",
             "system/security/keystore/binder",
@@ -676,6 +679,7 @@
 
     static_libs: [
         "apex_aidl_interface-java",
+        "networkstack-aidl-interfaces-java",
         "framework-protos",
         "android.hidl.base-V1.0-java",
         "android.hardware.cas-V1.0-java",
@@ -815,6 +819,16 @@
     output_extension: "srcjar",
 }
 
+// AIDL interfaces between the core system and the networking mainline module.
+aidl_interface {
+    name: "networkstack-aidl-interfaces",
+    local_include_dir: "core/java",
+    srcs: [
+        "core/java/android/net/INetworkStackConnector.aidl",
+    ],
+    api_dir: "aidl/networkstack",
+}
+
 // Build ext.jar
 // ============================================================
 java_library {
@@ -1146,6 +1160,7 @@
 metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " +
     "--hide-package com.android.okhttp " +
     "--hide-package com.android.org.conscrypt --hide-package com.android.server " +
+    "--error UnhiddenSystemApi " +
     "--hide RequiresPermission " +
     "--hide MissingPermission --hide BroadcastBehavior " +
     "--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
@@ -1562,6 +1577,7 @@
     dex_mapping_filename: "dex-mapping.txt",
     args: metalava_framework_docs_args +
         " --hide ReferencesHidden " +
+        " --hide UnhiddenSystemApi " +
         " --show-unannotated " +
         " --show-annotation android.annotation.SystemApi " +
         " --show-annotation android.annotation.TestApi "
diff --git a/Android.mk b/Android.mk
index 92e33e9..e3cc275 100644
--- a/Android.mk
+++ b/Android.mk
@@ -72,6 +72,11 @@
 	$(hide) mkdir -p $(OUT_DOCS)/offline-sdk
 	( unzip -qo $< -d $(OUT_DOCS)/offline-sdk && touch -f $@ ) || exit 1
 
+# Run this for checkbuild
+checkbuild: doc-comment-check-docs
+# Check comment when you are updating the API
+update-api: doc-comment-check-docs
+
 # ==== hiddenapi lists =======================================
 .KATI_RESTAT: $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS)
 $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): \
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index e061b15..543f0ed 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,13 +1,5 @@
 [Hook Scripts]
 checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
-                  -fw core/java/android/
-                      graphics/java/android
-                      core/tests/coretests/src/android/
-                      packages/PrintRecommendationService/
-                      packages/PrintSpooler/
-                      services/print/
-                      services/usb/
-                      telephony/
 
 api_lint_hook = ${REPO_ROOT}/frameworks/base/tools/apilint/apilint_sha.sh ${PREUPLOAD_COMMIT}
 
diff --git a/api/current.txt b/api/current.txt
index 4e4d823..65c988f 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -27225,7 +27225,7 @@
     method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
     method public boolean bindProcessToNetwork(android.net.Network);
     method public android.net.Network getActiveNetwork();
-    method public android.net.NetworkInfo getActiveNetworkInfo();
+    method public deprecated android.net.NetworkInfo getActiveNetworkInfo();
     method public deprecated android.net.NetworkInfo[] getAllNetworkInfo();
     method public android.net.Network[] getAllNetworks();
     method public deprecated boolean getBackgroundDataSetting();
@@ -27236,7 +27236,7 @@
     method public int getMultipathPreference(android.net.Network);
     method public android.net.NetworkCapabilities getNetworkCapabilities(android.net.Network);
     method public deprecated android.net.NetworkInfo getNetworkInfo(int);
-    method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
+    method public deprecated android.net.NetworkInfo getNetworkInfo(android.net.Network);
     method public deprecated int getNetworkPreference();
     method public byte[] getNetworkWatchlistConfigHash();
     method public static deprecated android.net.Network getProcessDefaultNetwork();
@@ -27270,14 +27270,14 @@
     field public static final deprecated int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
     field public static final java.lang.String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
     field public static final java.lang.String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
-    field public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo";
-    field public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover";
+    field public static final deprecated java.lang.String EXTRA_EXTRA_INFO = "extraInfo";
+    field public static final deprecated java.lang.String EXTRA_IS_FAILOVER = "isFailover";
     field public static final java.lang.String EXTRA_NETWORK = "android.net.extra.NETWORK";
     field public static final deprecated java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
     field public static final java.lang.String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
     field public static final java.lang.String EXTRA_NETWORK_TYPE = "networkType";
     field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
-    field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
+    field public static final deprecated java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
     field public static final java.lang.String EXTRA_REASON = "reason";
     field public static final int MULTIPATH_PREFERENCE_HANDOVER = 1; // 0x1
     field public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 4; // 0x4
@@ -27333,6 +27333,11 @@
     field public int serverAddress;
   }
 
+  public class InetAddresses {
+    method public static boolean isNumericAddress(java.lang.String);
+    method public static java.net.InetAddress parseNumericAddress(java.lang.String);
+  }
+
   public final class IpPrefix implements android.os.Parcelable {
     method public boolean contains(java.net.InetAddress);
     method public int describeContents();
@@ -27424,6 +27429,7 @@
     method public android.net.ProxyInfo getHttpProxy();
     method public java.lang.String getInterfaceName();
     method public java.util.List<android.net.LinkAddress> getLinkAddresses();
+    method public int getMtu();
     method public java.lang.String getPrivateDnsServerName();
     method public java.util.List<android.net.RouteInfo> getRoutes();
     method public boolean isPrivateDnsActive();
@@ -27572,10 +27578,10 @@
     field public static final int TRANSPORT_WIFI_AWARE = 5; // 0x5
   }
 
-  public class NetworkInfo implements android.os.Parcelable {
+  public deprecated class NetworkInfo implements android.os.Parcelable {
     method public int describeContents();
     method public deprecated android.net.NetworkInfo.DetailedState getDetailedState();
-    method public java.lang.String getExtraInfo();
+    method public deprecated java.lang.String getExtraInfo();
     method public deprecated java.lang.String getReason();
     method public deprecated android.net.NetworkInfo.State getState();
     method public deprecated int getSubtype();
@@ -27591,7 +27597,7 @@
     field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
   }
 
-  public static final class NetworkInfo.DetailedState extends java.lang.Enum {
+  public static final deprecated class NetworkInfo.DetailedState extends java.lang.Enum {
     method public static android.net.NetworkInfo.DetailedState valueOf(java.lang.String);
     method public static final android.net.NetworkInfo.DetailedState[] values();
     enum_constant public static final android.net.NetworkInfo.DetailedState AUTHENTICATING;
@@ -27609,7 +27615,7 @@
     enum_constant public static final android.net.NetworkInfo.DetailedState VERIFYING_POOR_LINK;
   }
 
-  public static final class NetworkInfo.State extends java.lang.Enum {
+  public static final deprecated class NetworkInfo.State extends java.lang.Enum {
     method public static android.net.NetworkInfo.State valueOf(java.lang.String);
     method public static final android.net.NetworkInfo.State[] values();
     enum_constant public static final android.net.NetworkInfo.State CONNECTED;
@@ -37330,10 +37336,13 @@
   }
 
   public static final class Telephony.CarrierId implements android.provider.BaseColumns {
+    method public static android.net.Uri getPreciseCarrierIdUriForSubscriptionId(int);
     method public static android.net.Uri getUriForSubscriptionId(int);
     field public static final java.lang.String CARRIER_ID = "carrier_id";
     field public static final java.lang.String CARRIER_NAME = "carrier_name";
     field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String PRECISE_CARRIER_ID = "precise_carrier_id";
+    field public static final java.lang.String PRECISE_CARRIER_ID_NAME = "precise_carrier_id_name";
   }
 
   public static final class Telephony.Carriers implements android.provider.BaseColumns {
@@ -37345,22 +37354,23 @@
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String CURRENT = "current";
     field public static final java.lang.String DEFAULT_SORT_ORDER = "name ASC";
-    field public static final java.lang.String MCC = "mcc";
+    field public static final deprecated java.lang.String MCC = "mcc";
     field public static final java.lang.String MMSC = "mmsc";
     field public static final java.lang.String MMSPORT = "mmsport";
     field public static final java.lang.String MMSPROXY = "mmsproxy";
-    field public static final java.lang.String MNC = "mnc";
-    field public static final java.lang.String MVNO_MATCH_DATA = "mvno_match_data";
-    field public static final java.lang.String MVNO_TYPE = "mvno_type";
+    field public static final deprecated java.lang.String MNC = "mnc";
+    field public static final deprecated java.lang.String MVNO_MATCH_DATA = "mvno_match_data";
+    field public static final deprecated java.lang.String MVNO_TYPE = "mvno_type";
     field public static final java.lang.String NAME = "name";
     field public static final java.lang.String NETWORK_TYPE_BITMASK = "network_type_bitmask";
-    field public static final java.lang.String NUMERIC = "numeric";
+    field public static final deprecated java.lang.String NUMERIC = "numeric";
     field public static final java.lang.String PASSWORD = "password";
     field public static final java.lang.String PORT = "port";
     field public static final java.lang.String PROTOCOL = "protocol";
     field public static final java.lang.String PROXY = "proxy";
     field public static final java.lang.String ROAMING_PROTOCOL = "roaming_protocol";
     field public static final java.lang.String SERVER = "server";
+    field public static final android.net.Uri SIM_APN_URI;
     field public static final java.lang.String SUBSCRIPTION_ID = "sub_id";
     field public static final java.lang.String TYPE = "type";
     field public static final java.lang.String USER = "user";
@@ -39458,13 +39468,16 @@
 
   public class CarrierIdentifier implements android.os.Parcelable {
     ctor public CarrierIdentifier(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+    ctor public CarrierIdentifier(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, int);
     ctor public CarrierIdentifier(byte[], java.lang.String, java.lang.String);
     method public int describeContents();
+    method public int getCarrierId();
     method public java.lang.String getGid1();
     method public java.lang.String getGid2();
     method public java.lang.String getImsi();
     method public java.lang.String getMcc();
     method public java.lang.String getMnc();
+    method public int getPreciseCarrierId();
     method public java.lang.String getSpn();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.carrier.CarrierIdentifier> CREATOR;
@@ -40855,7 +40868,9 @@
     field public static final int SIOCGIFBRDADDR;
     field public static final int SIOCGIFDSTADDR;
     field public static final int SIOCGIFNETMASK;
+    field public static final int SOCK_CLOEXEC;
     field public static final int SOCK_DGRAM;
+    field public static final int SOCK_NONBLOCK;
     field public static final int SOCK_RAW;
     field public static final int SOCK_SEQPACKET;
     field public static final int SOCK_STREAM;
@@ -41116,8 +41131,9 @@
     method public void swapConference();
     method public void unhold();
     method public void unregisterCallback(android.telecom.Call.Callback);
-    field public static final java.lang.String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
+    field public static final deprecated java.lang.String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
     field public static final java.lang.String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS = "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS";
+    field public static final java.lang.String EXTRA_SUGGESTED_PHONE_ACCOUNTS = "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS";
     field public static final int STATE_ACTIVE = 4; // 0x4
     field public static final int STATE_CONNECTING = 9; // 0x9
     field public static final int STATE_DIALING = 1; // 0x1
@@ -41688,6 +41704,20 @@
     field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccountHandle> CREATOR;
   }
 
+  public final class PhoneAccountSuggestion implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
+    method public int getReason();
+    method public boolean shouldAutoSelect();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccountSuggestion> CREATOR;
+    field public static final int REASON_FREQUENT = 2; // 0x2
+    field public static final int REASON_INTRA_CARRIER = 1; // 0x1
+    field public static final int REASON_NONE = 0; // 0x0
+    field public static final int REASON_OTHER = 4; // 0x4
+    field public static final int REASON_USER_SET = 3; // 0x3
+  }
+
   public final class RemoteConference {
     method public void disconnect();
     method public java.util.List<android.telecom.RemoteConnection> getConferenceableConnections();
@@ -41919,9 +41949,12 @@
 
   public static final class VideoProfile.CameraCapabilities implements android.os.Parcelable {
     ctor public VideoProfile.CameraCapabilities(int, int);
+    ctor public VideoProfile.CameraCapabilities(int, int, boolean, float);
     method public int describeContents();
     method public int getHeight();
+    method public float getMaxZoom();
     method public int getWidth();
+    method public boolean isZoomSupported();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telecom.VideoProfile.CameraCapabilities> CREATOR;
   }
@@ -42072,6 +42105,7 @@
     field public static final java.lang.String KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY = "call_forwarding_blocks_while_roaming_string_array";
     field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool";
     field public static final java.lang.String KEY_CARRIER_CALL_SCREENING_APP_STRING = "call_screening_app";
+    field public static final java.lang.String KEY_CARRIER_CONFIG_VERSION_STRING = "carrier_config_version_string";
     field public static final java.lang.String KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS = "carrier_data_call_permanent_failure_strings";
     field public static final java.lang.String KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT = "carrier_default_wfc_ims_mode_int";
     field public static final java.lang.String KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT = "carrier_default_wfc_ims_roaming_mode_int";
@@ -42830,6 +42864,7 @@
   public class SubscriptionInfo implements android.os.Parcelable {
     method public android.graphics.Bitmap createIconBitmap(android.content.Context);
     method public int describeContents();
+    method public int getCarrierId();
     method public java.lang.CharSequence getCarrierName();
     method public java.lang.String getCountryIso();
     method public int getDataRoaming();
@@ -42869,12 +42904,14 @@
     method public static int getSlotIndex(int);
     method public int[] getSubscriptionIds(int);
     method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
+    method public java.util.List<android.telephony.SubscriptionInfo> getSubscriptionsInGroup(int);
     method public boolean isActiveSubscriptionId(int);
     method public boolean isNetworkRoaming(int);
     method public static boolean isUsableSubscriptionId(int);
     method public static boolean isValidSubscriptionId(int);
     method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
+    method public boolean removeSubscriptionsFromGroup(int[]);
     method public java.lang.String setSubscriptionGroup(int[]);
     method public void setSubscriptionOverrideCongested(int, boolean, long);
     method public void setSubscriptionOverrideUnmetered(int, boolean, long);
@@ -42939,6 +42976,7 @@
     method public java.util.List<android.telephony.CellInfo> getAllCellInfo();
     method public int getCallState();
     method public android.os.PersistableBundle getCarrierConfig();
+    method public int getCarrierIdFromSimMccMnc();
     method public deprecated android.telephony.CellLocation getCellLocation();
     method public java.util.Map<java.lang.Integer, java.util.List<android.telephony.emergency.EmergencyNumber>> getCurrentEmergencyNumberList();
     method public java.util.Map<java.lang.Integer, java.util.List<android.telephony.emergency.EmergencyNumber>> getCurrentEmergencyNumberList(int);
@@ -42976,6 +43014,8 @@
     method public java.lang.String getSimCountryIso();
     method public java.lang.String getSimOperator();
     method public java.lang.String getSimOperatorName();
+    method public int getSimPreciseCarrierId();
+    method public java.lang.CharSequence getSimPreciseCarrierIdName();
     method public java.lang.String getSimSerialNumber();
     method public int getSimState();
     method public int getSimState(int);
@@ -43031,6 +43071,7 @@
     field public static final java.lang.String ACTION_SECRET_CODE = "android.telephony.action.SECRET_CODE";
     field public static final java.lang.String ACTION_SHOW_VOICEMAIL_NOTIFICATION = "android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION";
     field public static final java.lang.String ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED = "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED";
+    field public static final java.lang.String ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED = "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED";
     field public static final int APPTYPE_CSIM = 4; // 0x4
     field public static final int APPTYPE_ISIM = 5; // 0x5
     field public static final int APPTYPE_RUIM = 3; // 0x3
@@ -43063,6 +43104,8 @@
     field public static final java.lang.String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT";
     field public static final java.lang.String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT";
     field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE";
+    field public static final java.lang.String EXTRA_PRECISE_CARRIER_ID = "android.telephony.extra.PRECISE_CARRIER_ID";
+    field public static final java.lang.String EXTRA_PRECISE_CARRIER_NAME = "android.telephony.extra.PRECISE_CARRIER_NAME";
     field public static final java.lang.String EXTRA_STATE = "state";
     field public static final java.lang.String EXTRA_STATE_IDLE;
     field public static final java.lang.String EXTRA_STATE_OFFHOOK;
diff --git a/api/system-current.txt b/api/system-current.txt
index 1e5594c..5fd2bf8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4,7 +4,6 @@
     field public static final java.lang.String ACCESS_AMBIENT_LIGHT_STATS = "android.permission.ACCESS_AMBIENT_LIGHT_STATS";
     field public static final java.lang.String ACCESS_BROADCAST_RADIO = "android.permission.ACCESS_BROADCAST_RADIO";
     field public static final java.lang.String ACCESS_CACHE_FILESYSTEM = "android.permission.ACCESS_CACHE_FILESYSTEM";
-    field public static final java.lang.String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";
     field public static final java.lang.String ACCESS_DRM_CERTIFICATES = "android.permission.ACCESS_DRM_CERTIFICATES";
     field public static final deprecated java.lang.String ACCESS_FM_RADIO = "android.permission.ACCESS_FM_RADIO";
     field public static final java.lang.String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";
@@ -13,13 +12,10 @@
     field public static final java.lang.String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS";
     field public static final java.lang.String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS";
     field public static final java.lang.String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER";
-    field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
     field public static final java.lang.String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
     field public static final java.lang.String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
     field public static final java.lang.String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK";
     field public static final java.lang.String BACKUP = "android.permission.BACKUP";
-    field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
-    field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
     field public static final deprecated java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
     field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
     field public static final java.lang.String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
@@ -27,8 +23,8 @@
     field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
     field public static final java.lang.String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE";
     field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE";
+    field public static final java.lang.String BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE = "android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE";
     field public static final java.lang.String BIND_PRINT_RECOMMENDATION_SERVICE = "android.permission.BIND_PRINT_RECOMMENDATION_SERVICE";
-    field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
     field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
     field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE";
     field public static final java.lang.String BIND_SETTINGS_SUGGESTIONS_SERVICE = "android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE";
@@ -38,20 +34,13 @@
     field public static final java.lang.String BIND_TEXTCLASSIFIER_SERVICE = "android.permission.BIND_TEXTCLASSIFIER_SERVICE";
     field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
     field public static final java.lang.String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE";
-    field public static final java.lang.String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED";
     field public static final java.lang.String BRICK = "android.permission.BRICK";
     field public static final java.lang.String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
     field public static final deprecated java.lang.String BROADCAST_NETWORK_PRIVILEGED = "android.permission.BROADCAST_NETWORK_PRIVILEGED";
-    field public static final java.lang.String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED";
     field public static final java.lang.String CAMERA_DISABLE_TRANSMIT_LED = "android.permission.CAMERA_DISABLE_TRANSMIT_LED";
     field public static final java.lang.String CAPTURE_AUDIO_HOTWORD = "android.permission.CAPTURE_AUDIO_HOTWORD";
-    field public static final java.lang.String CAPTURE_AUDIO_OUTPUT = "android.permission.CAPTURE_AUDIO_OUTPUT";
-    field public static final java.lang.String CAPTURE_SECURE_VIDEO_OUTPUT = "android.permission.CAPTURE_SECURE_VIDEO_OUTPUT";
     field public static final java.lang.String CAPTURE_TV_INPUT = "android.permission.CAPTURE_TV_INPUT";
-    field public static final java.lang.String CAPTURE_VIDEO_OUTPUT = "android.permission.CAPTURE_VIDEO_OUTPUT";
     field public static final java.lang.String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
-    field public static final java.lang.String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE";
-    field public static final java.lang.String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION";
     field public static final java.lang.String CHANGE_DEVICE_IDLE_TEMP_WHITELIST = "android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST";
     field public static final java.lang.String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
     field public static final java.lang.String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS";
@@ -59,30 +48,21 @@
     field public static final java.lang.String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
     field public static final java.lang.String CONTROL_DISPLAY_SATURATION = "android.permission.CONTROL_DISPLAY_SATURATION";
     field public static final java.lang.String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE";
-    field public static final java.lang.String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
     field public static final java.lang.String CONTROL_VPN = "android.permission.CONTROL_VPN";
     field public static final java.lang.String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER";
-    field public static final java.lang.String DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES";
-    field public static final java.lang.String DELETE_PACKAGES = "android.permission.DELETE_PACKAGES";
     field public static final java.lang.String DEVICE_POWER = "android.permission.DEVICE_POWER";
-    field public static final java.lang.String DIAGNOSTIC = "android.permission.DIAGNOSTIC";
     field public static final java.lang.String DISPATCH_PROVISIONING_MESSAGE = "android.permission.DISPATCH_PROVISIONING_MESSAGE";
-    field public static final java.lang.String DUMP = "android.permission.DUMP";
     field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK";
     field public static final java.lang.String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES";
-    field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
     field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS";
     field public static final java.lang.String GET_PROCESS_STATE_AND_OOM_SCORE = "android.permission.GET_PROCESS_STATE_AND_OOM_SCORE";
     field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
-    field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
     field public static final java.lang.String GRANT_RUNTIME_PERMISSIONS = "android.permission.GRANT_RUNTIME_PERMISSIONS";
     field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST";
     field public static final java.lang.String HDMI_CEC = "android.permission.HDMI_CEC";
     field public static final java.lang.String HIDE_NON_SYSTEM_OVERLAY_WINDOWS = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS";
     field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
     field public static final java.lang.String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS";
-    field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
-    field public static final java.lang.String INSTALL_PACKAGES = "android.permission.INSTALL_PACKAGES";
     field public static final java.lang.String INSTALL_PACKAGE_UPDATES = "android.permission.INSTALL_PACKAGE_UPDATES";
     field public static final java.lang.String INSTALL_SELF_UPDATES = "android.permission.INSTALL_SELF_UPDATES";
     field public static final java.lang.String INTENT_FILTER_VERIFICATION_AGENT = "android.permission.INTENT_FILTER_VERIFICATION_AGENT";
@@ -92,7 +72,6 @@
     field public static final java.lang.String INVOKE_CARRIER_SETUP = "android.permission.INVOKE_CARRIER_SETUP";
     field public static final java.lang.String KILL_UID = "android.permission.KILL_UID";
     field public static final java.lang.String LOCAL_MAC_ADDRESS = "android.permission.LOCAL_MAC_ADDRESS";
-    field public static final java.lang.String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE";
     field public static final java.lang.String LOOP_RADIO = "android.permission.LOOP_RADIO";
     field public static final java.lang.String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS";
     field public static final java.lang.String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS";
@@ -107,25 +86,19 @@
     field public static final java.lang.String MANAGE_USB = "android.permission.MANAGE_USB";
     field public static final java.lang.String MANAGE_USERS = "android.permission.MANAGE_USERS";
     field public static final java.lang.String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE";
-    field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
-    field public static final java.lang.String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL";
     field public static final java.lang.String MODIFY_APPWIDGET_BIND_PERMISSIONS = "android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS";
     field public static final java.lang.String MODIFY_AUDIO_ROUTING = "android.permission.MODIFY_AUDIO_ROUTING";
     field public static final java.lang.String MODIFY_CELL_BROADCASTS = "android.permission.MODIFY_CELL_BROADCASTS";
     field public static final java.lang.String MODIFY_DAY_NIGHT_MODE = "android.permission.MODIFY_DAY_NIGHT_MODE";
     field public static final deprecated java.lang.String MODIFY_NETWORK_ACCOUNTING = "android.permission.MODIFY_NETWORK_ACCOUNTING";
     field public static final java.lang.String MODIFY_PARENTAL_CONTROLS = "android.permission.MODIFY_PARENTAL_CONTROLS";
-    field public static final java.lang.String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE";
     field public static final java.lang.String MODIFY_QUIET_MODE = "android.permission.MODIFY_QUIET_MODE";
-    field public static final java.lang.String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";
-    field public static final java.lang.String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
     field public static final java.lang.String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE";
     field public static final java.lang.String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
     field public static final java.lang.String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final java.lang.String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final java.lang.String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
     field public static final java.lang.String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG";
-    field public static final java.lang.String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
     field public static final java.lang.String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT";
     field public static final java.lang.String PEERS_MAC_ADDRESS = "android.permission.PEERS_MAC_ADDRESS";
     field public static final java.lang.String PERFORM_CDMA_PROVISIONING = "android.permission.PERFORM_CDMA_PROVISIONING";
@@ -135,9 +108,7 @@
     field public static final java.lang.String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES";
     field public static final java.lang.String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS";
     field public static final java.lang.String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE";
-    field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER";
     field public static final java.lang.String READ_INSTALL_SESSIONS = "android.permission.READ_INSTALL_SESSIONS";
-    field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS";
     field public static final java.lang.String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY";
     field public static final java.lang.String READ_OEM_UNLOCK_STATE = "android.permission.READ_OEM_UNLOCK_STATE";
     field public static final java.lang.String READ_PRINT_SERVICES = "android.permission.READ_PRINT_SERVICES";
@@ -149,7 +120,6 @@
     field public static final java.lang.String READ_WALLPAPER_INTERNAL = "android.permission.READ_WALLPAPER_INTERNAL";
     field public static final java.lang.String READ_WIFI_CREDENTIAL = "android.permission.READ_WIFI_CREDENTIAL";
     field public static final java.lang.String REAL_GET_TASKS = "android.permission.REAL_GET_TASKS";
-    field public static final java.lang.String REBOOT = "android.permission.REBOOT";
     field public static final java.lang.String RECEIVE_DATA_ACTIVITY_CHANGE = "android.permission.RECEIVE_DATA_ACTIVITY_CHANGE";
     field public static final java.lang.String RECEIVE_EMERGENCY_BROADCAST = "android.permission.RECEIVE_EMERGENCY_BROADCAST";
     field public static final java.lang.String RECEIVE_WIFI_CREDENTIAL_CHANGE = "android.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE";
@@ -163,27 +133,19 @@
     field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
     field public static final java.lang.String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
     field public static final java.lang.String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
-    field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
     field public static final java.lang.String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS";
     field public static final java.lang.String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION";
     field public static final java.lang.String SERIAL_PORT = "android.permission.SERIAL_PORT";
     field public static final java.lang.String SET_ACTIVITY_WATCHER = "android.permission.SET_ACTIVITY_WATCHER";
-    field public static final java.lang.String SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH";
-    field public static final java.lang.String SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE";
-    field public static final java.lang.String SET_DEBUG_APP = "android.permission.SET_DEBUG_APP";
     field public static final java.lang.String SET_HARMFUL_APP_WARNINGS = "android.permission.SET_HARMFUL_APP_WARNINGS";
     field public static final java.lang.String SET_MEDIA_KEY_LISTENER = "android.permission.SET_MEDIA_KEY_LISTENER";
     field public static final java.lang.String SET_ORIENTATION = "android.permission.SET_ORIENTATION";
     field public static final java.lang.String SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED";
-    field public static final java.lang.String SET_PROCESS_LIMIT = "android.permission.SET_PROCESS_LIMIT";
     field public static final java.lang.String SET_SCREEN_COMPATIBILITY = "android.permission.SET_SCREEN_COMPATIBILITY";
-    field public static final java.lang.String SET_TIME = "android.permission.SET_TIME";
     field public static final java.lang.String SET_VOLUME_KEY_LONG_PRESS_LISTENER = "android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER";
     field public static final java.lang.String SET_WALLPAPER_COMPONENT = "android.permission.SET_WALLPAPER_COMPONENT";
     field public static final java.lang.String SHOW_KEYGUARD_MESSAGE = "android.permission.SHOW_KEYGUARD_MESSAGE";
     field public static final java.lang.String SHUTDOWN = "android.permission.SHUTDOWN";
-    field public static final java.lang.String SIGNAL_PERSISTENT_PROCESSES = "android.permission.SIGNAL_PERSISTENT_PROCESSES";
-    field public static final java.lang.String STATUS_BAR = "android.permission.STATUS_BAR";
     field public static final java.lang.String STOP_APP_SWITCHES = "android.permission.STOP_APP_SWITCHES";
     field public static final java.lang.String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME";
     field public static final java.lang.String SUSPEND_APPS = "android.permission.SUSPEND_APPS";
@@ -192,17 +154,13 @@
     field public static final java.lang.String TV_VIRTUAL_REMOTE_CONTROLLER = "android.permission.TV_VIRTUAL_REMOTE_CONTROLLER";
     field public static final java.lang.String UNLIMITED_SHORTCUTS_API_CALLS = "android.permission.UNLIMITED_SHORTCUTS_API_CALLS";
     field public static final java.lang.String UPDATE_APP_OPS_STATS = "android.permission.UPDATE_APP_OPS_STATS";
-    field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
     field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK";
     field public static final java.lang.String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES";
     field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY";
     field public static final java.lang.String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK";
-    field public static final java.lang.String WRITE_APN_SETTINGS = "android.permission.WRITE_APN_SETTINGS";
     field public static final java.lang.String WRITE_DREAM_STATE = "android.permission.WRITE_DREAM_STATE";
     field public static final java.lang.String WRITE_EMBEDDED_SUBSCRIPTIONS = "android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS";
-    field public static final java.lang.String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";
     field public static final java.lang.String WRITE_MEDIA_STORAGE = "android.permission.WRITE_MEDIA_STORAGE";
-    field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
   }
 
   public static final class R.array {
@@ -425,10 +383,6 @@
 
 package android.app.admin {
 
-  public class DeviceAdminReceiver extends android.content.BroadcastReceiver {
-    method public deprecated void onReadyForUserInitialization(android.content.Context, android.content.Intent);
-  }
-
   public class DevicePolicyManager {
     method public java.lang.String getDeviceOwner();
     method public android.content.ComponentName getDeviceOwnerComponentOnAnyUser();
@@ -466,10 +420,7 @@
   }
 
   public final class SystemUpdatePolicy implements android.os.Parcelable {
-    method public int describeContents();
     method public android.app.admin.SystemUpdatePolicy.InstallationOption getInstallationOptionAt(long);
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdatePolicy> CREATOR;
     field public static final int TYPE_PAUSE = 4; // 0x4
   }
 
@@ -2948,7 +2899,6 @@
     method public void addBlockedRating(android.media.tv.TvContentRating);
     method public boolean captureFrame(java.lang.String, android.view.Surface, android.media.tv.TvStreamConfig);
     method public java.util.List<android.media.tv.TvStreamConfig> getAvailableTvStreamConfigList(java.lang.String);
-    method public java.util.List<android.media.tv.TvContentRating> getBlockedRatings();
     method public java.util.List<android.media.tv.TvInputHardwareInfo> getHardwareList();
     method public java.util.List<android.media.tv.TvContentRatingSystemInfo> getTvContentRatingSystemList();
     method public boolean isSingleSessionActive();
@@ -3095,7 +3045,20 @@
     ctor public LinkAddress(java.lang.String);
   }
 
+  public final class LinkProperties implements android.os.Parcelable {
+    ctor public LinkProperties();
+    method public boolean addRoute(android.net.RouteInfo);
+    method public void clear();
+    method public void setDnsServers(java.util.Collection<java.net.InetAddress>);
+    method public void setDomains(java.lang.String);
+    method public void setHttpProxy(android.net.ProxyInfo);
+    method public void setInterfaceName(java.lang.String);
+    method public void setLinkAddresses(java.util.Collection<android.net.LinkAddress>);
+    method public void setMtu(int);
+  }
+
   public final class NetworkCapabilities implements android.os.Parcelable {
+    method public int getSignalStrength();
     field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
   }
 
@@ -3115,6 +3078,10 @@
     method public abstract void onRequestScores(android.net.NetworkKey[]);
   }
 
+  public static class NetworkRequest.Builder {
+    method public android.net.NetworkRequest.Builder setSignalStrength(int);
+  }
+
   public class NetworkScoreManager {
     method public boolean clearScores() throws java.lang.SecurityException;
     method public void disableScoring() throws java.lang.SecurityException;
@@ -3163,11 +3130,9 @@
   }
 
   public class TrafficStats {
-    method public static void clearThreadStatsUid();
     method public static void setThreadStatsTagApp();
     method public static void setThreadStatsTagBackup();
     method public static void setThreadStatsTagRestore();
-    method public static void setThreadStatsUid(int);
   }
 
   public class VpnService extends android.app.Service {
@@ -3189,14 +3154,6 @@
 
 }
 
-package android.net.http {
-
-  public class X509TrustManagerExtensions {
-    method public boolean isSameTrustConfiguration(java.lang.String, java.lang.String);
-  }
-
-}
-
 package android.net.wifi {
 
   public deprecated class RttManager {
@@ -3415,7 +3372,6 @@
     method public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks();
     method public android.net.wifi.WifiConfiguration getWifiApConfiguration();
     method public int getWifiApState();
-    method public boolean isDeviceToApRttSupported();
     method public boolean isDeviceToDeviceRttSupported();
     method public boolean isPortableHotspotSupported();
     method public boolean isWifiApEnabled();
@@ -4614,28 +4570,6 @@
     field public static final java.lang.String KEY_USER_SENTIMENT = "key_user_sentiment";
   }
 
-  public final class Condition implements android.os.Parcelable {
-    ctor public Condition(android.net.Uri, java.lang.String, java.lang.String, java.lang.String, int, int, int);
-    method public android.service.notification.Condition copy();
-    method public static boolean isValidId(android.net.Uri, java.lang.String);
-    method public static android.net.Uri.Builder newId(android.content.Context);
-    method public static java.lang.String relevanceToString(int);
-    method public static java.lang.String stateToString(int);
-    field public static final int FLAG_RELEVANT_ALWAYS = 2; // 0x2
-    field public static final int FLAG_RELEVANT_NOW = 1; // 0x1
-    field public static final java.lang.String SCHEME = "condition";
-    field public static final int STATE_ERROR = 3; // 0x3
-    field public static final int STATE_UNKNOWN = 2; // 0x2
-    field public final int flags;
-    field public final int icon;
-    field public final java.lang.String line1;
-    field public final java.lang.String line2;
-  }
-
-  public abstract class ConditionProviderService extends android.app.Service {
-    method public void onRequestConditions(int);
-  }
-
   public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
     ctor public NotificationAssistantService();
     method public final void adjustNotification(android.service.notification.Adjustment);
@@ -5022,6 +4956,18 @@
     field public static final int CAPABILITY_MULTI_USER = 32; // 0x20
   }
 
+  public final class PhoneAccountSuggestion implements android.os.Parcelable {
+    ctor public PhoneAccountSuggestion(android.telecom.PhoneAccountHandle, int, boolean);
+  }
+
+  public class PhoneAccountSuggestionService extends android.app.Service {
+    ctor public PhoneAccountSuggestionService();
+    method public void onAccountSuggestionRequest(java.lang.String);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public final void suggestPhoneAccounts(java.lang.String, java.util.List<android.telecom.PhoneAccountSuggestion>);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.PhoneAccountSuggestionService";
+  }
+
   public final class RemoteConference {
     method public deprecated void setAudioState(android.telecom.AudioState);
   }
@@ -5078,7 +5024,6 @@
     method public void clearPhoneAccounts();
     method public android.telecom.TelecomAnalytics dumpAnalytics();
     method public void enablePhoneAccount(android.telecom.PhoneAccountHandle, boolean);
-    method public boolean endCall();
     method public java.util.List<android.telecom.PhoneAccountHandle> getAllPhoneAccountHandles();
     method public java.util.List<android.telecom.PhoneAccount> getAllPhoneAccounts();
     method public int getAllPhoneAccountsCount();
@@ -5090,7 +5035,6 @@
     method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String);
     method public boolean isInEmergencyCall();
     method public boolean isRinging();
-    method public boolean isTtySupported();
     method public boolean setDefaultDialer(java.lang.String);
     field public static final java.lang.String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT";
     field public static final java.lang.String EXTRA_CLEAR_MISSED_CALLS_INTENT = "android.telecom.extra.CLEAR_MISSED_CALLS_INTENT";
@@ -5115,7 +5059,83 @@
     method public void overrideConfig(int, android.os.PersistableBundle);
     method public void updateConfigForPhoneId(int, java.lang.String);
     field public static final java.lang.String KEY_CARRIER_SETUP_APP_STRING = "carrier_setup_app_string";
-    field public static final java.lang.String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string";
+  }
+
+  public class DisconnectCause {
+    field public static final int ALREADY_DIALING = 72; // 0x48
+    field public static final int ANSWERED_ELSEWHERE = 52; // 0x34
+    field public static final int BUSY = 4; // 0x4
+    field public static final int CALLING_DISABLED = 74; // 0x4a
+    field public static final int CALL_BARRED = 20; // 0x14
+    field public static final int CALL_PULLED = 51; // 0x33
+    field public static final int CANT_CALL_WHILE_RINGING = 73; // 0x49
+    field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23
+    field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20
+    field public static final int CDMA_ALREADY_ACTIVATED = 49; // 0x31
+    field public static final int CDMA_DROP = 27; // 0x1b
+    field public static final int CDMA_INTERCEPT = 28; // 0x1c
+    field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a
+    field public static final int CDMA_NOT_EMERGENCY = 34; // 0x22
+    field public static final int CDMA_PREEMPTED = 33; // 0x21
+    field public static final int CDMA_REORDER = 29; // 0x1d
+    field public static final int CDMA_RETRY_ORDER = 31; // 0x1f
+    field public static final int CDMA_SO_REJECT = 30; // 0x1e
+    field public static final int CONGESTION = 5; // 0x5
+    field public static final int CS_RESTRICTED = 22; // 0x16
+    field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18
+    field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17
+    field public static final int DATA_DISABLED = 54; // 0x36
+    field public static final int DATA_LIMIT_REACHED = 55; // 0x37
+    field public static final int DIALED_CALL_FORWARDING_WHILE_ROAMING = 57; // 0x39
+    field public static final int DIALED_MMI = 39; // 0x27
+    field public static final int DIAL_LOW_BATTERY = 62; // 0x3e
+    field public static final int DIAL_MODIFIED_TO_DIAL = 48; // 0x30
+    field public static final int DIAL_MODIFIED_TO_DIAL_VIDEO = 66; // 0x42
+    field public static final int DIAL_MODIFIED_TO_SS = 47; // 0x2f
+    field public static final int DIAL_MODIFIED_TO_USSD = 46; // 0x2e
+    field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL = 69; // 0x45
+    field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 70; // 0x46
+    field public static final int DIAL_VIDEO_MODIFIED_TO_SS = 67; // 0x43
+    field public static final int DIAL_VIDEO_MODIFIED_TO_USSD = 68; // 0x44
+    field public static final int EMERGENCY_PERM_FAILURE = 64; // 0x40
+    field public static final int EMERGENCY_TEMP_FAILURE = 63; // 0x3f
+    field public static final int ERROR_UNSPECIFIED = 36; // 0x24
+    field public static final int FDN_BLOCKED = 21; // 0x15
+    field public static final int ICC_ERROR = 19; // 0x13
+    field public static final int IMEI_NOT_ACCEPTED = 58; // 0x3a
+    field public static final int IMS_ACCESS_BLOCKED = 60; // 0x3c
+    field public static final int IMS_MERGED_SUCCESSFULLY = 45; // 0x2d
+    field public static final int IMS_SIP_ALTERNATE_EMERGENCY_CALL = 71; // 0x47
+    field public static final int INCOMING_MISSED = 1; // 0x1
+    field public static final int INCOMING_REJECTED = 16; // 0x10
+    field public static final int INVALID_CREDENTIALS = 10; // 0xa
+    field public static final int INVALID_NUMBER = 7; // 0x7
+    field public static final int LIMIT_EXCEEDED = 15; // 0xf
+    field public static final int LOCAL = 3; // 0x3
+    field public static final int LOST_SIGNAL = 14; // 0xe
+    field public static final int LOW_BATTERY = 61; // 0x3d
+    field public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53; // 0x35
+    field public static final int MMI = 6; // 0x6
+    field public static final int NORMAL = 2; // 0x2
+    field public static final int NORMAL_UNSPECIFIED = 65; // 0x41
+    field public static final int NOT_DISCONNECTED = 0; // 0x0
+    field public static final int NOT_VALID = -1; // 0xffffffff
+    field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26
+    field public static final int NUMBER_UNREACHABLE = 8; // 0x8
+    field public static final int OTASP_PROVISIONING_IN_PROCESS = 76; // 0x4c
+    field public static final int OUTGOING_CANCELED = 44; // 0x2c
+    field public static final int OUTGOING_FAILURE = 43; // 0x2b
+    field public static final int OUT_OF_NETWORK = 11; // 0xb
+    field public static final int OUT_OF_SERVICE = 18; // 0x12
+    field public static final int POWER_OFF = 17; // 0x11
+    field public static final int SERVER_ERROR = 12; // 0xc
+    field public static final int SERVER_UNREACHABLE = 9; // 0x9
+    field public static final int TIMED_OUT = 13; // 0xd
+    field public static final int TOO_MANY_ONGOING_CALLS = 75; // 0x4b
+    field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
+    field public static final int VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED = 50; // 0x32
+    field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
+    field public static final int WIFI_LOST = 59; // 0x3b
   }
 
   public class MbmsDownloadSession implements java.lang.AutoCloseable {
@@ -5164,16 +5184,15 @@
   public abstract class NetworkService extends android.app.Service {
     ctor public NetworkService();
     method protected abstract android.telephony.NetworkService.NetworkServiceProvider createNetworkServiceProvider(int);
-    field public static final java.lang.String NETWORK_SERVICE_EXTRA_SLOT_ID = "android.telephony.extra.SLOT_ID";
     field public static final java.lang.String NETWORK_SERVICE_INTERFACE = "android.telephony.NetworkService";
   }
 
-  public class NetworkService.NetworkServiceProvider {
+  public abstract class NetworkService.NetworkServiceProvider implements java.lang.AutoCloseable {
     ctor public NetworkService.NetworkServiceProvider(int);
+    method public abstract void close();
     method public void getNetworkRegistrationState(int, android.telephony.NetworkServiceCallback);
     method public final int getSlotId();
     method public final void notifyNetworkRegistrationStateChanged();
-    method protected void onDestroy();
   }
 
   public class NetworkServiceCallback {
@@ -5207,14 +5226,134 @@
   }
 
   public class PhoneStateListener {
+    method public void onCallDisconnectCauseChanged(int, int);
+    method public void onPreciseCallStateChanged(android.telephony.PreciseCallState);
     method public void onRadioPowerStateChanged(int);
     method public void onSrvccStateChanged(int);
     method public void onVoiceActivationStateChanged(int);
+    field public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000
+    field public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
     field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
     field public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
     field public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
   }
 
+  public final class PreciseCallState implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getBackgroundCallState();
+    method public int getForegroundCallState();
+    method public int getRingingCallState();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.PreciseCallState> CREATOR;
+    field public static final int PRECISE_CALL_STATE_ACTIVE = 1; // 0x1
+    field public static final int PRECISE_CALL_STATE_ALERTING = 4; // 0x4
+    field public static final int PRECISE_CALL_STATE_DIALING = 3; // 0x3
+    field public static final int PRECISE_CALL_STATE_DISCONNECTED = 7; // 0x7
+    field public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; // 0x8
+    field public static final int PRECISE_CALL_STATE_HOLDING = 2; // 0x2
+    field public static final int PRECISE_CALL_STATE_IDLE = 0; // 0x0
+    field public static final int PRECISE_CALL_STATE_INCOMING = 5; // 0x5
+    field public static final int PRECISE_CALL_STATE_NOT_VALID = -1; // 0xffffffff
+    field public static final int PRECISE_CALL_STATE_WAITING = 6; // 0x6
+  }
+
+  public class PreciseDisconnectCause {
+    field public static final int ACCESS_CLASS_BLOCKED = 260; // 0x104
+    field public static final int ACCESS_INFORMATION_DISCARDED = 43; // 0x2b
+    field public static final int ACM_LIMIT_EXCEEDED = 68; // 0x44
+    field public static final int BEARER_CAPABILITY_NOT_AUTHORIZED = 57; // 0x39
+    field public static final int BEARER_NOT_AVAIL = 58; // 0x3a
+    field public static final int BEARER_SERVICE_NOT_IMPLEMENTED = 65; // 0x41
+    field public static final int BUSY = 17; // 0x11
+    field public static final int CALL_BARRED = 240; // 0xf0
+    field public static final int CALL_REJECTED = 21; // 0x15
+    field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
+    field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
+    field public static final int CDMA_DROP = 1001; // 0x3e9
+    field public static final int CDMA_INTERCEPT = 1002; // 0x3ea
+    field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
+    field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
+    field public static final int CDMA_PREEMPTED = 1007; // 0x3ef
+    field public static final int CDMA_REORDER = 1003; // 0x3eb
+    field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
+    field public static final int CDMA_SO_REJECT = 1004; // 0x3ec
+    field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c
+    field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6
+    field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64
+    field public static final int DESTINATION_OUT_OF_ORDER = 27; // 0x1b
+    field public static final int ERROR_UNSPECIFIED = 65535; // 0xffff
+    field public static final int FACILITY_REJECTED = 29; // 0x1d
+    field public static final int FDN_BLOCKED = 241; // 0xf1
+    field public static final int IMEI_NOT_ACCEPTED = 243; // 0xf3
+    field public static final int IMSI_UNKNOWN_IN_VLR = 242; // 0xf2
+    field public static final int INCOMING_CALLS_BARRED_WITHIN_CUG = 55; // 0x37
+    field public static final int INCOMPATIBLE_DESTINATION = 88; // 0x58
+    field public static final int INFORMATION_ELEMENT_NON_EXISTENT = 99; // 0x63
+    field public static final int INTERWORKING_UNSPECIFIED = 127; // 0x7f
+    field public static final int INVALID_MANDATORY_INFORMATION = 96; // 0x60
+    field public static final int INVALID_NUMBER_FORMAT = 28; // 0x1c
+    field public static final int INVALID_TRANSACTION_IDENTIFIER = 81; // 0x51
+    field public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101; // 0x65
+    field public static final int MESSAGE_TYPE_NON_IMPLEMENTED = 97; // 0x61
+    field public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98; // 0x62
+    field public static final int NETWORK_DETACH = 261; // 0x105
+    field public static final int NETWORK_OUT_OF_ORDER = 38; // 0x26
+    field public static final int NETWORK_REJECT = 252; // 0xfc
+    field public static final int NETWORK_RESP_TIMEOUT = 251; // 0xfb
+    field public static final int NORMAL = 16; // 0x10
+    field public static final int NORMAL_UNSPECIFIED = 31; // 0x1f
+    field public static final int NOT_VALID = -1; // 0xffffffff
+    field public static final int NO_ANSWER_FROM_USER = 19; // 0x13
+    field public static final int NO_CIRCUIT_AVAIL = 34; // 0x22
+    field public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0; // 0x0
+    field public static final int NO_ROUTE_TO_DESTINATION = 3; // 0x3
+    field public static final int NO_USER_RESPONDING = 18; // 0x12
+    field public static final int NO_VALID_SIM = 249; // 0xf9
+    field public static final int NUMBER_CHANGED = 22; // 0x16
+    field public static final int OEM_CAUSE_1 = 61441; // 0xf001
+    field public static final int OEM_CAUSE_10 = 61450; // 0xf00a
+    field public static final int OEM_CAUSE_11 = 61451; // 0xf00b
+    field public static final int OEM_CAUSE_12 = 61452; // 0xf00c
+    field public static final int OEM_CAUSE_13 = 61453; // 0xf00d
+    field public static final int OEM_CAUSE_14 = 61454; // 0xf00e
+    field public static final int OEM_CAUSE_15 = 61455; // 0xf00f
+    field public static final int OEM_CAUSE_2 = 61442; // 0xf002
+    field public static final int OEM_CAUSE_3 = 61443; // 0xf003
+    field public static final int OEM_CAUSE_4 = 61444; // 0xf004
+    field public static final int OEM_CAUSE_5 = 61445; // 0xf005
+    field public static final int OEM_CAUSE_6 = 61446; // 0xf006
+    field public static final int OEM_CAUSE_7 = 61447; // 0xf007
+    field public static final int OEM_CAUSE_8 = 61448; // 0xf008
+    field public static final int OEM_CAUSE_9 = 61449; // 0xf009
+    field public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70; // 0x46
+    field public static final int OPERATOR_DETERMINED_BARRING = 8; // 0x8
+    field public static final int OUT_OF_SRV = 248; // 0xf8
+    field public static final int PREEMPTION = 25; // 0x19
+    field public static final int PROTOCOL_ERROR_UNSPECIFIED = 111; // 0x6f
+    field public static final int QOS_NOT_AVAIL = 49; // 0x31
+    field public static final int RADIO_ACCESS_FAILURE = 253; // 0xfd
+    field public static final int RADIO_INTERNAL_ERROR = 250; // 0xfa
+    field public static final int RADIO_LINK_FAILURE = 254; // 0xfe
+    field public static final int RADIO_LINK_LOST = 255; // 0xff
+    field public static final int RADIO_OFF = 247; // 0xf7
+    field public static final int RADIO_RELEASE_ABNORMAL = 259; // 0x103
+    field public static final int RADIO_RELEASE_NORMAL = 258; // 0x102
+    field public static final int RADIO_SETUP_FAILURE = 257; // 0x101
+    field public static final int RADIO_UPLINK_FAILURE = 256; // 0x100
+    field public static final int RECOVERY_ON_TIMER_EXPIRED = 102; // 0x66
+    field public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED = 69; // 0x45
+    field public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED = 50; // 0x32
+    field public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47; // 0x2f
+    field public static final int SEMANTICALLY_INCORRECT_MESSAGE = 95; // 0x5f
+    field public static final int SERVICE_OPTION_NOT_AVAILABLE = 63; // 0x3f
+    field public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79; // 0x4f
+    field public static final int STATUS_ENQUIRY = 30; // 0x1e
+    field public static final int SWITCHING_CONGESTION = 42; // 0x2a
+    field public static final int TEMPORARY_FAILURE = 41; // 0x29
+    field public static final int UNOBTAINABLE_NUMBER = 1; // 0x1
+    field public static final int USER_NOT_MEMBER_OF_CUG = 87; // 0x57
+  }
+
   public class ServiceState implements android.os.Parcelable {
     method public android.telephony.NetworkRegistrationState getNetworkRegistrationState(int, int);
     method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates();
@@ -5230,7 +5369,6 @@
 
   public final class SmsManager {
     method public void sendMultipartTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
-    method public void sendTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
     field public static final int RESULT_CANCELLED = 23; // 0x17
     field public static final int RESULT_ENCODING_ERROR = 18; // 0x12
     field public static final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; // 0x6
@@ -5253,17 +5391,12 @@
 
   public class SubscriptionInfo implements android.os.Parcelable {
     method public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+    method public int getCardId();
   }
 
   public class SubscriptionManager {
     method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList();
-    method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
     method public void requestEmbeddedSubscriptionInfoListRefresh();
-    method public void setSubscriptionOverrideCongested(int, boolean, long);
-    method public void setSubscriptionOverrideUnmetered(int, boolean, long);
-    method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
-    field public static final java.lang.String ACTION_MANAGE_SUBSCRIPTION_PLANS = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
-    field public static final java.lang.String ACTION_REFRESH_SUBSCRIPTION_PLANS = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
     field public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
     field public static final android.net.Uri VT_ENABLED_CONTENT_URI;
     field public static final android.net.Uri WFC_ENABLED_CONTENT_URI;
@@ -5272,37 +5405,10 @@
     field public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI;
   }
 
-  public final class SubscriptionPlan implements android.os.Parcelable {
-    method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator();
-    method public int describeContents();
-    method public int getDataLimitBehavior();
-    method public long getDataLimitBytes();
-    method public long getDataUsageBytes();
-    method public long getDataUsageTime();
-    method public java.lang.CharSequence getSummary();
-    method public java.lang.CharSequence getTitle();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final long BYTES_UNKNOWN = -1L; // 0xffffffffffffffffL
-    field public static final long BYTES_UNLIMITED = 9223372036854775807L; // 0x7fffffffffffffffL
-    field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionPlan> CREATOR;
-    field public static final int LIMIT_BEHAVIOR_BILLED = 1; // 0x1
-    field public static final int LIMIT_BEHAVIOR_DISABLED = 0; // 0x0
-    field public static final int LIMIT_BEHAVIOR_THROTTLED = 2; // 0x2
-    field public static final int LIMIT_BEHAVIOR_UNKNOWN = -1; // 0xffffffff
-    field public static final long TIME_UNKNOWN = -1L; // 0xffffffffffffffffL
-  }
-
   public static class SubscriptionPlan.Builder {
-    method public android.telephony.SubscriptionPlan build();
-    method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
     method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
     method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
     method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
-    method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
-    method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
-    method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
-    method public android.telephony.SubscriptionPlan.Builder setTitle(java.lang.CharSequence);
   }
 
   public final class TelephonyHistogram implements android.os.Parcelable {
@@ -5335,6 +5441,7 @@
     method public void enableVideoCalling(boolean);
     method public java.lang.String getAidForAppType(int);
     method public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
+    method public int getCardIdForDefaultEuicc();
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
     method public java.lang.String getCdmaMdn();
@@ -5355,6 +5462,7 @@
     method public int getSimCardState();
     method public int getSupportedRadioAccessFamily();
     method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
+    method public android.telephony.UiccCardInfo[] getUiccCardsInfo();
     method public android.telephony.UiccSlotInfo[] getUiccSlotsInfo();
     method public android.os.Bundle getVisualVoicemailSettings();
     method public int getVoiceActivationState();
@@ -5400,6 +5508,7 @@
     field public static final java.lang.String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
     field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
     field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+    field public static final int INVALID_CARD_ID = -1; // 0xffffffff
     field public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000L; // 0xea60L
     field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4
     field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5
@@ -5471,6 +5580,18 @@
     field public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR;
   }
 
+  public class UiccCardInfo implements android.os.Parcelable {
+    ctor public UiccCardInfo(boolean, int, java.lang.String, java.lang.String, int);
+    method public int describeContents();
+    method public int getCardId();
+    method public java.lang.String getEid();
+    method public java.lang.String getIccId();
+    method public int getSlotIndex();
+    method public boolean isEuicc();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.UiccCardInfo> CREATOR;
+  }
+
   public class UiccSlotInfo implements android.os.Parcelable {
     ctor public UiccSlotInfo(boolean, boolean, java.lang.String, int, int, boolean);
     method public int describeContents();
@@ -5542,20 +5663,19 @@
   public abstract class DataService extends android.app.Service {
     ctor public DataService();
     method public abstract android.telephony.data.DataService.DataServiceProvider createDataServiceProvider(int);
-    field public static final java.lang.String DATA_SERVICE_EXTRA_SLOT_ID = "android.telephony.data.extra.SLOT_ID";
     field public static final java.lang.String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService";
     field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3
     field public static final int REQUEST_REASON_NORMAL = 1; // 0x1
     field public static final int REQUEST_REASON_SHUTDOWN = 2; // 0x2
   }
 
-  public class DataService.DataServiceProvider {
+  public abstract class DataService.DataServiceProvider implements java.lang.AutoCloseable {
     ctor public DataService.DataServiceProvider(int);
+    method public abstract void close();
     method public void deactivateDataCall(int, int, android.telephony.data.DataServiceCallback);
     method public void getDataCallList(android.telephony.data.DataServiceCallback);
     method public final int getSlotId();
     method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
-    method protected void onDestroy();
     method public void setDataProfile(java.util.List<android.telephony.data.DataProfile>, boolean, android.telephony.data.DataServiceCallback);
     method public void setInitialAttachApn(android.telephony.data.DataProfile, boolean, android.telephony.data.DataServiceCallback);
     method public void setupDataCall(int, android.telephony.data.DataProfile, boolean, boolean, int, android.net.LinkProperties, android.telephony.data.DataServiceCallback);
@@ -6020,6 +6140,7 @@
     field public static final int CODE_RADIO_SETUP_FAILURE = 1509; // 0x5e5
     field public static final int CODE_RADIO_UPLINK_FAILURE = 1508; // 0x5e4
     field public static final int CODE_REGISTRATION_ERROR = 1000; // 0x3e8
+    field public static final int CODE_REJECTED_ELSEWHERE = 1017; // 0x3f9
     field public static final int CODE_REJECT_1X_COLLISION = 1603; // 0x643
     field public static final int CODE_REJECT_CALL_ON_OTHER_SUB = 1602; // 0x642
     field public static final int CODE_REJECT_CALL_TYPE_NOT_ALLOWED = 1605; // 0x645
@@ -6043,26 +6164,39 @@
     field public static final int CODE_REJECT_VT_AVPF_NOT_ALLOWED = 1619; // 0x653
     field public static final int CODE_REJECT_VT_TTY_NOT_ALLOWED = 1615; // 0x64f
     field public static final int CODE_REMOTE_CALL_DECLINE = 1404; // 0x57c
+    field public static final int CODE_SESSION_MODIFICATION_FAILED = 1517; // 0x5ed
     field public static final int CODE_SIP_ALTERNATE_EMERGENCY_CALL = 1514; // 0x5ea
+    field public static final int CODE_SIP_AMBIGUOUS = 376; // 0x178
     field public static final int CODE_SIP_BAD_ADDRESS = 337; // 0x151
     field public static final int CODE_SIP_BAD_REQUEST = 331; // 0x14b
     field public static final int CODE_SIP_BUSY = 338; // 0x152
+    field public static final int CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST = 372; // 0x174
     field public static final int CODE_SIP_CLIENT_ERROR = 342; // 0x156
+    field public static final int CODE_SIP_EXTENSION_REQUIRED = 370; // 0x172
     field public static final int CODE_SIP_FORBIDDEN = 332; // 0x14c
     field public static final int CODE_SIP_GLOBAL_ERROR = 362; // 0x16a
+    field public static final int CODE_SIP_INTERVAL_TOO_BRIEF = 371; // 0x173
+    field public static final int CODE_SIP_LOOP_DETECTED = 373; // 0x175
+    field public static final int CODE_SIP_METHOD_NOT_ALLOWED = 366; // 0x16e
     field public static final int CODE_SIP_NOT_ACCEPTABLE = 340; // 0x154
     field public static final int CODE_SIP_NOT_FOUND = 333; // 0x14d
     field public static final int CODE_SIP_NOT_REACHABLE = 341; // 0x155
     field public static final int CODE_SIP_NOT_SUPPORTED = 334; // 0x14e
+    field public static final int CODE_SIP_PROXY_AUTHENTICATION_REQUIRED = 367; // 0x16f
     field public static final int CODE_SIP_REDIRECTED = 321; // 0x141
     field public static final int CODE_SIP_REQUEST_CANCELLED = 339; // 0x153
+    field public static final int CODE_SIP_REQUEST_ENTITY_TOO_LARGE = 368; // 0x170
+    field public static final int CODE_SIP_REQUEST_PENDING = 377; // 0x179
     field public static final int CODE_SIP_REQUEST_TIMEOUT = 335; // 0x14f
+    field public static final int CODE_SIP_REQUEST_URI_TOO_LARGE = 369; // 0x171
     field public static final int CODE_SIP_SERVER_ERROR = 354; // 0x162
     field public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; // 0x15f
     field public static final int CODE_SIP_SERVER_TIMEOUT = 353; // 0x161
     field public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; // 0x160
     field public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; // 0x150
+    field public static final int CODE_SIP_TOO_MANY_HOPS = 374; // 0x176
     field public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343; // 0x157
+    field public static final int CODE_SIP_UNDECIPHERABLE = 378; // 0x17a
     field public static final int CODE_SIP_USER_MARKED_UNWANTED = 365; // 0x16d
     field public static final int CODE_SIP_USER_REJECTED = 361; // 0x169
     field public static final int CODE_SUPP_SVC_CANCELLED = 1202; // 0x4b2
@@ -6072,9 +6206,11 @@
     field public static final int CODE_TIMEOUT_NO_ANSWER = 202; // 0xca
     field public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; // 0xcb
     field public static final int CODE_UNSPECIFIED = 0; // 0x0
+    field public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512; // 0x200
     field public static final int CODE_USER_DECLINE = 504; // 0x1f8
     field public static final int CODE_USER_IGNORE = 503; // 0x1f7
     field public static final int CODE_USER_NOANSWER = 502; // 0x1f6
+    field public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511; // 0x1ff
     field public static final int CODE_USER_TERMINATED = 501; // 0x1f5
     field public static final int CODE_USER_TERMINATED_BY_REMOTE = 510; // 0x1fe
     field public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; // 0x335
@@ -6218,12 +6354,6 @@
     method public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int);
   }
 
-  public static abstract class ImsSsInfo.ClirInterrogationStatus implements java.lang.annotation.Annotation {
-  }
-
-  public static abstract class ImsSsInfo.ClirOutgoingState implements java.lang.annotation.Annotation {
-  }
-
   public final class ImsStreamMediaProfile implements android.os.Parcelable {
     ctor public ImsStreamMediaProfile(int, int, int, int, int);
     method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile);
diff --git a/api/test-current.txt b/api/test-current.txt
index 8466ef0..dfa1c16 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -963,6 +963,18 @@
     ctor public CallAudioState(boolean, int, int, android.bluetooth.BluetoothDevice, java.util.Collection<android.bluetooth.BluetoothDevice>);
   }
 
+  public final class PhoneAccountSuggestion implements android.os.Parcelable {
+    ctor public PhoneAccountSuggestion(android.telecom.PhoneAccountHandle, int, boolean);
+  }
+
+  public class PhoneAccountSuggestionService extends android.app.Service {
+    ctor public PhoneAccountSuggestionService();
+    method public void onAccountSuggestionRequest(java.lang.String);
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public final void suggestPhoneAccounts(java.lang.String, java.util.List<android.telecom.PhoneAccountSuggestion>);
+    field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.PhoneAccountSuggestionService";
+  }
+
 }
 
 package android.telephony {
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 8ffe5bf..ed6c25d 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -302,6 +302,7 @@
     mHeight = h;
     mFlingerSurfaceControl = control;
     mFlingerSurface = s;
+    mTargetInset = -1;
 
     // If the device has encryption turned on or is in process
     // of being encrypted we show the encrypted boot animation.
@@ -942,6 +943,7 @@
                 if (mClockEnabled && mTimeIsAccurate && validClock(part)) {
                     drawClock(animation.clockFont, part.clockPosX, part.clockPosY);
                 }
+                handleViewport(frameDuration);
 
                 eglSwapBuffers(mDisplay, mSurface);
 
@@ -966,7 +968,7 @@
             usleep(part.pause * ns2us(frameDuration));
 
             // For infinite parts, we've now played them at least once, so perhaps exit
-            if(exitPending() && !part.count)
+            if(exitPending() && !part.count && mCurrentInset >= mTargetInset)
                 break;
         }
 
@@ -986,6 +988,51 @@
     return true;
 }
 
+void BootAnimation::handleViewport(nsecs_t timestep) {
+    if (mShuttingDown || !mFlingerSurfaceControl || mTargetInset == 0) {
+        return;
+    }
+    if (mTargetInset < 0) {
+        // Poll the amount for the top display inset. This will return -1 until persistent properties
+        // have been loaded.
+        mTargetInset = android::base::GetIntProperty("persist.sys.displayinset.top",
+                -1 /* default */, -1 /* min */, mHeight / 2 /* max */);
+    }
+    if (mTargetInset <= 0) {
+        return;
+    }
+
+    if (mCurrentInset < mTargetInset) {
+        // After the device boots, the inset will effectively be cropped away. We animate this here.
+        float fraction = static_cast<float>(mCurrentInset) / mTargetInset;
+        int interpolatedInset = (cosf((fraction + 1) * M_PI) / 2.0f + 0.5f) * mTargetInset;
+
+        SurfaceComposerClient::Transaction()
+                .setCrop(mFlingerSurfaceControl, Rect(0, interpolatedInset, mWidth, mHeight))
+                .apply();
+    } else {
+        // At the end of the animation, we switch to the viewport that DisplayManager will apply
+        // later. This changes the coordinate system, and means we must move the surface up by
+        // the inset amount.
+        sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay(
+                ISurfaceComposer::eDisplayIdMain));
+
+        Rect layerStackRect(0, 0, mWidth, mHeight - mTargetInset);
+        Rect displayRect(0, mTargetInset, mWidth, mHeight);
+
+        SurfaceComposerClient::Transaction t;
+        t.setPosition(mFlingerSurfaceControl, 0, -mTargetInset)
+                .setCrop(mFlingerSurfaceControl, Rect(0, mTargetInset, mWidth, mHeight));
+        t.setDisplayProjection(dtoken, 0 /* orientation */, layerStackRect, displayRect);
+        t.apply();
+
+        mTargetInset = mCurrentInset = 0;
+    }
+
+    int delta = timestep * mTargetInset / ms2ns(200);
+    mCurrentInset += delta;
+}
+
 void BootAnimation::releaseAnimation(Animation* animation) const
 {
     for (Vector<Animation::Part>::iterator it = animation->parts.begin(),
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 56e131523..b4699d8 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -157,11 +157,15 @@
 
     void checkExit();
 
+    void handleViewport(nsecs_t timestep);
+
     sp<SurfaceComposerClient>       mSession;
     AssetManager mAssets;
     Texture     mAndroid[2];
     int         mWidth;
     int         mHeight;
+    int         mCurrentInset;
+    int         mTargetInset;
     bool        mUseNpotTextures = false;
     EGLDisplay  mDisplay;
     EGLDisplay  mContext;
diff --git a/cmds/incident_helper/src/TextParserBase.h b/cmds/incident_helper/src/TextParserBase.h
index 784c181..a6074e7 100644
--- a/cmds/incident_helper/src/TextParserBase.h
+++ b/cmds/incident_helper/src/TextParserBase.h
@@ -30,7 +30,7 @@
 public:
     String8 name;
 
-    TextParserBase(String8 name) : name(name) {};
+    explicit TextParserBase(String8 name) : name(name) {};
     virtual ~TextParserBase() {};
 
     virtual status_t Parse(const int in, const int out) const = 0;
diff --git a/cmds/incident_helper/src/ih_util.h b/cmds/incident_helper/src/ih_util.h
index c02a349..09dc8e6 100644
--- a/cmds/incident_helper/src/ih_util.h
+++ b/cmds/incident_helper/src/ih_util.h
@@ -109,7 +109,7 @@
 class Reader
 {
 public:
-    Reader(const int fd);
+    explicit Reader(const int fd);
     ~Reader();
 
     bool readLine(std::string* line);
@@ -162,7 +162,7 @@
 class Message
 {
 public:
-    Message(Table* table);
+    explicit Message(Table* table);
     ~Message();
 
     // Reconstructs the typical proto message by adding its message fields.
diff --git a/cmds/incident_helper/tests/KernelWakesParser_test.cpp b/cmds/incident_helper/tests/KernelWakesParser_test.cpp
index f92d813..573ca4f 100644
--- a/cmds/incident_helper/tests/KernelWakesParser_test.cpp
+++ b/cmds/incident_helper/tests/KernelWakesParser_test.cpp
@@ -84,9 +84,9 @@
     record1->set_event_count(8);
     record1->set_wakeup_count(0);
     record1->set_expire_count(0);
-    record1->set_active_since(0l);
-    record1->set_total_time(0l);
-    record1->set_max_time(0l);
+    record1->set_active_since(0L);
+    record1->set_total_time(0L);
+    record1->set_max_time(0L);
     record1->set_last_change(131348LL);
     record1->set_prevent_suspend_time(0LL);
 
@@ -96,9 +96,9 @@
     record2->set_event_count(143);
     record2->set_wakeup_count(0);
     record2->set_expire_count(0);
-    record2->set_active_since(0l);
-    record2->set_total_time(123l);
-    record2->set_max_time(3l);
+    record2->set_active_since(0L);
+    record2->set_total_time(123L);
+    record2->set_max_time(3L);
     record2->set_last_change(2067286206LL);
     record2->set_prevent_suspend_time(0LL);
 
diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h
index e176bfd..140484b 100644
--- a/cmds/incidentd/src/IncidentService.h
+++ b/cmds/incidentd/src/IncidentService.h
@@ -97,7 +97,7 @@
 // ================================================================================
 class IncidentService : public BnIncidentManager {
 public:
-    IncidentService(const sp<Looper>& handlerLooper);
+    explicit IncidentService(const sp<Looper>& handlerLooper);
     virtual ~IncidentService();
 
     virtual Status reportIncident(const IncidentReportArgs& args);
diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h
index a3df490..a0159d9 100644
--- a/cmds/incidentd/src/Privacy.h
+++ b/cmds/incidentd/src/Privacy.h
@@ -83,7 +83,7 @@
     static PrivacySpec new_spec(int dest);
 
 private:
-    PrivacySpec(uint8_t dest) : dest(dest) {}
+    explicit PrivacySpec(uint8_t dest) : dest(dest) {}
 };
 
 }  // namespace incidentd
diff --git a/cmds/incidentd/src/Reporter.h b/cmds/incidentd/src/Reporter.h
index 45fd944..2a3abd7 100644
--- a/cmds/incidentd/src/Reporter.h
+++ b/cmds/incidentd/src/Reporter.h
@@ -89,7 +89,7 @@
     ReportRequestSet batch;
 
     Reporter();                       // PROD must use this constructor.
-    Reporter(const char* directory);  // For testing purpose only.
+    explicit Reporter(const char* directory);  // For testing purpose only.
     virtual ~Reporter();
 
     // Run the report as described in the batch and args parameters.
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 72a4103..bb5221c 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -410,7 +410,7 @@
     bool workerDone;
     status_t workerError;
 
-    WorkerThreadData(const WorkerThreadSection* section);
+    explicit WorkerThreadData(const WorkerThreadSection* section);
     virtual ~WorkerThreadData();
 };
 
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.h b/cmds/statsd/src/anomaly/AlarmMonitor.h
index 3badb1f..bca858e 100644
--- a/cmds/statsd/src/anomaly/AlarmMonitor.h
+++ b/cmds/statsd/src/anomaly/AlarmMonitor.h
@@ -42,7 +42,7 @@
  * Timestamps are in seconds since epoch in a uint32, so will fail in year 2106.
  */
 struct InternalAlarm : public RefBase {
-    InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) {
+    explicit InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) {
     }
 
     const uint32_t timestampSec;
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index a2a03b1..7dfe7d6 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -64,10 +64,22 @@
     optional StateField option = 1 [default = STATE_FIELD_UNSET];
 }
 
+// Used to generate StatsLog.write APIs.
+enum LogMode {
+    MODE_UNSET = 0;
+    // Log fields as their actual types e.g., all primary data types.
+    // Or fields that are hardcoded in stats_log_api_gen tool e.g., AttributionNode
+    MODE_AUTOMATIC = 1;
+    // Log fields in their proto binary format. These fields will not be parsed in statsd
+    MODE_BYTES = 2;
+}
+
 extend google.protobuf.FieldOptions {
     // Flags to decorate an atom that presents a state change.
     optional StateAtomFieldOption stateFieldOption = 50000;
 
     // Flags to decorate the uid fields in an atom.
     optional bool is_uid = 50001 [default = false];
+
+    optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
 }
\ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 281f900..d9fa0f1 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -26,6 +26,7 @@
 import "frameworks/base/core/proto/android/bluetooth/enums.proto";
 import "frameworks/base/core/proto/android/os/enums.proto";
 import "frameworks/base/core/proto/android/server/enums.proto";
+import "frameworks/base/core/proto/android/stats/launcher/launcher.proto";
 import "frameworks/base/core/proto/android/telecomm/enums.proto";
 import "frameworks/base/core/proto/android/telephony/enums.proto";
 import "frameworks/base/core/proto/android/view/enums.proto";
@@ -59,7 +60,8 @@
         LongPartialWakelockStateChanged long_partial_wakelock_state_changed = 11;
         MobileRadioPowerStateChanged mobile_radio_power_state_changed = 12;
         WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13;
-        // 14 - 19 are available
+        // 14 - 18 are available
+        LauncherUIChanged launcher_event = 19;
         BatterySaverModeStateChanged battery_saver_mode_state_changed = 20;
         DeviceIdleModeStateChanged device_idle_mode_state_changed = 21;
         DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22;
@@ -1166,6 +1168,14 @@
     optional State state = 1;
 }
 
+message LauncherUIChanged {
+    optional android.stats.launcher.LauncherAction action = 1;
+    optional android.stats.launcher.LauncherState src_state = 2;
+    optional android.stats.launcher.LauncherState dst_state = 3;
+    optional android.stats.launcher.LauncherExtension extension = 4 [(log_mode) = MODE_BYTES];
+    optional bool is_swipe_up_enabled = 5;
+}
+
 /**
  * Logs that a setting was updated.
  * Logged from:
diff --git a/cmds/statsd/src/condition/ConditionWizard.h b/cmds/statsd/src/condition/ConditionWizard.h
index a6f88af..2c88147 100644
--- a/cmds/statsd/src/condition/ConditionWizard.h
+++ b/cmds/statsd/src/condition/ConditionWizard.h
@@ -29,7 +29,7 @@
 class ConditionWizard : public virtual android::RefBase {
 public:
     ConditionWizard(){};  // for testing
-    ConditionWizard(std::vector<sp<ConditionTracker>>& conditionTrackers)
+    explicit ConditionWizard(std::vector<sp<ConditionTracker>>& conditionTrackers)
         : mAllConditions(conditionTrackers){};
 
     virtual ~ConditionWizard(){};
diff --git a/cmds/statsd/src/config/ConfigKey.h b/cmds/statsd/src/config/ConfigKey.h
index dc79519..4cc9393 100644
--- a/cmds/statsd/src/config/ConfigKey.h
+++ b/cmds/statsd/src/config/ConfigKey.h
@@ -33,7 +33,7 @@
 class ConfigKey {
 public:
     ConfigKey();
-    explicit ConfigKey(const ConfigKey& that);
+    ConfigKey(const ConfigKey& that);
     ConfigKey(int uid, const int64_t& id);
     ~ConfigKey();
 
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index 16b7e79..5fea90b 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -106,14 +106,14 @@
         // Add to set.
         mConfigs[key.GetUid()].insert(key);
 
-        for (sp<ConfigListener> listener : mListeners) {
+        for (const sp<ConfigListener>& listener : mListeners) {
             broadcastList.push_back(listener);
         }
     }
 
     const int64_t timestampNs = getElapsedRealtimeNs();
     // Tell everyone
-    for (sp<ConfigListener> listener : broadcastList) {
+    for (const sp<ConfigListener>& listener : broadcastList) {
         listener->OnConfigUpdated(timestampNs, key, config);
     }
 }
@@ -137,7 +137,7 @@
         if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
             // Remove from map
             uidIt->second.erase(key);
-            for (sp<ConfigListener> listener : mListeners) {
+            for (const sp<ConfigListener>& listener : mListeners) {
                 broadcastList.push_back(listener);
             }
         }
@@ -153,7 +153,7 @@
         remove_saved_configs(key);
     }
 
-    for (sp<ConfigListener> listener:broadcastList) {
+    for (const sp<ConfigListener>& listener:broadcastList) {
         listener->OnConfigRemoved(key);
     }
 }
@@ -183,7 +183,7 @@
 
         mConfigs.erase(uidIt);
 
-        for (sp<ConfigListener> listener : mListeners) {
+        for (const sp<ConfigListener>& listener : mListeners) {
             broadcastList.push_back(listener);
         }
     }
@@ -191,7 +191,7 @@
     // Remove separately so if they do anything in the callback they can't mess up our iteration.
     for (auto& key : removed) {
         // Tell everyone
-        for (sp<ConfigListener> listener:broadcastList) {
+        for (const sp<ConfigListener>& listener:broadcastList) {
             listener->OnConfigRemoved(key);
         }
     }
@@ -213,7 +213,7 @@
         }
 
         mConfigReceivers.clear();
-        for (sp<ConfigListener> listener : mListeners) {
+        for (const sp<ConfigListener>& listener : mListeners) {
             broadcastList.push_back(listener);
         }
     }
@@ -221,7 +221,7 @@
     // Remove separately so if they do anything in the callback they can't mess up our iteration.
     for (auto& key : removed) {
         // Tell everyone
-        for (sp<ConfigListener> listener:broadcastList) {
+        for (const sp<ConfigListener>& listener:broadcastList) {
             listener->OnConfigRemoved(key);
         }
     }
diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.h b/cmds/statsd/src/external/ResourceHealthManagerPuller.h
index 9b238ea..ba6e6c3 100644
--- a/cmds/statsd/src/external/ResourceHealthManagerPuller.h
+++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.h
@@ -28,7 +28,7 @@
  */
 class ResourceHealthManagerPuller : public StatsPuller {
 public:
-    ResourceHealthManagerPuller(int tagId);
+    explicit ResourceHealthManagerPuller(int tagId);
     bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
 };
 
diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.h b/cmds/statsd/src/external/StatsCompanionServicePuller.h
index 0a49732..a16baf0 100644
--- a/cmds/statsd/src/external/StatsCompanionServicePuller.h
+++ b/cmds/statsd/src/external/StatsCompanionServicePuller.h
@@ -25,7 +25,7 @@
 
 class StatsCompanionServicePuller : public StatsPuller {
 public:
-    StatsCompanionServicePuller(int tagId);
+    explicit StatsCompanionServicePuller(int tagId);
     bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
 
     void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService) override;
diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h
index caac677..35be12b 100644
--- a/cmds/statsd/src/external/StatsPuller.h
+++ b/cmds/statsd/src/external/StatsPuller.h
@@ -33,7 +33,7 @@
 
 class StatsPuller : public virtual RefBase {
 public:
-    StatsPuller(const int tagId);
+    explicit StatsPuller(const int tagId);
 
     virtual ~StatsPuller() {}
 
diff --git a/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp b/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp
index 4501b64..2713d327 100644
--- a/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp
+++ b/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp
@@ -111,7 +111,7 @@
                              (long long)state.residencyInMsecSinceBoot,
                              (long long)state.totalTransitions,
                              state.supportedOnlyInSuspend ? 1 : 0);
-                        for (auto voter : state.voters) {
+                        for (const auto& voter : state.voters) {
                             auto voterPtr = make_shared<LogEvent>(
                                 android::util::SUBSYSTEM_SLEEP_STATE,
                                 wallClockTimestampNs, elapsedTimestampNs);
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 4e4f146..5d6d02b 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -379,7 +379,7 @@
 
 string LogEvent::ToString() const {
     string result;
-    result += StringPrintf("{ %lld %lld (%d)", (long long)mLogdTimestampNs,
+    result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs,
                            (long long)mElapsedTimestampNs, mTagId);
     for (const auto& value : mValues) {
         result +=
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 24d624d..8a03ac4 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -158,7 +158,7 @@
      * Don't copy, it's slower. If we really need this we can add it but let's try to
      * avoid it.
      */
-    explicit LogEvent(const LogEvent&);
+    LogEvent(const LogEvent&);
 
     /**
      * Parses a log_msg into a LogEvent object.
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 4fac0e1..a6c7f3a 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -395,7 +395,7 @@
 // Returns the total byte size of all metrics managed by a single config source.
 size_t MetricsManager::byteSize() {
     size_t totalSize = 0;
-    for (auto metricProducer : mAllMetricProducers) {
+    for (const auto& metricProducer : mAllMetricProducers) {
         totalSize += metricProducer->byteSize();
     }
     return totalSize;
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 811a00e..a1c80b8 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -537,7 +537,7 @@
         }
         noReportMetricIds.insert(no_report_metric);
     }
-    for (auto it : allMetricProducers) {
+    for (const auto& it : allMetricProducers) {
         uidMap.addListener(it);
     }
     return true;
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
index 73ac968..88957df 100644
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ b/cmds/statsd/src/packages/UidMap.cpp
@@ -141,7 +141,7 @@
     // listener removes itself before we call it. It's then the listener's job to handle it (expect
     // the callback to be called after listener is removed, and the listener should properly
     // ignore it).
-    for (auto weakPtr : broadcastList) {
+    for (const auto& weakPtr : broadcastList) {
         auto strongPtr = weakPtr.promote();
         if (strongPtr != NULL) {
             strongPtr->onUidMapReceived(timestamp);
@@ -181,7 +181,7 @@
         StatsdStats::getInstance().setUidMapChanges(mChanges.size());
     }
 
-    for (auto weakPtr : broadcastList) {
+    for (const auto& weakPtr : broadcastList) {
         auto strongPtr = weakPtr.promote();
         if (strongPtr != NULL) {
             strongPtr->notifyAppUpgrade(timestamp, appName, uid, versionCode);
@@ -248,7 +248,7 @@
         getListenerListCopyLocked(&broadcastList);
     }
 
-    for (auto weakPtr : broadcastList) {
+    for (const auto& weakPtr : broadcastList) {
         auto strongPtr = weakPtr.promote();
         if (strongPtr != NULL) {
             strongPtr->notifyAppRemoved(timestamp, app, uid);
diff --git a/cmds/statsd/src/socket/StatsSocketListener.h b/cmds/statsd/src/socket/StatsSocketListener.h
index 73e4d33..b8185d2 100644
--- a/cmds/statsd/src/socket/StatsSocketListener.h
+++ b/cmds/statsd/src/socket/StatsSocketListener.h
@@ -35,7 +35,7 @@
 
 class StatsSocketListener : public SocketListener, public virtual android::RefBase {
 public:
-    StatsSocketListener(const sp<LogListener>& listener);
+    explicit StatsSocketListener(const sp<LogListener>& listener);
 
     virtual ~StatsSocketListener();
 
@@ -51,4 +51,4 @@
 };
 }  // namespace statsd
 }  // namespace os
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index a0ab3e4..11ce717 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -25,15 +25,16 @@
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
 
+using android::util::AtomsInfo;
 using android::util::FIELD_COUNT_REPEATED;
 using android::util::FIELD_TYPE_BOOL;
+using android::util::FIELD_TYPE_FIXED64;
 using android::util::FIELD_TYPE_FLOAT;
 using android::util::FIELD_TYPE_INT32;
 using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_UINT64;
-using android::util::FIELD_TYPE_FIXED64;
 using android::util::FIELD_TYPE_MESSAGE;
 using android::util::FIELD_TYPE_STRING;
+using android::util::FIELD_TYPE_UINT64;
 using android::util::ProtoOutputStream;
 
 namespace android {
@@ -294,8 +295,9 @@
 // }
 //
 //
-void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size_t* index,
-                                       int depth, int prefix, ProtoOutputStream* protoOutput) {
+void writeFieldValueTreeToStreamHelper(int tagId, const std::vector<FieldValue>& dims,
+                                       size_t* index, int depth, int prefix,
+                                       ProtoOutputStream* protoOutput) {
     size_t count = dims.size();
     while (*index < count) {
         const auto& dim = dims[*index];
@@ -319,9 +321,33 @@
                 case FLOAT:
                     protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value);
                     break;
-                case STRING:
-                    protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
+                case STRING: {
+                    bool isBytesField = false;
+                    // Bytes field is logged via string format in log_msg format. So here we check
+                    // if this string field is a byte field.
+                    std::map<int, std::vector<int>>::const_iterator itr;
+                    if (depth == 0 && (itr = AtomsInfo::kBytesFieldAtoms.find(tagId)) !=
+                                              AtomsInfo::kBytesFieldAtoms.end()) {
+                        const std::vector<int>& bytesFields = itr->second;
+                        for (int bytesField : bytesFields) {
+                            if (bytesField == fieldNum) {
+                                // This is a bytes field
+                                isBytesField = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (isBytesField) {
+                        if (dim.mValue.str_value.length() > 0) {
+                            protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum,
+                                               (const char*)dim.mValue.str_value.c_str(),
+                                               dim.mValue.str_value.length());
+                        }
+                    } else {
+                        protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
+                    }
                     break;
+                }
                 default:
                     break;
             }
@@ -337,7 +363,7 @@
             }
             // Directly jump to the leaf value because the repeated position field is implied
             // by the position of the sub msg in the parent field.
-            writeFieldValueTreeToStreamHelper(dims, index, valueDepth,
+            writeFieldValueTreeToStreamHelper(tagId, dims, index, valueDepth,
                                               dim.mField.getPrefix(valueDepth), protoOutput);
             if (msg_token != 0) {
                 protoOutput->end(msg_token);
@@ -354,7 +380,7 @@
     uint64_t atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | tagId);
 
     size_t index = 0;
-    writeFieldValueTreeToStreamHelper(values, &index, 0, 0, protoOutput);
+    writeFieldValueTreeToStreamHelper(tagId, values, &index, 0, 0, protoOutput);
     protoOutput->end(atomToken);
 }
 
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index 2fcde29..b29de53 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -12,9 +12,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "src/logd/LogEvent.h"
 #include <gtest/gtest.h>
 #include <log/log_event_list.h>
-#include "src/logd/LogEvent.h"
+#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
+#include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h"
 
 #ifdef __ANDROID__
 
@@ -22,6 +24,9 @@
 namespace os {
 namespace statsd {
 
+using std::string;
+using util::ProtoOutputStream;
+
 TEST(LogEventTest, TestLogParsing) {
     LogEvent event1(1, 2000);
 
@@ -159,6 +164,94 @@
 }
 
 
+TEST(LogEventTest, TestBinaryFieldAtom) {
+    Atom launcherAtom;
+    auto launcher_event = launcherAtom.mutable_launcher_event();
+    launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS);
+    launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW);
+    launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS);
+
+    auto extension = launcher_event->mutable_extension();
+
+    auto src_target = extension->add_src_target();
+    src_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE);
+    src_target->set_item(stats::launcher::LauncherTarget_Item_FOLDER_ICON);
+
+    auto dst_target = extension->add_dst_target();
+    dst_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE);
+    dst_target->set_item(stats::launcher::LauncherTarget_Item_WIDGET);
+
+    string extension_str;
+    extension->SerializeToString(&extension_str);
+
+    LogEvent event1(Atom::kLauncherEventFieldNumber, 1000);
+
+    event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS);
+    event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW);
+    event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS);
+    event1.write(extension_str);
+    event1.init();
+
+    ProtoOutputStream proto;
+    event1.ToProto(proto);
+
+    std::vector<uint8_t> outData;
+    outData.resize(proto.size());
+    size_t pos = 0;
+    auto iter = proto.data();
+    while (iter.readBuffer() != NULL) {
+        size_t toRead = iter.currentToRead();
+        std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+        pos += toRead;
+        iter.rp()->move(toRead);
+    }
+
+    std::string result_str(outData.begin(), outData.end());
+    std::string orig_str;
+    launcherAtom.SerializeToString(&orig_str);
+
+    EXPECT_EQ(orig_str, result_str);
+}
+
+TEST(LogEventTest, TestBinaryFieldAtom_empty) {
+    Atom launcherAtom;
+    auto launcher_event = launcherAtom.mutable_launcher_event();
+    launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS);
+    launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW);
+    launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS);
+
+    // empty string.
+    string extension_str;
+
+    LogEvent event1(Atom::kLauncherEventFieldNumber, 1000);
+
+    event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS);
+    event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW);
+    event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS);
+    event1.write(extension_str);
+    event1.init();
+
+    ProtoOutputStream proto;
+    event1.ToProto(proto);
+
+    std::vector<uint8_t> outData;
+    outData.resize(proto.size());
+    size_t pos = 0;
+    auto iter = proto.data();
+    while (iter.readBuffer() != NULL) {
+        size_t toRead = iter.currentToRead();
+        std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+        pos += toRead;
+        iter.rp()->move(toRead);
+    }
+
+    std::string result_str(outData.begin(), outData.end());
+    std::string orig_str;
+    launcherAtom.SerializeToString(&orig_str);
+
+    EXPECT_EQ(orig_str, result_str);
+}
+
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
index 218d52a..e125887 100644
--- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
@@ -71,12 +71,12 @@
                          const std::shared_ptr<DimToValMap>& currentBucket,
                          const std::set<const MetricDimensionKey>& trueList,
                          const std::set<const MetricDimensionKey>& falseList) {
-    for (MetricDimensionKey key : trueList) {
+    for (const MetricDimensionKey& key : trueList) {
         if (!tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
             return false;
         }
     }
-    for (MetricDimensionKey key : falseList) {
+    for (const MetricDimensionKey& key : falseList) {
         if (tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
             return false;
         }
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index f3bf6e7..4174ad7 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -46,10 +46,13 @@
     private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled";
     private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account";
     private static final String COMMAND_REGISTER_SIM_PHONE_ACCOUNT = "register-sim-phone-account";
+    private static final String COMMAND_SET_TEST_CALL_REDIRECTION_APP = "set-test-call-redirection-app";
     private static final String COMMAND_SET_TEST_CALL_SCREENING_APP = "set-test-call-screening-app";
     private static final String COMMAND_ADD_OR_REMOVE_CALL_COMPANION_APP =
             "add-or-remove-call-companion-app";
     private static final String COMMAND_SET_TEST_AUTO_MODE_APP = "set-test-auto-mode-app";
+    private static final String COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT =
+            "set-phone-acct-suggestion-component";
     private static final String COMMAND_UNREGISTER_PHONE_ACCOUNT = "unregister-phone-account";
     private static final String COMMAND_SET_DEFAULT_DIALER = "set-default-dialer";
     private static final String COMMAND_GET_DEFAULT_DIALER = "get-default-dialer";
@@ -63,35 +66,37 @@
 
     @Override
     public void onShowUsage(PrintStream out) {
-        out.println(
-                "usage: telecom [subcommand] [options]\n" +
-                "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n" +
-                "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n" +
-                "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n" +
-                "usage: telecom set-test-call-screening-app <PACKAGE>\n" +
-                "usage: telecom set-test-auto-mode-app <PACKAGE>\n" +
-                "usage: telecom add-or-remove-call-companion-app <PACKAGE> <1/0>\n" +
-                "usage: telecom register-sim-phone-account <COMPONENT> <ID> <USER_SN> <LABEL> <ADDRESS>\n" +
-                "usage: telecom unregister-phone-account <COMPONENT> <ID> <USER_SN>\n" +
-                "usage: telecom set-default-dialer <PACKAGE>\n" +
-                "usage: telecom get-default-dialer\n" +
-                "usage: telecom get-system-dialer\n" +
-                "usage: telecom wait-on-handlers\n" +
-                "\n" +
-                "telecom set-phone-account-enabled: Enables the given phone account, if it has \n" +
-                " already been registered with Telecom.\n" +
-                "\n" +
-                "telecom set-phone-account-disabled: Disables the given phone account, if it \n" +
-                " has already been registered with telecom.\n" +
-                "\n" +
-                "telecom set-default-dialer: Sets the default dialer to the given component. \n" +
-                "\n" +
-                "telecom get-default-dialer: Displays the current default dialer. \n" +
-                "\n" +
-                "telecom get-system-dialer: Displays the current system dialer. \n" +
-                "\n" +
-                "telecom wait-on-handlers: Wait until all handlers finish their work. \n"
-                );
+        out.println("usage: telecom [subcommand] [options]\n"
+                + "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n"
+                + "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n"
+                + "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n"
+                + "usage: telecom set-test-call-redirection-app <PACKAGE>\n"
+                + "usage: telecom set-test-call-screening-app <PACKAGE>\n"
+                + "usage: telecom set-test-auto-mode-app <PACKAGE>\n"
+                + "usage: telecom set-phone-acct-suggestion-component <COMPONENT>\n"
+                + "usage: telecom add-or-remove-call-companion-app <PACKAGE> <1/0>\n"
+                + "usage: telecom register-sim-phone-account <COMPONENT> <ID> <USER_SN>"
+                + " <LABEL> <ADDRESS>\n"
+                + "usage: telecom unregister-phone-account <COMPONENT> <ID> <USER_SN>\n"
+                + "usage: telecom set-default-dialer <PACKAGE>\n"
+                + "usage: telecom get-default-dialer\n"
+                + "usage: telecom get-system-dialer\n"
+                + "usage: telecom wait-on-handlers\n"
+                + "\n"
+                + "telecom set-phone-account-enabled: Enables the given phone account, if it has \n"
+                + " already been registered with Telecom.\n"
+                + "\n"
+                + "telecom set-phone-account-disabled: Disables the given phone account, if it \n"
+                + " has already been registered with telecom.\n"
+                + "\n"
+                + "telecom set-default-dialer: Sets the default dialer to the given component. \n"
+                + "\n"
+                + "telecom get-default-dialer: Displays the current default dialer. \n"
+                + "\n"
+                + "telecom get-system-dialer: Displays the current system dialer. \n"
+                + "\n"
+                + "telecom wait-on-handlers: Wait until all handlers finish their work. \n"
+        );
     }
 
     @Override
@@ -120,6 +125,9 @@
             case COMMAND_REGISTER_PHONE_ACCOUNT:
                 runRegisterPhoneAccount();
                 break;
+            case COMMAND_SET_TEST_CALL_REDIRECTION_APP:
+                runSetTestCallRedirectionApp();
+                break;
             case COMMAND_SET_TEST_CALL_SCREENING_APP:
                 runSetTestCallScreeningApp();
                 break;
@@ -129,6 +137,9 @@
             case COMMAND_SET_TEST_AUTO_MODE_APP:
                 runSetTestAutoModeApp();
                 break;
+            case COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT:
+                runSetTestPhoneAcctSuggestionComponent();
+                break;
             case COMMAND_REGISTER_SIM_PHONE_ACCOUNT:
                 runRegisterSimPhoneAccount();
                 break;
@@ -189,6 +200,11 @@
         System.out.println("Success - " + handle + " registered.");
     }
 
+    private void runSetTestCallRedirectionApp() throws RemoteException {
+        final String packageName = nextArg();
+        mTelecomService.setTestDefaultCallRedirectionApp(packageName);
+    }
+
     private void runSetTestCallScreeningApp() throws RemoteException {
         final String packageName = nextArg();
         mTelecomService.setTestDefaultCallScreeningApp(packageName);
@@ -206,6 +222,11 @@
         mTelecomService.setTestAutoModeApp(packageName);
     }
 
+    private void runSetTestPhoneAcctSuggestionComponent() throws RemoteException {
+        final String componentName = nextArg();
+        mTelecomService.setTestPhoneAcctSuggestionComponent(componentName);
+    }
+
     private void runUnregisterPhoneAccount() throws RemoteException {
         final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
         mTelecomService.unregisterPhoneAccount(handle);
diff --git a/config/dirty-image-objects b/config/dirty-image-objects
index 9b4d199..9e2230b 100644
--- a/config/dirty-image-objects
+++ b/config/dirty-image-objects
@@ -44,7 +44,6 @@
 sun.misc.FormattedFloatingDecimal
 java.util.stream.IntStream
 android.icu.util.TimeZone
-libcore.io.DropBox
 org.apache.harmony.luni.internal.util.TimezoneGetter
 dalvik.system.SocketTagger
 dalvik.system.CloseGuard
@@ -137,7 +136,6 @@
 android.icu.util.ULocale
 dalvik.system.BaseDexClassLoader
 android.icu.text.BreakIterator
-libcore.io.EventLogger
 libcore.net.NetworkSecurityPolicy
 android.icu.text.UnicodeSet
 com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 1488b09..648ff27 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -1716,10 +1716,6 @@
 Landroid/widget/RelativeLayout$DependencyGraph$Node;-><init>()V
 Landroid/widget/RemoteViews$OnClickHandler;-><init>()V
 Landroid/widget/ScrollBarDrawable;-><init>()V
-Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;->values()[Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;
-Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;->values()[Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;
-Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;->values()[Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;
-Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->values()[Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
 Lcom/android/ims/ImsCall;->deflect(Ljava/lang/String;)V
 Lcom/android/ims/ImsCall;->isMultiparty()Z
 Lcom/android/ims/ImsCall;->reject(I)V
@@ -2942,7 +2938,6 @@
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mActiveState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcActiveState;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mConnectionParams:Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mDataRegState:I
-Lcom/android/internal/telephony/dataconnection/DataConnection;->mDcFailCause:Lcom/android/internal/telephony/dataconnection/DcFailCause;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingErrorCreatingConnection:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectionErrorCreatingConnection;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectingState;
@@ -2953,10 +2948,8 @@
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mNetworkInfo:Landroid/net/NetworkInfo;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mPhone:Lcom/android/internal/telephony/Phone;
 Lcom/android/internal/telephony/dataconnection/DataConnection;->mRilRat:I
-Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DcFailCause;)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfConnected(Ljava/lang/String;)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfDisconnectDcRetrying(Ljava/lang/String;)V
-Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyConnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;Lcom/android/internal/telephony/dataconnection/DcFailCause;Z)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$DisconnectParams;Z)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->onConnect(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;)V
 Lcom/android/internal/telephony/dataconnection/DataConnection;->tearDownData(Ljava/lang/Object;)V
@@ -2965,22 +2958,6 @@
 Lcom/android/internal/telephony/dataconnection/DcController;->mDcListActiveByCid:Ljava/util/HashMap;
 Lcom/android/internal/telephony/dataconnection/DcController;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
 Lcom/android/internal/telephony/dataconnection/DcController;->mDcTesterDeactivateAll:Lcom/android/internal/telephony/dataconnection/DcTesterDeactivateAll;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_GGSN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_UNSPECIFIED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->APN_TYPE_CONFLICT:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->INSUFFICIENT_RESOURCES:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->MISSING_UNKNOWN_APN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->NSAPI_IN_USE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV4_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV6_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_SINGLE_BEARER_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->OPERATOR_BARRED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->PROTOCOL_ERRORS:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUBSCRIBED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUPPORTED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_OUT_OF_ORDER:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->UNKNOWN_PDP_ADDRESS_TYPE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->USER_AUTHENTICATION:Lcom/android/internal/telephony/dataconnection/DcFailCause;
 Lcom/android/internal/telephony/dataconnection/DcTracker$RecoveryAction;->isAggressiveRecovery(I)Z
 Lcom/android/internal/telephony/dataconnection/DcTracker;->cancelReconnectAlarm(Lcom/android/internal/telephony/dataconnection/ApnContext;)V
 Lcom/android/internal/telephony/dataconnection/DcTracker;->cleanUpAllConnections(Ljava/lang/String;)V
@@ -3015,7 +2992,6 @@
 Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentDataStallAlarm(Landroid/content/Intent;)V
 Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentProvisioningApnAlarm(Landroid/content/Intent;)V
 Lcom/android/internal/telephony/dataconnection/DcTracker;->onRecordsLoadedOrSubIdChanged()V
-Lcom/android/internal/telephony/dataconnection/DcTracker;->onSetUserDataEnabled(Z)V
 Lcom/android/internal/telephony/dataconnection/DcTracker;->onTrySetupData(Lcom/android/internal/telephony/dataconnection/ApnContext;)Z
 Lcom/android/internal/telephony/dataconnection/DcTracker;->onTrySetupData(Ljava/lang/String;)Z
 Lcom/android/internal/telephony/dataconnection/DcTracker;->registerSettingsObserver()V
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 495615b..fafcc6b 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -6124,12 +6124,6 @@
 libcore.io.ClassPathURLStreamHandler
 libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection
 libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection$1
-libcore.io.DropBox
-libcore.io.DropBox$DefaultReporter
-libcore.io.DropBox$Reporter
-libcore.io.EventLogger
-libcore.io.EventLogger$DefaultReporter
-libcore.io.EventLogger$Reporter
 libcore.io.ForwardingOs
 libcore.io.IoBridge
 libcore.io.IoTracker
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index be2e2fa..f0a0e88 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -30,7 +30,6 @@
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.hardware.fingerprint.FingerprintManager;
-import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
@@ -190,12 +189,10 @@
      * content and also the accessibility service will receive accessibility events from
      * them.
      * <p>
-     * <strong>Note:</strong> For accessibility services targeting API version
-     * {@link Build.VERSION_CODES#JELLY_BEAN} or higher this flag has to be explicitly
-     * set for the system to regard views that are not important for accessibility. For
-     * accessibility services targeting API version lower than
-     * {@link Build.VERSION_CODES#JELLY_BEAN} this flag is ignored and all views are
-     * regarded for accessibility purposes.
+     * <strong>Note:</strong> For accessibility services targeting Android 4.1 (API level 16) or
+     * higher, this flag has to be explicitly set for the system to regard views that are not
+     * important for accessibility. For accessibility services targeting Android 4.0.4 (API level
+     * 15) or lower, this flag is ignored and all views are regarded for accessibility purposes.
      * </p>
      * <p>
      * Usually views not important for accessibility are layout managers that do not
@@ -220,19 +217,19 @@
      * flag does not guarantee that the device will not be in touch exploration
      * mode since there may be another enabled service that requested it.
      * <p>
-     * For accessibility services targeting API version higher than
-     * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set
-     * this flag have to declare this capability in their meta-data by setting
-     * the attribute {@link android.R.attr#canRequestTouchExplorationMode
-     * canRequestTouchExplorationMode} to true, otherwise this flag will
+     * For accessibility services targeting Android 4.3 (API level 18) or higher
+     * that want to set this flag have to declare this capability in their
+     * meta-data by setting the attribute
+     * {@link android.R.attr#canRequestTouchExplorationMode
+     * canRequestTouchExplorationMode} to true. Otherwise, this flag will
      * be ignored. For how to declare the meta-data of a service refer to
      * {@value AccessibilityService#SERVICE_META_DATA}.
      * </p>
      * <p>
-     * Services targeting API version equal to or lower than
-     * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} will work normally, i.e.
-     * the first time they are run, if this flag is specified, a dialog is
-     * shown to the user to confirm enabling explore by touch.
+     * Services targeting Android 4.2.2 (API level 17) or lower will work
+     * normally. In other words, the first time they are run, if this flag is
+     * specified, a dialog is shown to the user to confirm enabling explore by
+     * touch.
      * </p>
      * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode
      */
@@ -388,10 +385,10 @@
     public int feedbackType;
 
     /**
-     * The timeout after the most recent event of a given type before an
+     * The timeout, in milliseconds, after the most recent event of a given type before an
      * {@link AccessibilityService} is notified.
      * <p>
-     *   <strong>Can be dynamically set at runtime.</strong>.
+     *   <strong>Can be dynamically set at runtime.</strong>
      * </p>
      * <p>
      * <strong>Note:</strong> The event notification timeout is useful to avoid propagating
diff --git a/core/java/android/annotation/UnsupportedAppUsage.java b/core/java/android/annotation/UnsupportedAppUsage.java
index 65e3f25..ac3daaf 100644
--- a/core/java/android/annotation/UnsupportedAppUsage.java
+++ b/core/java/android/annotation/UnsupportedAppUsage.java
@@ -26,16 +26,32 @@
 import java.lang.annotation.Target;
 
 /**
- * Indicates that a class member, that is not part of the SDK, is used by apps.
- * Since the member is not part of the SDK, such use is not supported.
+ * Indicates that this non-SDK interface is used by apps. A non-SDK interface is a
+ * class member (field or method) that is not part of the public SDK. Since the
+ * member is not part of the SDK, usage by apps is not supported.
  *
- * <p>This annotation acts as a heads up that changing a given method or field
+ * <h2>If you are an Android App developer</h2>
+ *
+ * This annotation indicates that you may be able to access the member, but that
+ * this access is discouraged and not supported by Android. If there is a value
+ * for {@link #maxTargetSdk()} on the annotation, access will be restricted based
+ * on the {@code targetSdkVersion} value set in your manifest.
+ *
+ * <p>Fields and methods annotated with this are likely to be restricted, changed
+ * or removed in future Android releases. If you rely on these members for
+ * functionality that is not otherwise supported by Android, consider filing a
+ * <a href="http://g.co/dev/appcompat">feature request</a>.
+ *
+ * <h2>If you are an Android OS developer</h2>
+ *
+ * This annotation acts as a heads up that changing a given method or field
  * may affect apps, potentially breaking them when the next Android version is
  * released. In some cases, for members that are heavily used, this annotation
  * may imply restrictions on changes to the member.
  *
  * <p>This annotation also results in access to the member being permitted by the
- * runtime, with a warning being generated in debug builds.
+ * runtime, with a warning being generated in debug builds. Which apps can access
+ * the member is determined by the value of {@link #maxTargetSdk()}.
  *
  * <p>For more details, see go/UnsupportedAppUsage.
  *
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 31b5e0a..a6f9bca 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6375,6 +6375,10 @@
     }
 
     void dumpInner(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
+        if (args != null && args.length > 0 && args[0].equals("--autofill")) {
+            dumpAutofillManager(prefix, writer);
+            return;
+        }
         writer.print(prefix); writer.print("Local Activity ");
                 writer.print(Integer.toHexString(System.identityHashCode(this)));
                 writer.println(" State:");
@@ -6402,16 +6406,20 @@
 
         mHandler.getLooper().dump(new PrintWriterPrinter(writer), prefix);
 
+        dumpAutofillManager(prefix, writer);
+
+        ResourcesManager.getInstance().dump(prefix, writer);
+    }
+
+    void dumpAutofillManager(String prefix, PrintWriter writer) {
         final AutofillManager afm = getAutofillManager();
         if (afm != null) {
+            afm.dump(prefix, writer);
             writer.print(prefix); writer.print("Autofill Compat Mode: ");
             writer.println(isAutofillCompatibilityEnabled());
-            afm.dump(prefix, writer);
         } else {
             writer.print(prefix); writer.println("No AutofillManager");
         }
-
-        ResourcesManager.getInstance().dump(prefix, writer);
     }
 
     /**
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 9b6764d..14cae95 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -413,4 +413,9 @@
      * @return The intent used to launch the home activity.
      */
     public abstract Intent getHomeIntent();
+
+    /**
+     * WindowManager notifies AM when display size of the default display changes.
+     */
+    public abstract void notifyDefaultDisplaySizeChanged();
 }
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0a23858..15af8a9 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -81,7 +81,6 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Debug;
-import android.os.DropBoxManager;
 import android.os.Environment;
 import android.os.GraphicsEnvironment;
 import android.os.Handler;
@@ -147,6 +146,7 @@
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastPrintWriter;
+import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.org.conscrypt.OpenSSLSocketImpl;
 import com.android.org.conscrypt.TrustedCertificateStore;
@@ -156,8 +156,6 @@
 import dalvik.system.VMDebug;
 import dalvik.system.VMRuntime;
 
-import libcore.io.DropBox;
-import libcore.io.EventLogger;
 import libcore.io.IoUtils;
 import libcore.net.event.NetworkEventDispatcher;
 
@@ -384,6 +382,9 @@
         = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>();
 
     final GcIdler mGcIdler = new GcIdler();
+    final PurgeIdler mPurgeIdler = new PurgeIdler();
+
+    boolean mPurgeIdlerScheduled = false;
     boolean mGcIdlerScheduled = false;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -1666,6 +1667,7 @@
         public static final int RUN_ISOLATED_ENTRY_POINT = 158;
         public static final int EXECUTE_TRANSACTION = 159;
         public static final int RELAUNCH_ACTIVITY = 160;
+        public static final int PURGE_RESOURCES = 161;
 
         String codeToString(int code) {
             if (DEBUG_MESSAGES) {
@@ -1709,6 +1711,7 @@
                     case RUN_ISOLATED_ENTRY_POINT: return "RUN_ISOLATED_ENTRY_POINT";
                     case EXECUTE_TRANSACTION: return "EXECUTE_TRANSACTION";
                     case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
+                    case PURGE_RESOURCES: return "PURGE_RESOURCES";
                 }
             }
             return Integer.toString(code);
@@ -1746,6 +1749,7 @@
                 case UNBIND_SERVICE:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
                     handleUnbindService((BindServiceData)msg.obj);
+                    schedulePurgeIdler();
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case SERVICE_ARGS:
@@ -1756,6 +1760,7 @@
                 case STOP_SERVICE:
                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
                     handleStopService((IBinder)msg.obj);
+                    schedulePurgeIdler();
                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                     break;
                 case CONFIGURATION_CHANGED:
@@ -1889,6 +1894,9 @@
                 case RELAUNCH_ACTIVITY:
                     handleRelaunchActivityLocally((IBinder) msg.obj);
                     break;
+                case PURGE_RESOURCES:
+                    schedulePurgeIdler();
+                    break;
             }
             Object obj = msg.obj;
             if (obj instanceof SomeArgs) {
@@ -1941,6 +1949,17 @@
         @Override
         public final boolean queueIdle() {
             doGcIfNeeded();
+            nPurgePendingResources();
+            return false;
+        }
+    }
+
+    final class PurgeIdler implements MessageQueue.IdleHandler {
+        @Override
+        public boolean queueIdle() {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "purgePendingResources");
+            nPurgePendingResources();
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
             return false;
         }
     }
@@ -2270,6 +2289,22 @@
         mH.removeMessages(H.GC_WHEN_IDLE);
     }
 
+    void schedulePurgeIdler() {
+        if (!mPurgeIdlerScheduled) {
+            mPurgeIdlerScheduled = true;
+            Looper.myQueue().addIdleHandler(mPurgeIdler);
+        }
+        mH.removeMessages(H.PURGE_RESOURCES);
+    }
+
+    void unschedulePurgeIdler() {
+        if (mPurgeIdlerScheduled) {
+            mPurgeIdlerScheduled = false;
+            Looper.myQueue().removeIdleHandler(mPurgeIdler);
+        }
+        mH.removeMessages(H.PURGE_RESOURCES);
+    }
+
     void doGcIfNeeded() {
         mGcIdlerScheduled = false;
         final long now = SystemClock.uptimeMillis();
@@ -4559,6 +4594,7 @@
             }
             r.setState(ON_DESTROY);
         }
+        schedulePurgeIdler();
         mActivities.remove(token);
         StrictMode.decrementExpectedActivityCount(activityClass);
         return r;
@@ -5243,6 +5279,16 @@
         }
     }
 
+    /**
+     * Updates the application info.
+     *
+     * This only works in the system process. Must be called on the main thread.
+     */
+    public void handleSystemApplicationInfoChanged(@NonNull ApplicationInfo ai) {
+        Preconditions.checkState(mSystemThread, "Must only be called in the system process");
+        handleApplicationInfoChanged(ai);
+    }
+
     void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) {
         // Updates triggered by package installation go through a package update
         // receiver. Here we try to capture ApplicationInfo changes that are
@@ -6631,9 +6677,6 @@
             }
         }
 
-        // add dropbox logging to libcore
-        DropBox.setReporter(new DropBoxReporter());
-
         ViewRootImpl.ConfigChangedCallback configChangedCallback
                 = (Configuration globalConfig) -> {
             synchronized (mResourcesManager) {
@@ -6687,38 +6730,6 @@
         }
     }
 
-    private static class EventLoggingReporter implements EventLogger.Reporter {
-        @Override
-        public void report (int code, Object... list) {
-            EventLog.writeEvent(code, list);
-        }
-    }
-
-    private class DropBoxReporter implements DropBox.Reporter {
-
-        private DropBoxManager dropBox;
-
-        public DropBoxReporter() {}
-
-        @Override
-        public void addData(String tag, byte[] data, int flags) {
-            ensureInitialized();
-            dropBox.addData(tag, data, flags);
-        }
-
-        @Override
-        public void addText(String tag, String data) {
-            ensureInitialized();
-            dropBox.addText(tag, data);
-        }
-
-        private synchronized void ensureInitialized() {
-            if (dropBox == null) {
-                dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
-            }
-        }
-    }
-
     public static void main(String[] args) {
         Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
 
@@ -6729,9 +6740,6 @@
 
         Environment.initForCurrentUser();
 
-        // Set the reporter for event logging in libcore
-        EventLogger.setReporter(new EventLoggingReporter());
-
         // Make sure TrustedCertificateStore looks in the right place for CA certificates
         final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
         TrustedCertificateStore.setDefaultUserDirectory(configDir);
@@ -6771,6 +6779,6 @@
     }
 
     // ------------------ Regular JNI ------------------------
-
+    private native void nPurgePendingResources();
     private native void nDumpGraphicsInfo(FileDescriptor fd);
 }
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 68869c65..2d9fbf9 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -125,10 +125,13 @@
         }
     }
 
+    private static final boolean ENABLE_APK_ASSETS_CACHE = false;
+
     /**
      * The ApkAssets we are caching and intend to hold strong references to.
      */
-    private final LruCache<ApkKey, ApkAssets> mLoadedApkAssets = new LruCache<>(3);
+    private final LruCache<ApkKey, ApkAssets> mLoadedApkAssets =
+            (ENABLE_APK_ASSETS_CACHE) ? new LruCache<>(3) : null;
 
     /**
      * The ApkAssets that are being referenced in the wild that we can reuse, even if they aren't
@@ -316,9 +319,12 @@
     private @NonNull ApkAssets loadApkAssets(String path, boolean sharedLib, boolean overlay)
             throws IOException {
         final ApkKey newKey = new ApkKey(path, sharedLib, overlay);
-        ApkAssets apkAssets = mLoadedApkAssets.get(newKey);
-        if (apkAssets != null) {
-            return apkAssets;
+        ApkAssets apkAssets = null;
+        if (mLoadedApkAssets != null) {
+            apkAssets = mLoadedApkAssets.get(newKey);
+            if (apkAssets != null) {
+                return apkAssets;
+            }
         }
 
         // Optimistically check if this ApkAssets exists somewhere else.
@@ -326,7 +332,10 @@
         if (apkAssetsRef != null) {
             apkAssets = apkAssetsRef.get();
             if (apkAssets != null) {
-                mLoadedApkAssets.put(newKey, apkAssets);
+                if (mLoadedApkAssets != null) {
+                    mLoadedApkAssets.put(newKey, apkAssets);
+                }
+
                 return apkAssets;
             } else {
                 // Clean up the reference.
@@ -341,7 +350,11 @@
         } else {
             apkAssets = ApkAssets.loadFromPath(path, false /*system*/, sharedLib);
         }
-        mLoadedApkAssets.put(newKey, apkAssets);
+
+        if (mLoadedApkAssets != null) {
+            mLoadedApkAssets.put(newKey, apkAssets);
+        }
+
         mCachedApkAssets.put(newKey, new WeakReference<>(apkAssets));
         return apkAssets;
     }
@@ -441,18 +454,22 @@
 
             pw.println("ResourcesManager:");
             pw.increaseIndent();
-            pw.print("cached apks: total=");
-            pw.print(mLoadedApkAssets.size());
-            pw.print(" created=");
-            pw.print(mLoadedApkAssets.createCount());
-            pw.print(" evicted=");
-            pw.print(mLoadedApkAssets.evictionCount());
-            pw.print(" hit=");
-            pw.print(mLoadedApkAssets.hitCount());
-            pw.print(" miss=");
-            pw.print(mLoadedApkAssets.missCount());
-            pw.print(" max=");
-            pw.print(mLoadedApkAssets.maxSize());
+            if (mLoadedApkAssets != null) {
+                pw.print("cached apks: total=");
+                pw.print(mLoadedApkAssets.size());
+                pw.print(" created=");
+                pw.print(mLoadedApkAssets.createCount());
+                pw.print(" evicted=");
+                pw.print(mLoadedApkAssets.evictionCount());
+                pw.print(" hit=");
+                pw.print(mLoadedApkAssets.hitCount());
+                pw.print(" miss=");
+                pw.print(mLoadedApkAssets.missCount());
+                pw.print(" max=");
+                pw.print(mLoadedApkAssets.maxSize());
+            } else {
+                pw.print("cached apks: 0 [cache disabled]");
+            }
             pw.println();
 
             pw.print("total apks: ");
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 83c43e7..15005d0 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -87,6 +87,7 @@
 import android.net.IpSecManager;
 import android.net.NetworkPolicyManager;
 import android.net.NetworkScoreManager;
+import android.net.NetworkStack;
 import android.net.NetworkWatchlistManager;
 import android.net.lowpan.ILowpanManager;
 import android.net.lowpan.LowpanManager;
@@ -143,7 +144,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.euicc.EuiccCardManager;
 import android.telephony.euicc.EuiccManager;
-import android.telephony.rcs.RcsManager;
+import android.telephony.ims.RcsManager;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
@@ -283,6 +284,13 @@
                 return new ConnectivityManager(context, service);
             }});
 
+        registerService(Context.NETWORK_STACK_SERVICE, NetworkStack.class,
+                new StaticServiceFetcher<NetworkStack>() {
+                @Override
+                public NetworkStack createService() {
+                    return new NetworkStack();
+                }});
+
         registerService(Context.IPSEC_SERVICE, IpSecManager.class,
                 new CachedServiceFetcher<IpSecManager>() {
             @Override
diff --git a/core/java/android/app/VrManager.java b/core/java/android/app/VrManager.java
index 66d7a25..b1465ae 100644
--- a/core/java/android/app/VrManager.java
+++ b/core/java/android/app/VrManager.java
@@ -4,7 +4,6 @@
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
-import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
@@ -230,7 +229,6 @@
      * input by InputMethodManagerService.
      * @hide
      */
-    @TestApi
     @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
     public void setVrInputMethod(ComponentName componentName) {
         try {
diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java
index 1c9477d..6fb0d7e 100644
--- a/core/java/android/app/admin/DeviceAdminReceiver.java
+++ b/core/java/android/app/admin/DeviceAdminReceiver.java
@@ -23,7 +23,6 @@
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.SystemApi;
 import android.app.Service;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -755,7 +754,6 @@
      * @deprecated Do not use
      */
     @Deprecated
-    @SystemApi
     public void onReadyForUserInitialization(Context context, Intent intent) {
     }
 
diff --git a/core/java/android/app/admin/SystemUpdatePolicy.java b/core/java/android/app/admin/SystemUpdatePolicy.java
index 2a451ff..96dbc76 100644
--- a/core/java/android/app/admin/SystemUpdatePolicy.java
+++ b/core/java/android/app/admin/SystemUpdatePolicy.java
@@ -691,13 +691,11 @@
                 mFreezePeriods.stream().map(n -> n.toString()).collect(Collectors.joining(",")));
     }
 
-    @SystemApi
     @Override
     public int describeContents() {
         return 0;
     }
 
-    @SystemApi
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mPolicyType);
@@ -714,7 +712,6 @@
         }
     }
 
-    @SystemApi
     public static final Parcelable.Creator<SystemUpdatePolicy> CREATOR =
             new Parcelable.Creator<SystemUpdatePolicy>() {
 
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index d568662..dd61f28 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -41,18 +41,23 @@
 import java.util.List;
 
 /**
- * Assist data automatically created by the platform's implementation of assist and autofill.
+ * <p>This API automatically creates assist data from the platform's
+ * implementation of assist and autofill.
  *
  * <p>The structure is used for assist purposes when created by
  * {@link android.app.Activity#onProvideAssistData}, {@link View#onProvideStructure(ViewStructure)},
  * or {@link View#onProvideVirtualStructure(ViewStructure)}.
  *
- * <p>The structure is used for autofill purposes when created by
+ * <p>The structure is also used for autofill purposes when created by
  * {@link View#onProvideAutofillStructure(ViewStructure, int)},
  * or {@link View#onProvideAutofillVirtualStructure(ViewStructure, int)}.
  *
- * <p>For performance reasons, some properties of the assist data might be available just for assist
- * or autofill purposes; in those case, the property availability will be document in its javadoc.
+ * <p>For performance reasons, some properties of the assist data might only be available for
+ * assist or autofill purposes. In those cases, a property's availability will be documented
+ * in its javadoc.
+ *
+ * <p>To learn about using Autofill in your app, read the
+ * <a href="/guide/topics/text/autofill">Autofill Framework</a> guides.
  */
 public class AssistStructure implements Parcelable {
     static final String TAG = "AssistStructure";
diff --git a/core/java/android/appwidget/AppWidgetManagerInternal.java b/core/java/android/appwidget/AppWidgetManagerInternal.java
index 7ab3d8b..5694ca8 100644
--- a/core/java/android/appwidget/AppWidgetManagerInternal.java
+++ b/core/java/android/appwidget/AppWidgetManagerInternal.java
@@ -16,12 +16,9 @@
 
 package android.appwidget;
 
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.util.ArraySet;
 
-import java.util.Set;
-
 /**
  * App widget manager local system service interface.
  *
@@ -36,4 +33,13 @@
      * @return Whether the UID hosts widgets from the package.
      */
     public abstract @Nullable ArraySet<String> getHostedWidgetPackages(int uid);
+
+    /**
+     * Execute the widget-related work of unlocking a user.  This is intentionally
+     * invoked just <em>before</em> the boot-completed broadcast is issued, after
+     * the data-related work of unlock has completed.
+     *
+     * @param userId The user that is being unlocked.
+     */
+    public abstract void unlockUser(int userId);
 }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 654bfaf..10c8b15 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -643,6 +643,7 @@
     private final IBluetoothManager mManagerService;
     @UnsupportedAppUsage
     private IBluetooth mService;
+    private Context mContext;
     private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock();
 
     private final Object mLock = new Object();
@@ -1541,6 +1542,23 @@
     }
 
     /**
+     * Set the context for this BluetoothAdapter (only called from BluetoothManager)
+     * @hide
+     */
+    public void setContext(Context context) {
+        mContext = context;
+    }
+
+    private String getOpPackageName() {
+        // Workaround for legacy API for getting a BluetoothAdapter not
+        // passing a context
+        if (mContext != null) {
+            return mContext.getOpPackageName();
+        }
+        return ActivityThread.currentOpPackageName();
+    }
+
+    /**
      * Start the remote device discovery process.
      * <p>The discovery process usually involves an inquiry scan of about 12
      * seconds, followed by a page scan of each new device to retrieve its
@@ -1577,7 +1595,7 @@
         try {
             mServiceLock.readLock().lock();
             if (mService != null) {
-                return mService.startDiscovery();
+                return mService.startDiscovery(getOpPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "", e);
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index e3672a7..e08d405 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -67,6 +67,7 @@
         }
         // Legacy api - getDefaultAdapter does not take in the context
         mAdapter = BluetoothAdapter.getDefaultAdapter();
+        mAdapter.setContext(context);
     }
 
     /**
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 4c98e23..d3393b9 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -56,6 +56,7 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Objects;
 
 /**
  * Content providers are one of the primary building blocks of Android applications, providing
@@ -218,7 +219,7 @@
         @Override
         public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection,
                 @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 // The caller has no access to the data, so return an empty cursor with
@@ -257,14 +258,14 @@
 
         @Override
         public String getType(Uri uri) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             return ContentProvider.this.getType(uri);
         }
 
         @Override
         public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
@@ -280,7 +281,7 @@
 
         @Override
         public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
@@ -302,11 +303,12 @@
             for (int i = 0; i < numOperations; i++) {
                 ContentProviderOperation operation = operations.get(i);
                 Uri uri = operation.getUri();
-                validateIncomingUri(uri);
                 userIds[i] = getUserIdFromUri(uri);
-                if (userIds[i] != UserHandle.USER_CURRENT) {
-                    // Removing the user id from the uri.
-                    operation = new ContentProviderOperation(operation, true);
+                uri = validateIncomingUri(uri);
+                uri = maybeGetUriWithoutUserId(uri);
+                // Rebuild operation if we changed the Uri above
+                if (!Objects.equals(operation.getUri(), uri)) {
+                    operation = new ContentProviderOperation(operation, uri);
                     operations.set(i, operation);
                 }
                 if (operation.isReadOperation()) {
@@ -341,7 +343,7 @@
 
         @Override
         public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
@@ -357,7 +359,7 @@
         @Override
         public int update(String callingPkg, Uri uri, ContentValues values, String selection,
                 String[] selectionArgs) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
@@ -374,7 +376,7 @@
         public ParcelFileDescriptor openFile(
                 String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal,
                 IBinder callerToken) throws FileNotFoundException {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             enforceFilePermission(callingPkg, uri, mode, callerToken);
             final String original = setCallingPackage(callingPkg);
@@ -390,7 +392,7 @@
         public AssetFileDescriptor openAssetFile(
                 String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             enforceFilePermission(callingPkg, uri, mode, null);
             final String original = setCallingPackage(callingPkg);
@@ -416,7 +418,7 @@
 
         @Override
         public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter);
         }
@@ -425,7 +427,7 @@
         public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
                 Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
             Bundle.setDefusable(opts, true);
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = maybeGetUriWithoutUserId(uri);
             enforceFilePermission(callingPkg, uri, "r", null);
             final String original = setCallingPackage(callingPkg);
@@ -444,7 +446,7 @@
 
         @Override
         public Uri canonicalize(String callingPkg, Uri uri) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
@@ -460,7 +462,7 @@
 
         @Override
         public Uri uncanonicalize(String callingPkg, Uri uri) {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             int userId = getUserIdFromUri(uri);
             uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
@@ -477,7 +479,7 @@
         @Override
         public boolean refresh(String callingPkg, Uri uri, Bundle args,
                 ICancellationSignal cancellationSignal) throws RemoteException {
-            validateIncomingUri(uri);
+            uri = validateIncomingUri(uri);
             uri = getUriWithoutUserId(uri);
             if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
                 return false;
@@ -1914,7 +1916,7 @@
          */
         if (mContext == null) {
             mContext = context;
-            if (context != null) {
+            if (context != null && mTransport != null) {
                 mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService(
                         Context.APP_OPS_SERVICE);
             }
@@ -2023,7 +2025,7 @@
     }
 
     /** @hide */
-    private void validateIncomingUri(Uri uri) throws SecurityException {
+    public Uri validateIncomingUri(Uri uri) throws SecurityException {
         String auth = uri.getAuthority();
         if (!mSingleUser) {
             int userId = getUserIdFromAuthority(auth, UserHandle.USER_CURRENT);
@@ -2042,6 +2044,19 @@
             }
             throw new SecurityException(message);
         }
+
+        // Normalize the path by removing any empty path segments, which can be
+        // a source of security issues.
+        final String encodedPath = uri.getEncodedPath();
+        if (encodedPath != null && encodedPath.indexOf("//") != -1) {
+            final Uri normalized = uri.buildUpon()
+                    .encodedPath(encodedPath.replaceAll("//+", "/")).build();
+            Log.w(TAG, "Normalized " + uri + " to " + normalized
+                    + " to avoid possible security issues");
+            return normalized;
+        } else {
+            return uri;
+        }
     }
 
     /** @hide */
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index e3d9b19..7dc4577 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -101,13 +101,9 @@
     }
 
     /** @hide */
-    public ContentProviderOperation(ContentProviderOperation cpo, boolean removeUserIdFromUri) {
+    public ContentProviderOperation(ContentProviderOperation cpo, Uri withUri) {
         mType = cpo.mType;
-        if (removeUserIdFromUri) {
-            mUri = ContentProvider.getUriWithoutUserId(cpo.mUri);
-        } else {
-            mUri = cpo.mUri;
-        }
+        mUri = withUri;
         mValues = cpo.mValues;
         mSelection = cpo.mSelection;
         mSelectionArgs = cpo.mSelectionArgs;
@@ -117,14 +113,6 @@
         mYieldAllowed = cpo.mYieldAllowed;
     }
 
-    /** @hide */
-    public ContentProviderOperation getWithoutUserIdInUri() {
-        if (ContentProvider.uriHasUserId(mUri)) {
-            return new ContentProviderOperation(this, true);
-        }
-        return this;
-    }
-
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mType);
         Uri.writeToParcel(dest, mUri);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5cbb1f8..81e72cc 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -49,6 +49,7 @@
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
+import android.net.NetworkStack;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -327,6 +328,15 @@
     public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
 
     /**
+     * Flag for {@link #bindService}: If binding from something better than perceptible,
+     * still set the adjust below perceptible. This would be used for bound services that can
+     * afford to be evicted when under extreme memory pressure, but should be restarted as soon
+     * as possible.
+     * @hide
+     */
+    public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100;
+
+    /**
      * @hide Flag for {@link #bindService}: allows binding to a service provided
      * by an instant app. Note that the caller may not have access to the instant
      * app providing the service which is a violation of the instant app sandbox.
@@ -3495,6 +3505,15 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve a
+     * {@link NetworkStack} for communicating with the network stack
+     * @hide
+     * @see #getSystemService(String)
+     * @see NetworkStack
+     */
+    public static final String NETWORK_STACK_SERVICE = "network_stack";
+
+    /**
+     * Use with {@link #getSystemService(String)} to retrieve a
      * {@link android.net.IpSecManager} for encrypting Sockets or Networks with
      * IPSec.
      *
@@ -4251,7 +4270,7 @@
 
     /**
      * Use with {@link #getSystemService(String)} to retrieve an
-     * {@link android.telephony.rcs.RcsManager}.
+     * {@link android.telephony.ims.RcsManager}.
      * @hide
      */
     public static final String TELEPHONY_RCS_SERVICE = "ircs";
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index 3de7a8b..2d59003 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -21,7 +21,6 @@
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.annotation.UserIdInt;
-import android.app.Activity;
 import android.app.usage.UsageStatsManager;
 import android.content.Context;
 import android.content.Intent;
@@ -31,256 +30,23 @@
 import android.os.Build.VERSION_CODES;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.UserHandle;
 
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.util.List;
 
 /**
- * The ShortcutManager performs operations on an app's set of <em>shortcuts</em>. The
- * {@link ShortcutInfo} class contains information about each of the shortcuts themselves.
+ * <p><code>ShortcutManager</code> executes operations on an app's set of <i>shortcuts</i>, which
+ * represent specific tasks and actions that users can perform within your app. This page lists
+ * components of the <code>ShortcutManager</code> class that you can use to create and manage
+ * sets of shortcuts.
  *
- * <p>An app's shortcuts represent specific tasks and actions that users can perform within your
- * app. When a user selects a shortcut in the currently-active launcher, your app opens an activity
- * other than the app's starting activity, provided that the currently-active launcher supports app
- * shortcuts.</p>
+ * <p>To learn about methods that retrieve information about a single shortcut&mdash;including
+ * identifiers, type, and status&mdash;read the <code>
+ * <a href="/reference/android/content/pm/ShortcutInfo.html">ShortcutInfo</a></code> reference.
  *
- * <p>The types of shortcuts that you create for your app depend on the app's key use cases. For
- * example, an email app may publish the "compose new email" shortcut, which allows the app to
- * directly open the compose activity.</p>
- *
- * <p class="note"><b>Note:</b> Only main activities&mdash;activities that handle the
- * {@link Intent#ACTION_MAIN} action and the {@link Intent#CATEGORY_LAUNCHER} category&mdash;can
- * have shortcuts. If an app has multiple main activities, you need to define the set of shortcuts
- * for <em>each</em> activity.
- *
- * <p>This page discusses the implementation details of the <code>ShortcutManager</code> class. For
- * definitions of key terms and guidance on performing operations on shortcuts within your app, see
- * the <a href="/guide/topics/ui/shortcuts.html">App Shortcuts</a> feature guide.
- *
- * <h3>Shortcut characteristics</h3>
- *
- * This section describes in-depth details about each shortcut type's usage and availability.
- *
- * <p class="note"><b>Important security note:</b> All shortcut information is stored in
- * <a href="/training/articles/direct-boot.html">credential encrypted storage</a>, so your app
- * cannot access a user's shortcuts until after they've unlocked the device.
- *
- * <h4>Static and dynamic shortcuts</h4>
- *
- * <p>Static shortcuts and dynamic shortcuts are shown in a supported launcher when the user
- * performs a specific gesture. On currently-supported launchers, the gesture is a long-press on the
- * app's launcher icon, but the actual gesture may be different on other launcher apps.
- *
- * <p>The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts.
- *
- * <h4>Pinned shortcuts</h4>
- *
- * <p>Because pinned shortcuts appear in the launcher itself, they're always visible. A pinned
- * shortcut is removed from the launcher only in the following situations:
- * <ul>
- *     <li>The user removes it.
- *     <li>The publisher app associated with the shortcut is uninstalled.
- *     <li>The user selects <b>Clear data</b> from the publisher app's <i>Storage</i> screen, within
- *     the system's <b>Settings</b> app.
- * </ul>
- *
- * <p>Because the system performs
- * <a href="/guide/topics/ui/shortcuts.html#backup-and-restore">backup and restore</a> on pinned
- * shortcuts automatically, these shortcuts' IDs should contain either stable, constant strings or
- * server-side identifiers, rather than identifiers generated locally that might not make sense on
- * other devices.
- *
- * <h3>Shortcut display order</h3>
- *
- * <p>When the launcher displays an app's shortcuts, they should appear in the following order:
- *
- * <ol>
- *   <li><b>Static shortcuts:</b> Shortcuts whose {@link ShortcutInfo#isDeclaredInManifest()} method
- *   returns {@code true}.</li>
- *   <li><b>Dynamic shortcuts:</b> Shortcuts whose {@link ShortcutInfo#isDynamic()} method returns
- *   {@code true}.</li>
- * </ol>
- *
- * <p>Within each shortcut type (static and dynamic), shortcuts are sorted in order of increasing
- * rank according to {@link ShortcutInfo#getRank()}.</p>
- *
- * <h4>Shortcut ranks</h4>
- *
- * <p>Shortcut ranks are non-negative, sequential integers that determine the order in which
- * shortcuts appear, assuming that the shortcuts are all in the same category. You can update ranks
- * of existing shortcuts when you call {@link #updateShortcuts(List)},
- * {@link #addDynamicShortcuts(List)}, or {@link #setDynamicShortcuts(List)}.
- *
- * <p class="note"><b>Note:</b> Ranks are auto-adjusted so that they're unique for each type of
- * shortcut (static or dynamic). For example, if there are 3 dynamic shortcuts with ranks 0, 1 and
- * 2, adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut
- * at the second position. In response, the third and fourth shortcuts move closer to the bottom of
- * the shortcut list, with their ranks changing to 2 and 3, respectively.
- *
- * <h3>Options for static shortcuts</h3>
- *
- * The following list includes descriptions for the different attributes within a static shortcut.
- * You must provide a value for {@code android:shortcutId} and {@code android:shortcutShortLabel};
- * all other values are optional.
- *
- * <dl>
- *   <dt>{@code android:shortcutId}</dt>
- *   <dd><p>A string literal, which represents the shortcut when a {@code ShortcutManager} object
- *   performs operations on it.</p>
- *   <p class="note"><b>Note: </b>You cannot set this attribute's value to a resource string, such
- *   as <code>@string/foo</code>.</p>
- *   </dd>
- *
- *   <dt>{@code android:enabled}</dt>
- *   <dd><p>Whether the user can interact with the shortcut from a supported launcher.</p>
- *   <p>The default value is {@code true}. If you set it to {@code false}, you should also set
- *   {@code android:shortcutDisabledMessage} to a message that explains why you've disabled the
- *   shortcut. If you don't think you need to provide such a message, it's easiest to just remove
- *   the shortcut from the XML file entirely, rather than changing the values of the shortcut's
- *   {@code android:enabled} and {@code android:shortcutDisabledMessage} attributes.
- *   </dd>
- *
- *   <dt>{@code android:icon}</dt>
- *   <dd><p>The <a href="/topic/performance/graphics/index.html">bitmap</a> or
- *   <a href="/guide/practices/ui_guidelines/icon_design_adaptive.html">adaptive icon</a> that the
- *   launcher uses when displaying the shortcut to the user. This value can be either the path to an
- *   image or the resource file that contains the image. Use adaptive icons whenever possible to
- *   improve performance and consistency.</p>
- *   <p class="note"><b>Note: </b>Shortcut icons cannot include
- *   <a href="/training/material/drawables.html#DrawableTint">tints</a>.
- *   </dd>
- *
- *   <dt>{@code android:shortcutShortLabel}</dt>
- *   <dd><p>A concise phrase that describes the shortcut's purpose. For more information, see
- *   {@link ShortcutInfo.Builder#setShortLabel(CharSequence)}.</p>
- *   <p class="note"><b>Note: </b>This attribute's value must be a resource string, such as
- *   <code>@string/shortcut_short_label</code>.</p>
- *   </dd>
- *
- *   <dt>{@code android:shortcutLongLabel}</dt>
- *   <dd><p>An extended phrase that describes the shortcut's purpose. If there's enough space, the
- *   launcher displays this value instead of {@code android:shortcutShortLabel}. For more
- *   information, see {@link ShortcutInfo.Builder#setLongLabel(CharSequence)}.</p>
- *   <p class="note"><b>Note: </b>This attribute's value must be a resource string, such as
- *   <code>@string/shortcut_long_label</code>.</p>
- *   </dd>
- *
- *   <dt>{@code android:shortcutDisabledMessage}</dt>
- *   <dd><p>The message that appears in a supported launcher when the user attempts to launch a
- *   disabled shortcut. The message should explain to the user why the shortcut is now disabled.
- *   This attribute's value has no effect if {@code android:enabled} is {@code true}.</p>
- *   <p class="note"><b>Note: </b>This attribute's value must be a resource string, such as
- *   <code>@string/shortcut_disabled_message</code>.</p>
- *   </dd>
- * </dl>
- *
- * <h3>Inner elements that define static shortcuts</h3>
- *
- * <p>The XML file that lists an app's static shortcuts supports the following elements inside each
- * {@code <shortcut>} element. You must include an {@code intent} inner element for each
- * static shortcut that you define.</p>
- *
- * <dl>
- *   <dt>{@code intent}</dt>
- *   <dd><p>The action that the system launches when the user selects the shortcut. This intent must
- *   provide a value for the {@code android:action} attribute.</p>
- *   <p>You can provide multiple intents for a single shortcut. If you do so, the last defined
- *   activity is launched, and the other activities are placed in the
- *   <a href="/guide/components/tasks-and-back-stack.html">back stack</a>. See
- *   <a href="/guide/topics/ui/shortcuts.html#static">Using Static Shortcuts</a> and the
- *   {@link android.app.TaskStackBuilder} class reference for details.</p>
- *   <p class="note"><b>Note:</b> This {@code intent} element cannot include string resources.</p>
- *   <p>To learn more about how to configure intents, see
- *   <a href="{@docRoot}guide/topics/ui/settings.html#Intents">Using intents</a>.</p>
- *   </dd>
- *
- *   <dt>{@code categories}</dt>
- *   <dd><p>Provides a grouping for the types of actions that your app's shortcuts perform, such as
- *   creating new chat messages.</p>
- *   <p>For a list of supported shortcut categories, see the {@link ShortcutInfo} class reference
- *   for a list of supported shortcut categories.
- *   </dd>
- * </dl>
- *
- * <h3>Updating shortcuts</h3>
- *
- * <p>Each app's launcher icon can contain at most {@link #getMaxShortcutCountPerActivity()} number
- * of static and dynamic shortcuts combined. There is no limit to the number of pinned shortcuts
- * that an app can create, though.
- *
- * <p>When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut,
- * the pinned shortcut is still visible and launchable.  This allows an app to have more than
- * {@link #getMaxShortcutCountPerActivity()} number of shortcuts.
- *
- * <p>As an example, suppose {@link #getMaxShortcutCountPerActivity()} is 5:
- * <ol>
- *     <li>A chat app publishes 5 dynamic shortcuts for the 5 most recent
- *     conversations (c1, c2, ..., c5).
- *
- *     <li>The user pins all 5 of the shortcuts.
- *
- *     <li>Later, the user has started 3 additional conversations (c6, c7, and c8), so the publisher
- *     app re-publishes its dynamic shortcuts. The new dynamic shortcut list is: c4, c5, ..., c8.
- *     <p>The publisher app has to remove c1, c2, and c3 because it can't have more than 5 dynamic
- *     shortcuts. However, c1, c2, and c3 are still pinned shortcuts that the user can access and
- *     launch.
- *     <p>At this point, the user can access a total of 8 shortcuts that link to activities in the
- *     publisher app, including the 3 pinned shortcuts, even though an app can have at most 5
- *     dynamic shortcuts.
- *
- *     <li>The app can use {@link #updateShortcuts(List)} to update <em>any</em> of the existing
- *     8 shortcuts, when, for example, the chat peers' icons have changed.
- *     <p>The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods
- *     can also be used to update existing shortcuts with the same IDs, but they <b>cannot</b> be
- *     used for updating non-dynamic, pinned shortcuts because these 2 methods try to convert the
- *     given lists of shortcuts to dynamic shortcuts.
- * </ol>
- *
- * <h3>Shortcut intents</h3>
- *
- * <p>
- * Dynamic shortcuts can be published with any set of {@link Intent#addFlags Intent} flags.
- * Typically, {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} is specified, possibly along with other
- * flags; otherwise, if the app is already running, the app is simply brought to
- * the foreground, and the target activity might not appear.
- *
- * <p>Static shortcuts <b>cannot</b> have custom intent flags.
- * The first intent of a static shortcut will always have {@link Intent#FLAG_ACTIVITY_NEW_TASK}
- * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set. This means, when the app is already running, all
- * the existing activities in your app are destroyed when a static shortcut is launched.
- * If this behavior is not desirable, you can use a <em>trampoline activity</em>, or an invisible
- * activity that starts another activity in {@link Activity#onCreate}, then calls
- * {@link Activity#finish()}:
- * <ol>
- *     <li>In the <code>AndroidManifest.xml</code> file, the trampoline activity should include the
- *     attribute assignment {@code android:taskAffinity=""}.
- *     <li>In the shortcuts resource file, the intent within the static shortcut should reference
- *     the trampoline activity.
- * </ol>
- *
- * <h3>Rate limiting</h3>
- *
- * <p>When <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate limiting</a> is active,
- * {@link #isRateLimitingActive()} returns {@code true}.
- *
- * <p>Rate limiting is reset upon certain events, so even background apps can call these APIs until
- * the rate limit is reached again. These events include the following:
- * <ul>
- *   <li>An app comes to the foreground.
- *   <li>The system locale changes.
- *   <li>The user performs the <a href="/guide/topics/ui/notifiers/notifications.html#direct">inline
- *   reply</a> action on a notification.
- * </ul>
- *
- * <h3>Handling system locale changes</h3>
- *
- * <p>Apps should update dynamic and pinned shortcuts when they receive the
- * {@link Intent#ACTION_LOCALE_CHANGED} broadcast, indicating that the system locale has changed.
- * <p>When the system locale changes, <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate
- * limiting</a> is reset, so even background apps can add and update dynamic shortcuts until the
- * rate limit is reached again.
+ * <p>For guidance about using shortcuts, see
+ * <a href="/guide/topics/ui/shortcuts/index.html">App shortcuts</a>.
  *
  * <h3>Retrieving class instances</h3>
  * <!-- Provides a heading for the content filled in by the @SystemService annotation below -->
@@ -461,8 +227,9 @@
     }
 
     /**
-     * Disable pinned shortcuts.  For more details, see the Javadoc for the {@link ShortcutManager}
-     * class.
+     * Disable pinned shortcuts.  For more details, read
+     * <a href="/guide/topics/ui/shortcuts/managing-shortcuts.html#disable-shortcuts">
+     * Disable shortcuts</a>.
      *
      * @throws IllegalArgumentException If trying to disable immutable shortcuts.
      *
@@ -501,7 +268,9 @@
     /**
      * Disable pinned shortcuts, showing the user a custom error message when they try to select
      * the disabled shortcuts.
-     * For more details, see the Javadoc for the {@link ShortcutManager} class.
+     * For more details, read
+     * <a href="/guide/topics/ui/shortcuts/managing-shortcuts.html#disable-shortcuts">
+     * Disable shortcuts</a>.
      *
      * @throws IllegalArgumentException If trying to disable immutable shortcuts.
      *
@@ -589,7 +358,8 @@
     /**
      * Return {@code true} when rate-limiting is active for the caller app.
      *
-     * <p>See the class level javadoc for details.
+     * <p>For details, see <a href="/guide/topics/ui/shortcuts/managing-shortcuts#rate-limiting">
+     * Rate limiting</a>.
      *
      * @throws IllegalStateException when the user is locked.
      */
@@ -635,7 +405,9 @@
      * Apps that publish shortcuts should call this method whenever the user
      * selects the shortcut containing the given ID or when the user completes
      * an action in the app that is equivalent to selecting the shortcut.
-     * For more details, see the Javadoc for the {@link ShortcutManager} class
+     * For more details, read about
+     * <a href="/guide/topics/ui/shortcuts/managing-shortcuts.html#track-usage">
+     * tracking shortcut usage</a>.
      *
      * <p>The information is accessible via {@link UsageStatsManager#queryEvents}
      * Typically, launcher apps use this information to build a prediction model
@@ -703,7 +475,9 @@
      * @param resultIntent If not null, this intent will be sent when the shortcut is pinned.
      *    Use {@link android.app.PendingIntent#getIntentSender()} to create an {@link IntentSender}.
      *    To avoid background execution limits, use an unexported, manifest-declared receiver.
-     *    For more details, see the overview documentation for the {@link ShortcutManager} class.
+     *    For more details, see
+     *    <a href="/guide/topics/ui/shortcuts/creating-shortcuts.html#pinned">
+     *    Creating pinned shortcuts</a>.
      *
      * @return {@code TRUE} if the launcher supports this feature.  Note the API will return without
      *    waiting for the user to respond, so getting {@code TRUE} from this API does *not* mean
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
index d392521..48f8ac9 100644
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ b/core/java/android/database/sqlite/SQLiteDebug.java
@@ -119,7 +119,6 @@
     /**
      * contains statistics about a database
      */
-    @TestApi
     public static class DbStats {
         /** name of the database */
         public String dbName;
@@ -151,7 +150,6 @@
      * return all pager and database stats for the current process.
      * @return {@link PagerStats}
      */
-    @TestApi
     public static PagerStats getDatabaseInfo() {
         PagerStats stats = new PagerStats();
         nativeGetPagerStats(stats);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4714587..49c3dc6 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -187,13 +187,19 @@
      * is for a network to which the connectivity manager was failing over
      * following a disconnect on another network.
      * Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
+     *
+     * @deprecated See {@link NetworkInfo}.
      */
+    @Deprecated
     public static final String EXTRA_IS_FAILOVER = "isFailover";
     /**
      * The lookup key for a {@link NetworkInfo} object. This is supplied when
      * there is another network that it may be possible to connect to. Retrieve with
      * {@link android.content.Intent#getParcelableExtra(String)}.
+     *
+     * @deprecated See {@link NetworkInfo}.
      */
+    @Deprecated
     public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
     /**
      * The lookup key for a boolean that indicates whether there is a
@@ -214,7 +220,10 @@
      * may be passed up from the lower networking layers, and its
      * meaning may be specific to a particular network type. Retrieve
      * it with {@link android.content.Intent#getStringExtra(String)}.
+     *
+     * @deprecated See {@link NetworkInfo#getExtraInfo()}.
      */
+    @Deprecated
     public static final String EXTRA_EXTRA_INFO = "extraInfo";
     /**
      * The lookup key for an int that provides information about
@@ -895,7 +904,9 @@
      *
      * @return a {@link NetworkInfo} object for the current default network
      *        or {@code null} if no default network is currently active
+     * @deprecated See {@link NetworkInfo}.
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public NetworkInfo getActiveNetworkInfo() {
         try {
@@ -1079,7 +1090,9 @@
      * @return a {@link NetworkInfo} object for the requested
      *        network or {@code null} if the {@code Network}
      *        is not valid.
+     * @deprecated See {@link NetworkInfo}.
      */
+    @Deprecated
     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public NetworkInfo getNetworkInfo(Network network) {
         return getNetworkInfoForUid(network, Process.myUid(), false);
diff --git a/core/java/android/net/INetdEventCallback.aidl b/core/java/android/net/INetdEventCallback.aidl
index 4b1a08d..0877a1a4 100644
--- a/core/java/android/net/INetdEventCallback.aidl
+++ b/core/java/android/net/INetdEventCallback.aidl
@@ -45,6 +45,20 @@
             in String[] ipAddresses, int ipAddressesCount, long timestamp, int uid);
 
     /**
+     * Represents adding or removing a NAT64 prefix.
+     * This method must not block or perform long-running operations.
+     *
+     * @param netId the ID of the network the prefix was performed on.
+     * @param added true if the NAT64 prefix was added, or false if the NAT64 prefix was removed.
+     *        There is only one prefix at a time for each netId. If a prefix is added, it replaces
+     *        the previous-added prefix.
+     * @param prefixString the detected NAT64 prefix as a string literal.
+     * @param prefixLength the prefix length associated with this NAT64 prefix.
+     */
+    void onNat64PrefixEvent(int netId, boolean added, @utf8InCpp String prefixString,
+            int prefixLength);
+
+    /**
      * Represents a private DNS validation success or failure.
      * This method must not block or perform long-running operations.
      *
diff --git a/core/java/android/net/INetworkStackConnector.aidl b/core/java/android/net/INetworkStackConnector.aidl
new file mode 100644
index 0000000..29f8828
--- /dev/null
+++ b/core/java/android/net/INetworkStackConnector.aidl
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2018, 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 perNmissions and
+ * limitations under the License.
+ */
+package android.net;
+
+/** @hide */
+oneway interface INetworkStackConnector {
+    // TODO: requestDhcpServer(), etc. will go here
+}
\ No newline at end of file
diff --git a/core/java/android/net/InetAddresses.java b/core/java/android/net/InetAddresses.java
new file mode 100644
index 0000000..8e6c69a
--- /dev/null
+++ b/core/java/android/net/InetAddresses.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net;
+
+import libcore.net.InetAddressUtils;
+
+import java.net.InetAddress;
+
+/**
+ * Utility methods for {@link InetAddress} implementations.
+ */
+public class InetAddresses {
+
+    private InetAddresses() {}
+
+    /**
+     * Checks to see if the {@code address} is a numeric address (such as {@code "192.0.2.1"} or
+     * {@code "2001:db8::1:2"}).
+     *
+     * <p>A numeric address is either an IPv4 address containing exactly 4 decimal numbers or an
+     * IPv6 numeric address. IPv4 addresses that consist of either hexadecimal or octal digits or
+     * do not have exactly 4 numbers are not treated as numeric.
+     *
+     * <p>This method will never do a DNS lookup.
+     *
+     * @param address the address to parse.
+     * @return true if the supplied address is numeric, false otherwise.
+     */
+    public static boolean isNumericAddress(String address) {
+        return InetAddressUtils.isNumericAddress(address);
+    }
+
+    /**
+     * Returns an InetAddress corresponding to the given numeric address (such
+     * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
+     *
+     * <p>See {@link #isNumericAddress(String)} (String)} for a definition as to what constitutes a
+     * numeric address.
+     *
+     * <p>This method will never do a DNS lookup.
+     *
+     * @param address the address to parse, must be numeric.
+     * @return an {@link InetAddress} instance corresponding to the address.
+     * @throws IllegalArgumentException if {@code address} is not a numeric address.
+     */
+    public static InetAddress parseNumericAddress(String address) {
+        return InetAddressUtils.parseNumericAddress(address);
+    }
+}
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 1b9a66c..80517ce 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -161,7 +162,7 @@
     /**
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public LinkProperties() {
     }
 
@@ -195,7 +196,7 @@
      * @param iface The name of the network interface used for this link.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public void setInterfaceName(String iface) {
         mIfaceName = iface;
         ArrayList<RouteInfo> newRoutes = new ArrayList<>(mRoutes.size());
@@ -346,7 +347,7 @@
      *                  object.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public void setLinkAddresses(Collection<LinkAddress> addresses) {
         mLinkAddresses.clear();
         for (LinkAddress address: addresses) {
@@ -392,7 +393,7 @@
      * @param dnsServers The {@link Collection} of DNS servers to set in this object.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public void setDnsServers(Collection<InetAddress> dnsServers) {
         mDnses.clear();
         for (InetAddress dnsServer: dnsServers) {
@@ -529,7 +530,7 @@
      *                domains to search when resolving host names on this link.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public void setDomains(String domains) {
         mDomains = domains;
     }
@@ -552,7 +553,7 @@
      * @param mtu The MTU to use for this link.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public void setMtu(int mtu) {
         mMtu = mtu;
     }
@@ -562,9 +563,7 @@
      * this will return 0.
      *
      * @return The mtu value set for this link.
-     * @hide
      */
-    @UnsupportedAppUsage
     public int getMtu() {
         return mMtu;
     }
@@ -613,7 +612,7 @@
      *
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public boolean addRoute(RouteInfo route) {
         if (route != null) {
             String routeIface = route.getInterface();
@@ -688,7 +687,7 @@
      * @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public void setHttpProxy(ProxyInfo proxy) {
         mHttpProxy = proxy;
     }
@@ -760,7 +759,7 @@
      * Clears this object to its initial state.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public void clear() {
         mIfaceName = null;
         mLinkAddresses.clear();
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 0c44a56..1b44c92 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -931,7 +931,7 @@
      * Returns a transport-specific information container. The application may cast this
      * container to a concrete sub-class based on its knowledge of the network request. The
      * application should be able to deal with a {@code null} return value or an invalid case,
-     * e.g. use {@code instanceof} operation to verify expected type.
+     * e.g. use {@code instanceof} operator to verify expected type.
      *
      * @return A concrete implementation of the {@link TransportInfo} class or null if not
      * available for the network.
@@ -1017,7 +1017,7 @@
      * @return The bearer-specific signal strength.
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public int getSignalStrength() {
         return mSignalStrength;
     }
@@ -1467,7 +1467,7 @@
             appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities,
                     NetworkCapabilities::capabilityNameOf, "&");
         }
-        if (0 != mNetworkCapabilities) {
+        if (0 != mUnwantedNetworkCapabilities) {
             sb.append(" Unwanted: ");
             appendStringRepresentationOfBitMaskToStringBuilder(sb, mUnwantedNetworkCapabilities,
                     NetworkCapabilities::capabilityNameOf, "&");
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 1a1d2d334..89d9961 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -28,7 +28,20 @@
  * Describes the status of a network interface.
  * <p>Use {@link ConnectivityManager#getActiveNetworkInfo()} to get an instance that represents
  * the current network connection.
+ *
+ * @deprecated Callers should instead use the {@link ConnectivityManager.NetworkCallback} API to
+ *             learn about connectivity changes, or switch to use
+ *             {@link ConnectivityManager#getNetworkCapabilities} or
+ *             {@link ConnectivityManager#getLinkProperties} to get information synchronously. Keep
+ *             in mind that while callbacks are guaranteed to be called for every event in order,
+ *             synchronous calls have no such constraints, and as such it is unadvisable to use the
+ *             synchronous methods inside the callbacks as they will often not offer a view of
+ *             networking that is consistent (that is: they may return a past or a future state with
+ *             respect to the event being processed by the callback). Instead, callers are advised
+ *             to only use the arguments of the callbacks, possibly memorizing the specific bits of
+ *             information they need to keep from one callback to another.
  */
+@Deprecated
 public class NetworkInfo implements Parcelable {
 
     /**
@@ -52,7 +65,10 @@
      * <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
      * <tr><td><code>BLOCKED</code></td><td><code>DISCONNECTED</code></td></tr>
      * </table>
+     *
+     * @deprecated See {@link NetworkInfo}.
      */
+    @Deprecated
     public enum State {
         CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
     }
@@ -61,7 +77,10 @@
      * The fine-grained state of a network connection. This level of detail
      * is probably of interest to few applications. Most should use
      * {@link android.net.NetworkInfo.State State} instead.
+     *
+     * @deprecated See {@link NetworkInfo}.
      */
+    @Deprecated
     public enum DetailedState {
         /** Ready to start data connection setup. */
         IDLE,
@@ -463,8 +482,10 @@
      * Set the extraInfo field.
      * @param extraInfo an optional {@code String} providing addditional network state
      * information passed up from the lower networking layers.
+     * @deprecated See {@link NetworkInfo#getExtraInfo}.
      * @hide
      */
+    @Deprecated
     public void setExtraInfo(String extraInfo) {
         synchronized (this) {
             this.mExtraInfo = extraInfo;
@@ -488,7 +509,10 @@
      * Report the extra information about the network state, if any was
      * provided by the lower networking layers.
      * @return the extra information, or null if not available
+     * @deprecated Use other services e.g. WifiManager to get additional information passed up from
+     *             the lower networking layers.
      */
+    @Deprecated
     public String getExtraInfo() {
         synchronized (this) {
             return mExtraInfo;
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 04b6b44..3b01b03 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.net.NetworkCapabilities.NetCapability;
 import android.net.NetworkCapabilities.Transport;
@@ -344,7 +345,7 @@
          * @param signalStrength the bearer-specific signal strength.
          * @hide
          */
-        @UnsupportedAppUsage
+        @SystemApi
         public Builder setSignalStrength(int signalStrength) {
             mNetworkCapabilities.setSignalStrength(signalStrength);
             return this;
diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java
new file mode 100644
index 0000000..82a4e31
--- /dev/null
+++ b/core/java/android/net/NetworkStack.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net;
+
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+/**
+ * Service used to communicate with the network stack, which is running in a separate module.
+ * @hide
+ */
+@SystemService(Context.NETWORK_STACK_SERVICE)
+public class NetworkStack {
+    private static final String TAG = NetworkStack.class.getSimpleName();
+
+    @NonNull
+    @GuardedBy("mPendingNetStackRequests")
+    private final ArrayList<NetworkStackRequest> mPendingNetStackRequests = new ArrayList<>();
+    @Nullable
+    @GuardedBy("mPendingNetStackRequests")
+    private INetworkStackConnector mConnector;
+
+    private interface NetworkStackRequest {
+        void onNetworkStackConnected(INetworkStackConnector connector);
+    }
+
+    public NetworkStack() { }
+
+    private class NetworkStackConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            registerNetworkStackService(service);
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            // TODO: crash/reboot the system ?
+            Slog.wtf(TAG, "Lost network stack connector");
+        }
+    };
+
+    private void registerNetworkStackService(@NonNull IBinder service) {
+        final INetworkStackConnector connector = INetworkStackConnector.Stub.asInterface(service);
+
+        ServiceManager.addService(Context.NETWORK_STACK_SERVICE, service, false /* allowIsolated */,
+                DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
+
+        final ArrayList<NetworkStackRequest> requests;
+        synchronized (mPendingNetStackRequests) {
+            requests = new ArrayList<>(mPendingNetStackRequests);
+            mPendingNetStackRequests.clear();
+            mConnector = connector;
+        }
+
+        for (NetworkStackRequest r : requests) {
+            r.onNetworkStackConnected(connector);
+        }
+    }
+
+    /**
+     * Start the network stack. Should be called only once on device startup.
+     *
+     * <p>This method will start the network stack either in the network stack process, or inside
+     * the system server on devices that do not support the network stack module. The network stack
+     * connector will then be delivered asynchronously to clients that requested it before it was
+     * started.
+     */
+    public void start(Context context) {
+        // Try to bind in-process if the library is available
+        IBinder connector = null;
+        try {
+            final Class service = Class.forName(
+                    "com.android.server.NetworkStackService",
+                    true /* initialize */,
+                    context.getClassLoader());
+            connector = (IBinder) service.getMethod("makeConnector").invoke(null);
+        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+            Slog.wtf(TAG, "Could not create network stack connector from NetworkStackService");
+            // TODO: crash/reboot system here ?
+            return;
+        } catch (ClassNotFoundException e) {
+            // Normal behavior if stack is provided by the app: fall through
+        }
+
+        // In-process network stack. Add the service to the service manager here.
+        if (connector != null) {
+            registerNetworkStackService(connector);
+            return;
+        }
+        // Start the network stack process. The service will be added to the service manager in
+        // NetworkStackConnection.onServiceConnected().
+        final Intent intent = new Intent(INetworkStackConnector.class.getName());
+        final ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0);
+        intent.setComponent(comp);
+
+        if (comp == null || !context.bindServiceAsUser(intent, new NetworkStackConnection(),
+                Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) {
+            Slog.wtf(TAG,
+                    "Could not bind to network stack in-process, or in app with " + intent);
+            // TODO: crash/reboot system server if no network stack after a timeout ?
+        }
+    }
+
+    // TODO: use this method to obtain the connector when implementing network stack operations
+    private void requestConnector(@NonNull NetworkStackRequest request) {
+        // TODO: PID check.
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            // Don't even attempt to obtain the connector and give a nice error message
+            throw new SecurityException(
+                    "Only the system server should try to bind to the network stack.");
+        }
+
+        final INetworkStackConnector connector;
+        synchronized (mPendingNetStackRequests) {
+            connector = mConnector;
+            if (connector == null) {
+                mPendingNetStackRequests.add(request);
+                return;
+            }
+        }
+
+        request.onNetworkStackConnected(connector);
+    }
+}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 34e9476..c0aa4a6 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -17,6 +17,7 @@
 package android.net;
 
 import android.annotation.UnsupportedAppUsage;
+import android.os.Build;
 import android.os.Parcel;
 import android.util.Log;
 import android.util.Pair;
@@ -294,8 +295,10 @@
      * @param addrString
      * @return the InetAddress
      * @hide
+     * @deprecated Use {@link InetAddresses#parseNumericAddress(String)}, if possible.
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+    @Deprecated
     public static InetAddress numericToInetAddress(String addrString)
             throws IllegalArgumentException {
         return InetAddress.parseNumericAddress(addrString);
diff --git a/core/java/android/net/TrafficStats.java b/core/java/android/net/TrafficStats.java
index 1b22911..bbf8f97 100644
--- a/core/java/android/net/TrafficStats.java
+++ b/core/java/android/net/TrafficStats.java
@@ -274,7 +274,6 @@
      * Changes only take effect during subsequent calls to
      * {@link #tagSocket(Socket)}.
      */
-    @SystemApi
     @SuppressLint("Doclava125")
     public static void setThreadStatsUid(int uid) {
         NetworkManagementSocketTagger.setThreadSocketStatsUid(uid);
@@ -313,7 +312,6 @@
      *
      * @see #setThreadStatsUid(int)
      */
-    @SystemApi
     @SuppressLint("Doclava125")
     public static void clearThreadStatsUid() {
         NetworkManagementSocketTagger.setThreadSocketStatsUid(-1);
@@ -333,6 +331,14 @@
 
     /**
      * Remove any statistics parameters from the given {@link Socket}.
+     * <p>
+     * In Android 8.1 (API level 27) and lower, a socket is automatically
+     * untagged when it's sent to another process using binder IPC with a
+     * {@code ParcelFileDescriptor} container. In Android 9.0 (API level 28)
+     * and higher, the socket tag is kept when the socket is sent to another
+     * process using binder IPC. You can mimic the previous behavior by
+     * calling {@code untagSocket()} before sending the socket to another
+     * process.
      */
     public static void untagSocket(Socket socket) throws SocketException {
         SocketTagger.get().untag(socket);
diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java
index f9b6dfc..280dad0 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -16,7 +16,6 @@
 
 package android.net.http;
 
-import android.annotation.SystemApi;
 import android.security.net.config.UserCertificateSource;
 
 import com.android.org.conscrypt.TrustManagerImpl;
@@ -133,7 +132,6 @@
      * Returns {@code true} if the TrustManager uses the same trust configuration for the provided
      * hostnames.
      */
-    @SystemApi
     public boolean isSameTrustConfiguration(String hostname1, String hostname2) {
         if (mIsSameTrustConfiguration == null) {
             return true;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
old mode 100644
new mode 100755
index 9188894..6de5759
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -628,7 +628,8 @@
          * October 2013: Android 4.4, KitKat, another tasty treat.
          *
          * <p>Applications targeting this or a later release will get these
-         * new changes in behavior:</p>
+         * new changes in behavior. For more information about this release, see the
+         * <a href="/about/versions/kitkat/">Android KitKat overview</a>.</p>
          * <ul>
          * <li> The default result of
          * {@link android.preference.PreferenceActivity#isValidFragment(String)
@@ -678,7 +679,8 @@
          * November 2014: Lollipop.  A flat one with beautiful shadows.  But still tasty.
          *
          * <p>Applications targeting this or a later release will get these
-         * new changes in behavior:</p>
+         * new changes in behavior.  For more information about this release, see the
+         * <a href="/about/versions/lollipop/">Android Lollipop overview</a>.</p>
          * <ul>
          * <li> {@link android.content.Context#bindService Context.bindService} now
          * requires an explicit Intent, and will throw an exception if given an implicit
@@ -707,6 +709,8 @@
 
         /**
          * March 2015: Lollipop with an extra sugar coating on the outside!
+         * For more information about this release, see the
+         * <a href="/about/versions/android-5.1">Android 5.1 APIs</a>.
          */
         public static final int LOLLIPOP_MR1 = 22;
 
@@ -714,7 +718,8 @@
          * M is for Marshmallow!
          *
          * <p>Applications targeting this or a later release will get these
-         * new changes in behavior:</p>
+         * new changes in behavior. For more information about this release, see the
+         * <a href="/about/versions/marshmallow/">Android 6.0 Marshmallow overview</a>.</p>
          * <ul>
          * <li> Runtime permissions.  Dangerous permissions are no longer granted at
          * install time, but must be requested by the application at runtime through
@@ -745,7 +750,8 @@
          * N is for Nougat.
          *
          * <p>Applications targeting this or a later release will get these
-         * new changes in behavior:</p>
+         * new changes in behavior. For more information about this release, see
+         * the <a href="/about/versions/nougat/">Android Nougat overview</a>.</p>
          * <ul>
          * <li> {@link android.app.DownloadManager.Request#setAllowedNetworkTypes
          * DownloadManager.Request.setAllowedNetworkTypes}
@@ -795,7 +801,9 @@
         public static final int N = 24;
 
         /**
-         * N MR1: Nougat++.
+         * N MR1: Nougat++. For more information about this release, see
+         * <a href="/about/versions/nougat/android-7.1">Android 7.1 for
+         * Developers</a>.
          */
         public static final int N_MR1 = 25;
 
@@ -803,7 +811,8 @@
          * O.
          *
          * <p>Applications targeting this or a later release will get these
-         * new changes in behavior:</p>
+         * new changes in behavior. For more information about this release, see
+         * the <a href="/about/versions/oreo/">Android Oreo overview</a>.</p>
          * <ul>
          * <li><a href="{@docRoot}about/versions/oreo/background.html">Background execution limits</a>
          * are applied to the application.</li>
@@ -892,13 +901,16 @@
          * O MR1.
          *
          * <p>Applications targeting this or a later release will get these
-         * new changes in behavior:</p>
+         * new changes in behavior. For more information about this release, see
+         * <a href="/about/versions/oreo/android-8.1">Android 8.1 features and
+         * APIs</a>.</p>
          * <ul>
          * <li>Apps exporting and linking to apk shared libraries must explicitly
          * enumerate all signing certificates in a consistent order.</li>
          * <li>{@link android.R.attr#screenOrientation} can not be used to request a fixed
          * orientation if the associated activity is not fullscreen and opaque.</li>
          * </ul>
+         *
          */
         public static final int O_MR1 = 27;
 
@@ -906,7 +918,8 @@
          * P.
          *
          * <p>Applications targeting this or a later release will get these
-         * new changes in behavior:</p>
+         * new changes in behavior. For more information about this release, see the
+         * <a href="/about/versions/pie/">Android 9 Pie overview</a>.</p>
          * <ul>
          * <li>{@link android.app.Service#startForeground Service.startForeground} requires
          * that apps hold the permission
@@ -914,6 +927,7 @@
          * <li>{@link android.widget.LinearLayout} will always remeasure weighted children,
          * even if there is no excess space.</li>
          * </ul>
+         *
          */
         public static final int P = 28;
 
@@ -1113,7 +1127,8 @@
      * null (if, for instance, the radio is not currently on).
      */
     public static String getRadioVersion() {
-        return SystemProperties.get(TelephonyProperties.PROPERTY_BASEBAND_VERSION, null);
+        String propVal = SystemProperties.get(TelephonyProperties.PROPERTY_BASEBAND_VERSION);
+        return TextUtils.isEmpty(propVal) ? null : propVal;
     }
 
     private static String getString(String property) {
diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java
index 228fe7a..3de3494 100644
--- a/core/java/android/os/HwBinder.java
+++ b/core/java/android/os/HwBinder.java
@@ -32,10 +32,7 @@
     /**
      * Create and initialize a HwBinder object and the native objects
      * used to allow this to participate in hwbinder transactions.
-     *
-     * @hide
      */
-    @SystemApi
     public HwBinder() {
         native_setup();
 
@@ -44,7 +41,6 @@
                 mNativeContext);
     }
 
-    /** @hide */
     @Override
     public final native void transact(
             int code, HwParcel request, HwParcel reply, int flags)
@@ -57,10 +53,7 @@
      * @param request parceled transaction
      * @param reply object to parcel reply into
      * @param flags transaction flags to be chosen by wire protocol
-     *
-     * @hide
      */
-    @SystemApi
     public abstract void onTransact(
             int code, HwParcel request, HwParcel reply, int flags)
         throws RemoteException;
@@ -69,9 +62,7 @@
      * Registers this service with the hwservicemanager.
      *
      * @param serviceName instance name of the service
-     * @hide
      */
-    @SystemApi
     public native final void registerService(String serviceName)
         throws RemoteException;
 
@@ -81,9 +72,7 @@
      * @param iface fully-qualified interface name for example foo.bar@1.3::IBaz
      * @param serviceName the instance name of the service for example default.
      * @throws NoSuchElementException when the service is unavailable
-     * @hide
      */
-    @SystemApi
     public static final IHwBinder getService(
             String iface,
             String serviceName)
@@ -96,9 +85,7 @@
      * @param serviceName the instance name of the service for example default.
      * @param retry whether to wait for the service to start if it's not already started
      * @throws NoSuchElementException when the service is unavailable
-     * @hide
      */
-    @SystemApi
     public static native final IHwBinder getService(
             String iface,
             String serviceName,
@@ -112,9 +99,7 @@
      * @param maxThreads total number of threads to create (includes this thread if
      *     callerWillJoin is true)
      * @param callerWillJoin whether joinRpcThreadpool will be called in advance
-     * @hide
      */
-    @SystemApi
     public static native final void configureRpcThreadpool(
             long maxThreads, boolean callerWillJoin);
 
@@ -124,10 +109,7 @@
      * a threadpool with callerWillJoin true and then registering
      * the provided service if this thread doesn't need to do
      * anything else.
-     *
-     * @hide
      */
-    @SystemApi
     public static native final void joinRpcThreadpool();
 
     // Returns address of the "freeFunction".
@@ -155,10 +137,7 @@
      * - tries to enable atracing (if enabled)
      * - tries to enable coverage dumps (if running in VTS)
      * - tries to enable record and replay (if running in VTS)
-     *
-     * @hide
      */
-    @SystemApi
     public static void enableInstrumentation() {
         native_report_sysprop_change();
     }
diff --git a/core/java/android/os/IHwBinder.java b/core/java/android/os/IHwBinder.java
index fbdf27e..249eb3a 100644
--- a/core/java/android/os/IHwBinder.java
+++ b/core/java/android/os/IHwBinder.java
@@ -28,10 +28,7 @@
      * @param request parceled transaction
      * @param reply object to parcel reply into
      * @param flags transaction flags to be chosen by wire protocol
-     *
-     * @hide
      */
-    @SystemApi
     public void transact(
             int code, HwParcel request, HwParcel reply, int flags)
         throws RemoteException;
@@ -40,23 +37,19 @@
      * Return as IHwInterface instance only if this implements descriptor.
      *
      * @param descriptor for example foo.bar@1.0::IBaz
-     * @hide
      */
-    @SystemApi
     public IHwInterface queryLocalInterface(String descriptor);
 
     /**
      * Interface for receiving a callback when the process hosting a service
      * has gone away.
      */
-    @SystemApi
     public interface DeathRecipient {
         /**
          * Callback for a registered process dying.
          *
          * @param cookie cookie this death recipient was registered with.
          */
-        @SystemApi
         public void serviceDied(long cookie);
     }
 
@@ -67,13 +60,11 @@
      * @param recipient callback object to be called on object death.
      * @param cookie value to be given to callback on object death.
      */
-    @SystemApi
     public boolean linkToDeath(DeathRecipient recipient, long cookie);
     /**
      * Unregisters the death recipient from this binder.
      *
      * @param recipient callback to no longer recieve death notifications on this binder.
      */
-    @SystemApi
     public boolean unlinkToDeath(DeathRecipient recipient);
 }
diff --git a/core/java/android/os/IHwInterface.java b/core/java/android/os/IHwInterface.java
index 1d9e2b0..f9edd5b 100644
--- a/core/java/android/os/IHwInterface.java
+++ b/core/java/android/os/IHwInterface.java
@@ -23,6 +23,5 @@
     /**
      * @return the binder object that corresponds to this interface.
      */
-    @SystemApi
     public IHwBinder asBinder();
 }
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index c9c4205..fdd7488 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -18,7 +18,6 @@
 package android.os;
 
 import android.net.InterfaceConfiguration;
-import android.net.INetd;
 import android.net.INetworkManagementEventObserver;
 import android.net.ITetheringStatsProvider;
 import android.net.Network;
@@ -47,11 +46,6 @@
     void unregisterObserver(INetworkManagementEventObserver obs);
 
     /**
-     * Retrieve an INetd to talk to netd.
-     */
-    INetd getNetdService();
-
-    /**
      * Returns a list of currently known network interfaces
      */
     String[] listInterfaces();
@@ -396,7 +390,7 @@
     /**
      * Setup a new VPN.
      */
-    void createVirtualNetwork(int netId, boolean hasDNS, boolean secure);
+    void createVirtualNetwork(int netId, boolean secure);
 
     /**
      * Remove a network.
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index c3f60a3..47659a2 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -349,7 +349,7 @@
     }
 
     /**
-     * Retrieve the a {@link android.os.Handler Handler} implementation that
+     * Retrieve the {@link android.os.Handler Handler} implementation that
      * will receive this message. The object must implement
      * {@link android.os.Handler#handleMessage(android.os.Message)
      * Handler.handleMessage()}. Each Handler has its own name-space for
diff --git a/core/java/android/os/NativeHandle.java b/core/java/android/os/NativeHandle.java
index fbecc8e..f7ffc37 100644
--- a/core/java/android/os/NativeHandle.java
+++ b/core/java/android/os/NativeHandle.java
@@ -16,6 +16,8 @@
 
 package android.os;
 
+import static android.system.OsConstants.F_DUPFD_CLOEXEC;
+
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.system.ErrnoException;
@@ -108,7 +110,10 @@
         FileDescriptor[] fds = new FileDescriptor[mFds.length];
         try {
             for (int i = 0; i < mFds.length; i++) {
-                fds[i] = Os.dup(mFds[i]);
+                FileDescriptor newFd = new FileDescriptor();
+                int fdint = Os.fcntlInt(mFds[i], F_DUPFD_CLOEXEC, 0);
+                newFd.setInt$(fdint);
+                fds[i] = newFd;
             }
         } catch (ErrnoException e) {
             e.rethrowAsIOException();
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index c7ebc89..210404c 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -834,11 +834,19 @@
             return;
         }
         Set<Map.Entry<String,Object>> entries = val.entrySet();
-        writeInt(entries.size());
+        int size = entries.size();
+        writeInt(size);
+
         for (Map.Entry<String,Object> e : entries) {
             writeValue(e.getKey());
             writeValue(e.getValue());
+            size--;
         }
+
+        if (size != 0) {
+            throw new BadParcelableException("Map size does not match number of entries!");
+        }
+
     }
 
     /**
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index d0cdf6e..f2837ecb 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -174,6 +174,12 @@
      */
     public static final int SE_UID = 1068;
 
+    /**
+     * Defines the UID/GID for the NetworkStack app.
+     * @hide
+     */
+    public static final int NETWORK_STACK_UID = 1073;
+
     /** {@hide} */
     public static final int NOBODY_UID = 9999;
 
diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java
index d4d3dc8..7b3ea57 100644
--- a/core/java/android/os/StatsLogEventWrapper.java
+++ b/core/java/android/os/StatsLogEventWrapper.java
@@ -65,11 +65,17 @@
     public static final Parcelable.Creator<StatsLogEventWrapper> CREATOR = new
             Parcelable.Creator<StatsLogEventWrapper>() {
                 public StatsLogEventWrapper createFromParcel(Parcel in) {
-                    return new StatsLogEventWrapper(in);
+                    android.util.EventLog.writeEvent(0x534e4554, "112550251",
+                            android.os.Binder.getCallingUid(), "");
+                    // Purposefully leaving this method not implemented.
+                    throw new RuntimeException("Not implemented");
                 }
 
                 public StatsLogEventWrapper[] newArray(int size) {
-                    return new StatsLogEventWrapper[size];
+                    android.util.EventLog.writeEvent(0x534e4554, "112550251",
+                            android.os.Binder.getCallingUid(), "");
+                    // Purposefully leaving this method not implemented.
+                    throw new RuntimeException("Not implemented");
                 }
             };
 
@@ -120,10 +126,6 @@
         mStorage.write(bytes, 0, bytes.length);
     }
 
-    private StatsLogEventWrapper(Parcel in) {
-        readFromParcel(in);
-    }
-
     /**
      * Writes the stored fields to a byte array. Will first write a new-line character to denote
      * END_LIST before writing contents to byte array.
@@ -134,13 +136,6 @@
     }
 
     /**
-     * Not implemented.
-     */
-    public void readFromParcel(Parcel in) {
-        // Not needed since this java class is for sending to statsd only.
-    }
-
-    /**
      * Boilerplate for Parcel.
      */
     public int describeContents() {
diff --git a/core/java/android/os/SystemUpdateManager.java b/core/java/android/os/SystemUpdateManager.java
index ce3e2259..9146731 100644
--- a/core/java/android/os/SystemUpdateManager.java
+++ b/core/java/android/os/SystemUpdateManager.java
@@ -34,62 +34,51 @@
     private static final String TAG = "SystemUpdateManager";
 
     /** The status key of the system update info, expecting an int value. */
-    @SystemApi
     public static final String KEY_STATUS = "status";
 
     /** The title of the current update, expecting a String value. */
-    @SystemApi
     public static final String KEY_TITLE = "title";
 
     /** Whether it is a security update, expecting a boolean value. */
-    @SystemApi
     public static final String KEY_IS_SECURITY_UPDATE = "is_security_update";
 
     /** The build fingerprint after installing the current update, expecting a String value. */
-    @SystemApi
     public static final String KEY_TARGET_BUILD_FINGERPRINT = "target_build_fingerprint";
 
     /** The security patch level after installing the current update, expecting a String value. */
-    @SystemApi
     public static final String KEY_TARGET_SECURITY_PATCH_LEVEL = "target_security_patch_level";
 
     /**
      * The KEY_STATUS value that indicates there's no update status info available.
      */
-    @SystemApi
     public static final int STATUS_UNKNOWN = 0;
 
     /**
      * The KEY_STATUS value that indicates there's no pending update.
      */
-    @SystemApi
     public static final int STATUS_IDLE = 1;
 
     /**
      * The KEY_STATUS value that indicates an update is available for download, but pending user
      * approval to start.
      */
-    @SystemApi
     public static final int STATUS_WAITING_DOWNLOAD = 2;
 
     /**
      * The KEY_STATUS value that indicates an update is in progress (i.e. downloading or installing
      * has started).
      */
-    @SystemApi
     public static final int STATUS_IN_PROGRESS = 3;
 
     /**
      * The KEY_STATUS value that indicates an update is available for install.
      */
-    @SystemApi
     public static final int STATUS_WAITING_INSTALL = 4;
 
     /**
      * The KEY_STATUS value that indicates an update will be installed after a reboot. This applies
      * to both of A/B and non-A/B OTAs.
      */
-    @SystemApi
     public static final int STATUS_WAITING_REBOOT = 5;
 
     private final ISystemUpdateManager mService;
@@ -110,7 +99,6 @@
      *
      * @throws SecurityException if the caller is not allowed to read the info.
      */
-    @SystemApi
     @RequiresPermission(anyOf = {
             android.Manifest.permission.READ_SYSTEM_UPDATE_INFO,
             android.Manifest.permission.RECOVERY,
@@ -137,7 +125,6 @@
      * @throws IllegalArgumentException if @link #KEY_STATUS} does not exist.
      * @throws SecurityException if the caller is not allowed to update the info.
      */
-    @SystemApi
     @RequiresPermission(android.Manifest.permission.RECOVERY)
     public void updateSystemUpdateInfo(PersistableBundle infoBundle) {
         if (infoBundle == null || !infoBundle.containsKey(KEY_STATUS)) {
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index 24c9c91..8f2826c 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -54,7 +54,6 @@
      * Error code from the update engine. Values must agree with the ones in
      * system/update_engine/common/error_code.h.
      */
-    @SystemApi
     public static final class ErrorCodeConstants {
         public static final int SUCCESS = 0;
         public static final int ERROR = 1;
@@ -74,7 +73,6 @@
      * Update status code from the update engine. Values must agree with the
      * ones in system/update_engine/client_library/include/update_engine/update_status.h.
      */
-    @SystemApi
     public static final class UpdateStatusConstants {
         public static final int IDLE = 0;
         public static final int CHECKING_FOR_UPDATE = 1;
@@ -95,7 +93,6 @@
     /**
      * Creates a new instance.
      */
-    @SystemApi
     public UpdateEngine() {
         mUpdateEngine = IUpdateEngine.Stub.asInterface(
                 ServiceManager.getService(UPDATE_ENGINE_SERVICE));
@@ -106,7 +103,6 @@
      * status change, and when the update completes. A handler can be supplied
      * to control which thread runs the callback, or null.
      */
-    @SystemApi
     public boolean bind(final UpdateEngineCallback callback, final Handler handler) {
         synchronized (mUpdateEngineCallbackLock) {
             mUpdateEngineCallback = new IUpdateEngineCallback.Stub() {
@@ -150,7 +146,6 @@
     /**
      * Equivalent to {@code bind(callback, null)}.
      */
-    @SystemApi
     public boolean bind(final UpdateEngineCallback callback) {
         return bind(callback, null);
     }
@@ -183,7 +178,6 @@
      * };
      * </pre>
      */
-    @SystemApi
     public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) {
         try {
             mUpdateEngine.applyPayload(url, offset, size, headerKeyValuePairs);
@@ -201,7 +195,6 @@
      * <p>See {@link #suspend} for a way to temporarily stop an in-progress
      * update with the ability to resume it later.
      */
-    @SystemApi
     public void cancel() {
         try {
             mUpdateEngine.cancel();
@@ -214,7 +207,6 @@
      * Suspends an in-progress update. This can be undone by calling
      * {@link #resume}.
      */
-    @SystemApi
     public void suspend() {
         try {
             mUpdateEngine.suspend();
@@ -226,7 +218,6 @@
     /**
      * Resumes a suspended update.
      */
-    @SystemApi
     public void resume() {
         try {
             mUpdateEngine.resume();
@@ -244,7 +235,6 @@
      * {@code UPDATED_NEED_REBOOT}, so your callback can remove any outstanding
      * notification that rebooting into the new system is possible.
      */
-    @SystemApi
     public void resetStatus() {
         try {
             mUpdateEngine.resetStatus();
@@ -256,7 +246,6 @@
     /**
      * Unbinds the last bound callback function.
      */
-    @SystemApi
     public boolean unbind() {
         synchronized (mUpdateEngineCallbackLock) {
             if (mUpdateEngineCallback == null) {
@@ -281,7 +270,6 @@
      * @param payloadMetadataFilename the location of the metadata without the
      * {@code file://} prefix.
      */
-    @SystemApi
     public boolean verifyPayloadMetadata(String payloadMetadataFilename) {
         try {
             return mUpdateEngine.verifyPayloadApplicable(payloadMetadataFilename);
diff --git a/core/java/android/os/UpdateEngineCallback.java b/core/java/android/os/UpdateEngineCallback.java
index afff60a..f07294e 100644
--- a/core/java/android/os/UpdateEngineCallback.java
+++ b/core/java/android/os/UpdateEngineCallback.java
@@ -37,7 +37,6 @@
      * be one of the values from {@link UpdateEngine.UpdateStatusConstants},
      * and {@code percent} will be valid [TODO: in which cases?].
      */
-    @SystemApi
     public abstract void onStatusUpdate(int status, float percent);
 
     /**
@@ -45,6 +44,5 @@
      * unsuccessfully. The value of {@code errorCode} will be one of the
      * values from {@link UpdateEngine.ErrorCodeConstants}.
      */
-    @SystemApi
     public abstract void onPayloadApplicationComplete(int errorCode);
 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index d072d02..6b59279 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -52,6 +52,7 @@
 import android.os.ServiceManager.ServiceNotFoundException;
 import android.os.SystemProperties;
 import android.provider.Settings;
+import android.sysprop.VoldProperties;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -1465,7 +1466,7 @@
      * framework, so no service needs to check for changes during their lifespan
      */
     public static boolean isBlockEncrypting() {
-        final String state = SystemProperties.get("vold.encrypt_progress", "");
+        final String state = VoldProperties.encrypt_progress().orElse("");
         return !"".equalsIgnoreCase(state);
     }
 
@@ -1481,7 +1482,7 @@
      * framework, so no service needs to check for changes during their lifespan
      */
     public static boolean inCryptKeeperBounce() {
-        final String status = SystemProperties.get("vold.decrypt");
+        final String status = VoldProperties.decrypt().orElse("");
         return "trigger_restart_min_framework".equals(status);
     }
 
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index d163909..8ed2605 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -80,7 +80,7 @@
  * <li>On a small screen it may display only the headers as a single list when first launched.
  * Selecting one of the header items will only show the PreferenceFragment of that header (on
  * Android N and lower a new Activity is launched).
- * <li>On a large screen in may display both the headers and current PreferenceFragment together as
+ * <li>On a large screen it may display both the headers and current PreferenceFragment together as
  * panes. Selecting a header item switches to showing the correct PreferenceFragment for that item.
  * </ul>
  *
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 258c9a9..e6f8a56 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10682,6 +10682,15 @@
         public static final String ACTIVITY_MANAGER_CONSTANTS = "activity_manager_constants";
 
         /**
+         * Feature flag to enable or disable the activity starts logging feature.
+         * Type: int (0 for false, 1 for true)
+         * Default: 0
+         * @hide
+         */
+        public static final String ACTIVITY_STARTS_LOGGING_ENABLED
+                = "activity_starts_logging_enabled";
+
+        /**
          * App ops specific settings.
          * This is encoded as a key=value list, separated by commas. Ex:
          *
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index 5211767..f8408be 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -33,8 +33,13 @@
 import java.util.regex.Pattern;
 
 /**
- * A dataset object represents a group of fields (key / value pairs) used to autofill parts of a
- * screen.
+ * <p>A <code>Dataset</code> object represents a group of fields (key / value pairs) used
+ * to autofill parts of a screen.
+ *
+ * <p>For more information about the role of datasets in the autofill workflow, read
+ * <a href="/guide/topics/text/autofill-services">Build autofill services</a> and the
+ * <code><a href="/reference/android/service/autofill/AutofillService">AutofillService</a></code>
+ * documentation.
  *
  * <a name="BasicUsage"></a>
  * <h3>Basic usage</h3>
@@ -88,10 +93,6 @@
  *   <li>All other datasets are hidden.
  * </ol>
  *
- * <a name="MoreInfo"></a>
- * <h3>More information</h3>
- * <p>See {@link android.service.autofill.AutofillService} for more information and examples about
- * the role of datasets in the autofill workflow.
  */
 public final class Dataset implements Parcelable {
 
diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java
index 0257891..1695c13 100644
--- a/core/java/android/service/autofill/FillCallback.java
+++ b/core/java/android/service/autofill/FillCallback.java
@@ -21,8 +21,11 @@
 import android.os.RemoteException;
 
 /**
- * Handles autofill requests from the {@link AutofillService} into the {@link Activity} being
- * autofilled.
+ * <p><code>FillCallback</code> handles autofill requests from the {@link AutofillService} into
+ * the {@link Activity} being autofilled.
+ *
+ * <p>To learn about using Autofill services in your app, read
+ * <a href="/guide/topics/text/autofill-services">Build autofill services</a>.
  */
 public final class FillCallback {
     private final IFillCallback mCallback;
diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java
index e930f40..568ca0f 100644
--- a/core/java/android/service/carrier/CarrierIdentifier.java
+++ b/core/java/android/service/carrier/CarrierIdentifier.java
@@ -71,10 +71,8 @@
      * @param gid2 group id level 2
      * @param carrierid carrier unique identifier {@link TelephonyManager#getSimCarrierId()}, used
      *                  to uniquely identify the carrier and look up the carrier configurations.
-     * @param preciseCarrierId precise carrier identifier {@link TelephonyManager#getSimPreciseCarrierId()}
-     * @hide
-     *
-     * TODO: expose this to public API
+     * @param preciseCarrierId precise carrier identifier
+     * {@link TelephonyManager#getSimPreciseCarrierId()}
      */
     public CarrierIdentifier(String mcc, String mnc, @Nullable String spn,
                              @Nullable String imsi, @Nullable String gid1, @Nullable String gid2,
@@ -155,16 +153,16 @@
     }
 
     /**
-     * Get the carrier id {@link TelephonyManager#getSimCarrierId() }
-     * @hide
+     * Returns the carrier id.
+     * @see TelephonyManager#getSimCarrierId()
      */
     public int getCarrierId() {
         return mCarrierId;
     }
 
     /**
-     * Get the precise carrier id {@link TelephonyManager#getSimPreciseCarrierId()}
-     * @hide
+     * Returns the precise carrier id.
+     * @see TelephonyManager#getSimPreciseCarrierId()
      */
     public int getPreciseCarrierId() {
         return mPreciseCarrierId;
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
index b6c6bdc..af7e93e 100644
--- a/core/java/android/service/notification/Condition.java
+++ b/core/java/android/service/notification/Condition.java
@@ -17,7 +17,6 @@
 package android.service.notification;
 
 import android.annotation.IntDef;
-import android.annotation.SystemApi;
 import android.content.Context;
 import android.net.Uri;
 import android.os.Parcel;
@@ -35,7 +34,6 @@
  */
 public final class Condition implements Parcelable {
 
-    @SystemApi
     public static final String SCHEME = "condition";
 
     /** @hide */
@@ -59,14 +57,10 @@
      */
     public static final int STATE_TRUE = 1;
 
-    @SystemApi
     public static final int STATE_UNKNOWN = 2;
-    @SystemApi
     public static final int STATE_ERROR = 3;
 
-    @SystemApi
     public static final int FLAG_RELEVANT_NOW = 1 << 0;
-    @SystemApi
     public static final int FLAG_RELEVANT_ALWAYS = 1 << 1;
 
     /**
@@ -81,9 +75,7 @@
      */
     public final String summary;
 
-    @SystemApi
     public final String line1;
-    @SystemApi
     public final String line2;
 
     /**
@@ -94,9 +86,7 @@
     @State
     public final int state;
 
-    @SystemApi
     public final int flags;
-    @SystemApi
     public final int icon;
 
     /**
@@ -108,7 +98,6 @@
         this(id, summary, "", "", -1, state, FLAG_RELEVANT_ALWAYS);
     }
 
-    @SystemApi
     public Condition(Uri id, String summary, String line1, String line2, int icon,
             int state, int flags) {
         if (id == null) throw new IllegalArgumentException("id is required");
@@ -151,14 +140,14 @@
     @Override
     public String toString() {
         return new StringBuilder(Condition.class.getSimpleName()).append('[')
-            .append("id=").append(id)
-            .append(",summary=").append(summary)
-            .append(",line1=").append(line1)
-            .append(",line2=").append(line2)
-            .append(",icon=").append(icon)
-            .append(",state=").append(stateToString(state))
-            .append(",flags=").append(flags)
-            .append(']').toString();
+                .append("state=").append(stateToString(state))
+                .append(",id=").append(id)
+                .append(",summary=").append(summary)
+                .append(",line1=").append(line1)
+                .append(",line2=").append(line2)
+                .append(",icon=").append(icon)
+                .append(",flags=").append(flags)
+                .append(']').toString();
     }
 
     /** @hide */
@@ -177,7 +166,6 @@
         proto.end(token);
     }
 
-    @SystemApi
     public static String stateToString(int state) {
         if (state == STATE_FALSE) return "STATE_FALSE";
         if (state == STATE_TRUE) return "STATE_TRUE";
@@ -186,7 +174,6 @@
         throw new IllegalArgumentException("state is invalid: " + state);
     }
 
-    @SystemApi
     public static String relevanceToString(int flags) {
         final boolean now = (flags & FLAG_RELEVANT_NOW) != 0;
         final boolean always = (flags & FLAG_RELEVANT_ALWAYS) != 0;
@@ -219,7 +206,6 @@
         return 0;
     }
 
-    @SystemApi
     public Condition copy() {
         final Parcel parcel = Parcel.obtain();
         try {
@@ -231,14 +217,12 @@
         }
     }
 
-    @SystemApi
     public static Uri.Builder newId(Context context) {
         return new Uri.Builder()
                 .scheme(Condition.SCHEME)
                 .authority(context.getPackageName());
     }
 
-    @SystemApi
     public static boolean isValidId(Uri id, String pkg) {
         return id != null && SCHEME.equals(id.getScheme()) && pkg.equals(id.getAuthority());
     }
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index 6fc689a..5203c8f 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -17,7 +17,6 @@
 package android.service.notification;
 
 import android.annotation.SdkConstant;
-import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.app.ActivityManager;
 import android.app.INotificationManager;
@@ -107,7 +106,6 @@
      */
     abstract public void onConnected();
 
-    @SystemApi
     public void onRequestConditions(int relevance) {}
 
     /**
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index f6749ee..1af2e73 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -244,11 +244,29 @@
                 .append(",allowMessagesFrom=").append(sourceToString(allowMessagesFrom))
                 .append(",suppressedVisualEffects=").append(suppressedVisualEffects)
                 .append(",areChannelsBypassingDnd=").append(areChannelsBypassingDnd)
-                .append(",automaticRules=").append(automaticRules)
-                .append(",manualRule=").append(manualRule)
+                .append(",\nautomaticRules=").append(rulesToString())
+                .append(",\nmanualRule=").append(manualRule)
                 .append(']').toString();
     }
 
+    private String rulesToString() {
+        if (automaticRules.isEmpty()) {
+            return "{}";
+        }
+
+        StringBuilder buffer = new StringBuilder(automaticRules.size() * 28);
+        buffer.append('{');
+        for (int i = 0; i < automaticRules.size(); i++) {
+            if (i > 0) {
+                buffer.append(",\n");
+            }
+            Object value = automaticRules.valueAt(i);
+            buffer.append(value);
+        }
+        buffer.append('}');
+        return buffer.toString();
+    }
+
     private Diff diff(ZenModeConfig to) {
         final Diff d = new Diff();
         if (to == null) {
@@ -1014,10 +1032,10 @@
     @UnsupportedAppUsage
     public static ScheduleInfo tryParseScheduleConditionId(Uri conditionId) {
         final boolean isSchedule =  conditionId != null
-                && conditionId.getScheme().equals(Condition.SCHEME)
-                && conditionId.getAuthority().equals(ZenModeConfig.SYSTEM_AUTHORITY)
+                && Condition.SCHEME.equals(conditionId.getScheme())
+                && ZenModeConfig.SYSTEM_AUTHORITY.equals(conditionId.getAuthority())
                 && conditionId.getPathSegments().size() == 1
-                && conditionId.getPathSegments().get(0).equals(ZenModeConfig.SCHEDULE_PATH);
+                && ZenModeConfig.SCHEDULE_PATH.equals(conditionId.getPathSegments().get(0));
         if (!isSchedule) return null;
         final int[] start = tryParseHourAndMinute(conditionId.getQueryParameter("start"));
         final int[] end = tryParseHourAndMinute(conditionId.getQueryParameter("end"));
@@ -1120,10 +1138,10 @@
 
     public static EventInfo tryParseEventConditionId(Uri conditionId) {
         final boolean isEvent = conditionId != null
-                && conditionId.getScheme().equals(Condition.SCHEME)
-                && conditionId.getAuthority().equals(ZenModeConfig.SYSTEM_AUTHORITY)
+                && Condition.SCHEME.equals(conditionId.getScheme())
+                && ZenModeConfig.SYSTEM_AUTHORITY.equals(conditionId.getAuthority())
                 && conditionId.getPathSegments().size() == 1
-                && conditionId.getPathSegments().get(0).equals(EVENT_PATH);
+                && EVENT_PATH.equals(conditionId.getPathSegments().get(0));
         if (!isEvent) return null;
         final EventInfo rt = new EventInfo();
         rt.userId = tryParseInt(conditionId.getQueryParameter("userId"), UserHandle.USER_NULL);
@@ -1338,14 +1356,14 @@
         @Override
         public String toString() {
             return new StringBuilder(ZenRule.class.getSimpleName()).append('[')
-                    .append("enabled=").append(enabled)
+                    .append("id=").append(id)
+                    .append(",enabled=").append(String.valueOf(enabled).toUpperCase())
                     .append(",snoozing=").append(snoozing)
                     .append(",name=").append(name)
                     .append(",zenMode=").append(Global.zenModeToString(zenMode))
                     .append(",conditionId=").append(conditionId)
                     .append(",condition=").append(condition)
                     .append(",component=").append(component)
-                    .append(",id=").append(id)
                     .append(",creationTime=").append(creationTime)
                     .append(",enabler=").append(enabler)
                     .append(']').toString();
@@ -1477,7 +1495,7 @@
             final int N = lines.size();
             for (int i = 0; i < N; i++) {
                 if (i > 0) {
-                    sb.append(',');
+                    sb.append(",\n");
                 }
                 sb.append(lines.get(i));
             }
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index b461c0d..2417e59 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -80,7 +80,6 @@
      * {@link android.Manifest.permission#BIND_TEXTCLASSIFIER_SERVICE} permission so
      * that other applications can not abuse it.
      */
-    @SystemApi
     public static final String SERVICE_INTERFACE =
             "android.service.textclassifier.TextClassifierService";
 
@@ -371,9 +370,7 @@
      * Callbacks for TextClassifierService results.
      *
      * @param <T> the type of the result
-     * @hide
      */
-    @SystemApi
     public interface Callback<T> {
         /**
          * Returns the result.
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index dc07494..aa5ca35 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -23,32 +23,34 @@
 import libcore.util.EmptyArray;
 
 /**
- * SparseArrays map integers to Objects.  Unlike a normal array of Objects,
- * there can be gaps in the indices.  It is intended to be more memory efficient
- * than using a HashMap to map Integers to Objects, both because it avoids
+ * <code>SparseArray</code> maps integers to Objects and, unlike a normal array of Objects,
+ * its indices can contain gaps. <code>SparseArray</code> is intended to be more memory-efficient
+ * than a
+ * <a href="/reference/java/util/HashMap"><code>HashMap</code></a>, because it avoids
  * auto-boxing keys and its data structure doesn't rely on an extra entry object
  * for each mapping.
  *
  * <p>Note that this container keeps its mappings in an array data structure,
- * using a binary search to find keys.  The implementation is not intended to be appropriate for
+ * using a binary search to find keys. The implementation is not intended to be appropriate for
  * data structures
- * that may contain large numbers of items.  It is generally slower than a traditional
- * HashMap, since lookups require a binary search and adds and removes require inserting
- * and deleting entries in the array.  For containers holding up to hundreds of items,
- * the performance difference is not significant, less than 50%.</p>
+ * that may contain large numbers of items. It is generally slower than a
+ * <code>HashMap</code> because lookups require a binary search,
+ * and adds and removes require inserting
+ * and deleting entries in the array. For containers holding up to hundreds of items,
+ * the performance difference is less than 50%.
  *
  * <p>To help with performance, the container includes an optimization when removing
  * keys: instead of compacting its array immediately, it leaves the removed entry marked
- * as deleted.  The entry can then be re-used for the same key, or compacted later in
- * a single garbage collection step of all removed entries.  This garbage collection will
- * need to be performed at any time the array needs to be grown or the the map size or
- * entry values are retrieved.</p>
+ * as deleted. The entry can then be re-used for the same key or compacted later in
+ * a single garbage collection of all removed entries. This garbage collection
+ * must be performed whenever the array needs to be grown, or when the map size or
+ * entry values are retrieved.
  *
  * <p>It is possible to iterate over the items in this container using
  * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
- * <code>keyAt(int)</code> with ascending values of the index will return the
- * keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)</code>.</p>
+ * <code>keyAt(int)</code> with ascending values of the index returns the
+ * keys in ascending order. In the case of <code>valueAt(int)</code>, the
+ * values corresponding to the keys are returned in ascending order.
  */
 public class SparseArray<E> implements Cloneable {
     private static final Object DELETED = new Object();
@@ -337,7 +339,7 @@
 
     /**
      * Returns an index for which {@link #valueAt} would return the
-     * specified key, or a negative number if no keys map to the
+     * specified value, or a negative number if no keys map to the
      * specified value.
      * <p>Beware that this is a linear search, unlike lookups by key,
      * and that multiple keys can map to the same value and this will
@@ -361,7 +363,7 @@
 
     /**
      * Returns an index for which {@link #valueAt} would return the
-     * specified key, or a negative number if no keys map to the
+     * specified value, or a negative number if no keys map to the
      * specified value.
      * <p>Beware that this is a linear search, unlike lookups by key,
      * and that multiple keys can map to the same value and this will
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 496bc9f..5f80d31 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -325,6 +325,7 @@
      *
      * @hide
      */
+    @VisibleForTesting
     public static DisplayCutout fromBoundingRect(int left, int top, int right, int bottom) {
         Region r = Region.obtain();
         r.set(left, top, right, bottom);
@@ -422,8 +423,11 @@
         m.postTranslate(offsetX, 0);
         p.transform(m);
 
-        addToRegion(p, r);
+        final Rect tmpRect = new Rect();
+        toRectAndAddToRegion(p, r, tmpRect);
+        final int topInset = tmpRect.bottom;
 
+        final int bottomInset;
         if (bottomSpec != null) {
             final Path bottomPath;
             try {
@@ -436,10 +440,17 @@
             m.postTranslate(0, displayHeight);
             bottomPath.transform(m);
             p.addPath(bottomPath);
-            addToRegion(bottomPath, r);
+            toRectAndAddToRegion(bottomPath, r, tmpRect);
+            bottomInset = displayHeight - tmpRect.top;
+        } else {
+            bottomInset = 0;
         }
 
-        final Pair<Path, DisplayCutout> result = new Pair<>(p, fromBounds(r));
+        // Reuse tmpRect as the inset rect we store into the DisplayCutout instance.
+        tmpRect.set(0, topInset, 0, bottomInset);
+        final DisplayCutout cutout = new DisplayCutout(tmpRect, r, false /* copyArguments */);
+
+        final Pair<Path, DisplayCutout> result = new Pair<>(p, cutout);
         synchronized (CACHE_LOCK) {
             sCachedSpec = spec;
             sCachedDisplayWidth = displayWidth;
@@ -450,12 +461,11 @@
         return result;
     }
 
-    private static void addToRegion(Path p, Region r) {
+    private static void toRectAndAddToRegion(Path p, Region inoutRegion, Rect inoutRect) {
         final RectF rectF = new RectF();
-        final Rect rect = new Rect();
         p.computeBounds(rectF, false /* unused */);
-        rectF.round(rect);
-        r.op(rect, Op.UNION);
+        rectF.round(inoutRect);
+        inoutRegion.op(inoutRect, Op.UNION);
     }
 
     private static Region boundingRectsToRegion(List<Rect> rects) {
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 2e98d03..1dbe166 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -268,6 +268,13 @@
     public static final int FX_SURFACE_DIM = 0x00020000;
 
     /**
+     * Surface creation flag: Creates a container surface.
+     * This surface will have no buffers and will only be used
+     * as a container for other surfaces, or for its InputInfo.
+     */
+    public static final int FX_SURFACE_CONTAINER = 0x00080000;
+
+    /**
      * Mask used for FX values above.
      *
      */
@@ -523,14 +530,39 @@
          */
         public Builder setColorLayer(boolean isColorLayer) {
             if (isColorLayer) {
-                mFlags |= FX_SURFACE_DIM;
+                setFlags(FX_SURFACE_DIM, FX_SURFACE_MASK);
             } else {
-                mFlags &= ~FX_SURFACE_DIM;
+                setBufferLayer();
             }
             return this;
         }
 
         /**
+         * Indicates whether a 'ContainerLayer' is to be constructed.
+         *
+         * Container layers will not be rendered in any fashion and instead are used
+         * as a parent of renderable layers.
+         *
+         * @param isContainerLayer Whether to create a container layer.
+         */
+        public Builder setContainerLayer(boolean isContainerLayer) {
+            if (isContainerLayer) {
+                setFlags(FX_SURFACE_CONTAINER, FX_SURFACE_MASK);
+            } else {
+                setBufferLayer();
+            }
+            return this;
+        }
+
+        /**
+         * Indicates whether a buffer layer is to be constructed.
+         *
+         */
+        public Builder setBufferLayer() {
+            return setFlags(FX_SURFACE_NORMAL, FX_SURFACE_MASK);
+        }
+
+        /**
          * Set 'Surface creation flags' such as {@link HIDDEN}, {@link SECURE}.
          *
          * TODO: Finish conversion to individual builder methods?
@@ -540,6 +572,11 @@
             mFlags = flags;
             return this;
         }
+
+        private Builder setFlags(int flags, int mask) {
+            mFlags = (mFlags & ~mask) | flags;
+            return this;
+        }
     }
 
     /**
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 3f7ab2a..38dcdd3 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -33,9 +33,14 @@
 import java.util.List;
 
 /**
- * Container for storing additional per-view data generated by {@link View#onProvideStructure
+ * <p><code>ViewStructure</code> is a container for storing additional
+ * per-view data generated by {@link View#onProvideStructure
  * View.onProvideStructure} and {@link View#onProvideAutofillStructure
  * View.onProvideAutofillStructure}.
+ *
+ * <p>To learn more about using Autofill in your app, read the
+ * <a href="/guide/topics/text/autofill">Autofill Framework</a> guides.
+ *
  */
 public abstract class ViewStructure {
 
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 8b9b856..84a4601 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1699,6 +1699,15 @@
         public static final int PRIVATE_FLAG_IS_SCREEN_DECOR = 0x00400000;
 
         /**
+         * Flag to indicate that the status bar window is now in an explicit expanded state, meaning
+         * that status bar will not be hidden by any window with flag {@link #FLAG_FULLSCREEN} or
+         * {@link View#SYSTEM_UI_FLAG_FULLSCREEN} set.
+         * This can only be set by {@link LayoutParams#TYPE_STATUS_BAR}.
+         * @hide
+         */
+        public static final int PRIVATE_FLAG_STATUS_BAR_EXPANDED = 0x00800000;
+
+        /**
          * Control flags that are private to the platform.
          * @hide
          */
@@ -1786,7 +1795,11 @@
                 @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_IS_SCREEN_DECOR,
                         equals = PRIVATE_FLAG_IS_SCREEN_DECOR,
-                        name = "IS_SCREEN_DECOR")
+                        name = "IS_SCREEN_DECOR"),
+                @ViewDebug.FlagToString(
+                        mask = PRIVATE_FLAG_STATUS_BAR_EXPANDED,
+                        equals = PRIVATE_FLAG_STATUS_BAR_EXPANDED,
+                        name = "STATUS_BAR_EXPANDED")
         })
         @TestApi
         public int privateFlags;
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 769ea3e..b382a18 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -628,7 +628,7 @@
     }
 
     /**
-     * Sets the text before a change.
+     * Gets the text before a change.
      *
      * @return The text before the change.
      */
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 7555fff..d21cb3e 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -77,11 +77,16 @@
 import sun.misc.Cleaner;
 
 /**
- * The {@link AutofillManager} provides ways for apps and custom views to integrate with the
- * Autofill Framework lifecycle.
+ * <p>The {@link AutofillManager} class provides ways for apps and custom views to
+ * integrate with the Autofill Framework lifecycle.
+ *
+ * <p>To learn about using Autofill in your app, read
+ * the <a href="/guide/topics/text/autofill">Autofill Framework</a> guides.
+ *
+ * <h3 id="autofill-lifecycle">Autofill lifecycle</h3>
  *
  * <p>The autofill lifecycle starts with the creation of an autofill context associated with an
- * activity context; the autofill context is created when one of the following methods is called for
+ * activity context. The autofill context is created when one of the following methods is called for
  * the first time in an activity context, and the current user has an enabled autofill service:
  *
  * <ul>
@@ -90,7 +95,7 @@
  *   <li>{@link #requestAutofill(View)}
  * </ul>
  *
- * <p>Tipically, the context is automatically created when the first view of the activity is
+ * <p>Typically, the context is automatically created when the first view of the activity is
  * focused because {@code View.onFocusChanged()} indirectly calls
  * {@link #notifyViewEntered(View)}. App developers can call {@link #requestAutofill(View)} to
  * explicitly create it (for example, a custom view developer could offer a contextual menu action
@@ -134,7 +139,9 @@
  * shows an autofill save UI if the value of savable views have changed. If the user selects the
  * option to Save, the current value of the views is then sent to the autofill service.
  *
- * <p>It is safe to call into its methods from any thread.
+ * <h3 id="additional-notes">Additional notes</h3>
+ *
+ * <p>It is safe to call <code>AutofillManager</code> methods from any thread.
  */
 @SystemService(Context.AUTOFILL_MANAGER_SERVICE)
 @RequiresFeature(PackageManager.FEATURE_AUTOFILL)
@@ -2138,7 +2145,11 @@
         pw.print(pfx); pw.print("sessionId: "); pw.println(mSessionId);
         pw.print(pfx); pw.print("state: "); pw.println(getStateAsStringLocked());
         pw.print(pfx); pw.print("context: "); pw.println(mContext);
-        pw.print(pfx); pw.print("client: "); pw.println(getClient());
+        final AutofillClient client = getClient();
+        if (client != null) {
+            pw.print(pfx); pw.print("client: "); pw.print(client);
+            pw.print(" ("); pw.print(client.autofillClientGetActivityToken()); pw.println(')');
+        }
         pw.print(pfx); pw.print("enabled: "); pw.println(mEnabled);
         pw.print(pfx); pw.print("hasService: "); pw.println(mService != null);
         pw.print(pfx); pw.print("hasCallback: "); pw.println(mCallback != null);
@@ -2157,8 +2168,24 @@
         pw.print(pfx); pw.print("entered ids: "); pw.println(mEnteredIds);
         pw.print(pfx); pw.print("save trigger id: "); pw.println(mSaveTriggerId);
         pw.print(pfx); pw.print("save on finish(): "); pw.println(mSaveOnFinish);
-        pw.print(pfx); pw.print("compat mode enabled: "); pw.println(
-                isCompatibilityModeEnabledLocked());
+        pw.print(pfx); pw.print("compat mode enabled: ");
+        synchronized (mLock) {
+            if (mCompatibilityBridge != null) {
+                final String pfx2 = pfx + "  ";
+                pw.println("true");
+                pw.print(pfx2); pw.print("windowId: ");
+                pw.println(mCompatibilityBridge.mFocusedWindowId);
+                pw.print(pfx2); pw.print("nodeId: ");
+                pw.println(mCompatibilityBridge.mFocusedNodeId);
+                pw.print(pfx2); pw.print("virtualId: ");
+                pw.println(AccessibilityNodeInfo
+                        .getVirtualDescendantId(mCompatibilityBridge.mFocusedNodeId));
+                pw.print(pfx2); pw.print("focusedBounds: ");
+                pw.println(mCompatibilityBridge.mFocusedBounds);
+            } else {
+                pw.println("false");
+            }
+        }
         pw.print(pfx); pw.print("debug: "); pw.print(sDebug);
         pw.print(" verbose: "); pw.println(sVerbose);
     }
@@ -2292,7 +2319,15 @@
         @Override
         public AccessibilityEvent onAccessibilityEvent(AccessibilityEvent event,
                 boolean accessibilityEnabled, int relevantEventTypes) {
-            switch (event.getEventType()) {
+            final int type = event.getEventType();
+            if (sVerbose) {
+                // NOTE: this is waaay spammy, but that's life.
+                Log.v(TAG, "onAccessibilityEvent(" + AccessibilityEvent.eventTypeToString(type)
+                        + "): virtualId="
+                        + AccessibilityNodeInfo.getVirtualDescendantId(event.getSourceNodeId())
+                        + ", client=" + getClient());
+            }
+            switch (type) {
                 case AccessibilityEvent.TYPE_VIEW_FOCUSED: {
                     synchronized (mLock) {
                         if (mFocusedWindowId == event.getWindowId()
diff --git a/core/java/android/webkit/WebBackForwardList.java b/core/java/android/webkit/WebBackForwardList.java
index 0c34e3c..4d3bbe4 100644
--- a/core/java/android/webkit/WebBackForwardList.java
+++ b/core/java/android/webkit/WebBackForwardList.java
@@ -57,7 +57,8 @@
     /**
      * Clone the entire object to be used in the UI thread by clients of
      * WebView. This creates a copy that should never be modified by any of the
-     * webkit package classes.
+     * webkit package classes. On Android 4.4 and later there is no need to use
+     * this, as the object is already a read-only copy of the internal state.
      */
     protected abstract WebBackForwardList clone();
 }
diff --git a/core/java/android/webkit/WebHistoryItem.java b/core/java/android/webkit/WebHistoryItem.java
index 74db039..b9e7042 100644
--- a/core/java/android/webkit/WebHistoryItem.java
+++ b/core/java/android/webkit/WebHistoryItem.java
@@ -23,7 +23,7 @@
 /**
  * A convenience class for accessing fields in an entry in the back/forward list
  * of a WebView. Each WebHistoryItem is a snapshot of the requested history
- * item. Each history item may be updated during the load of a page.
+ * item.
  * @see WebBackForwardList
  */
 public abstract class WebHistoryItem implements Cloneable {
@@ -44,8 +44,6 @@
      * history item. See getTargetUrl() for the url that is the actual target of
      * this history item.
      * @return The base url of this history item.
-     * Note: The VM ensures 32-bit atomic read/write operations so we don't have
-     * to synchronize this method.
      */
     public abstract String getUrl();
 
@@ -60,22 +58,20 @@
     /**
      * Return the document title of this history item.
      * @return The document title of this history item.
-     * Note: The VM ensures 32-bit atomic read/write operations so we don't have
-     * to synchronize this method.
      */
     public abstract String getTitle();
 
     /**
      * Return the favicon of this history item or {@code null} if no favicon was found.
      * @return A Bitmap containing the favicon for this history item or {@code null}.
-     * Note: The VM ensures 32-bit atomic read/write operations so we don't have
-     * to synchronize this method.
      */
     @Nullable
     public abstract Bitmap getFavicon();
 
     /**
-     * Clone the history item for use by clients of WebView.
+     * Clone the history item for use by clients of WebView. On Android 4.4 and later
+     * there is no need to use this, as the object is already a read-only copy of the
+     * internal state.
      */
     protected abstract WebHistoryItem clone();
 }
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 66e079e..c30edd3 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -991,7 +991,9 @@
      * {@link PluginState#OFF}.
      *
      * @param state a PluginState value
-     * @deprecated Plugins will not be supported in future, and should not be used.
+     * @deprecated Plugins are not supported in API level
+     *             {@link android.os.Build.VERSION_CODES#KITKAT} or later;
+     *             enabling plugins is a no-op.
      */
     @Deprecated
     public abstract void setPluginState(PluginState state);
@@ -1187,7 +1189,9 @@
      *
      * @return the plugin state as a {@link PluginState} value
      * @see #setPluginState
-     * @deprecated Plugins will not be supported in future, and should not be used.
+     * @deprecated Plugins are not supported in API level
+     *             {@link android.os.Build.VERSION_CODES#KITKAT} or later;
+     *             enabling plugins is a no-op.
      */
     @Deprecated
     public abstract PluginState getPluginState();
diff --git a/core/java/android/webkit/WebSyncManager.java b/core/java/android/webkit/WebSyncManager.java
index 3fa1b01..e44d6eb 100644
--- a/core/java/android/webkit/WebSyncManager.java
+++ b/core/java/android/webkit/WebSyncManager.java
@@ -26,6 +26,7 @@
 abstract class WebSyncManager implements Runnable {
     protected static final java.lang.String LOGTAG = "websync";
     protected android.webkit.WebViewDatabase mDataBase;
+    @UnsupportedAppUsage
     protected android.os.Handler mHandler;
 
     protected WebSyncManager(Context context, String name) {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5c5e9de..8f03b69 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -42,7 +42,6 @@
 import android.os.RemoteException;
 import android.os.StrictMode;
 import android.print.PrintDocumentAdapter;
-import android.security.KeyChain;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.SparseArray;
@@ -1432,9 +1431,8 @@
     /**
      * Clears the client certificate preferences stored in response
      * to proceeding/cancelling client cert requests. Note that WebView
-     * automatically clears these preferences when it receives a
-     * {@link KeyChain#ACTION_STORAGE_CHANGED} intent. The preferences are
-     * shared by all the WebViews that are created by the embedder application.
+     * automatically clears these preferences when the system keychain is updated.
+     * The preferences are shared by all the WebViews that are created by the embedder application.
      *
      * @param onCleared  A runnable to be invoked when client certs are cleared.
      *                   The runnable will be called in UI thread.
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index f686b66..bdd7a09 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -31,18 +31,25 @@
 public class WebViewClient {
 
     /**
-     * Give the host application a chance to take over the control when a new
-     * url is about to be loaded in the current WebView. If WebViewClient is not
-     * provided, by default WebView will ask Activity Manager to choose the
-     * proper handler for the url. If WebViewClient is provided, return {@code true}
-     * means the host application handles the url, while return {@code false} means the
-     * current WebView handles the url.
-     * This method is not called for requests using the POST "method".
+     * Give the host application a chance to take control when a URL is about to be loaded in the
+     * current WebView. If a WebViewClient is not provided, by default WebView will ask Activity
+     * Manager to choose the proper handler for the URL. If a WebViewClient is provided, returning
+     * {@code true} causes the current WebView to abort loading the URL, while returning
+     * {@code false} causes the WebView to continue loading the URL as usual.
+     *
+     * <p class="note"><b>Note:</b> Do not call {@link WebView#loadUrl(String)} with the same
+     * URL and then return {@code true}. This unnecessarily cancels the current load and starts a
+     * new load with the same URL. The correct way to continue loading a given URL is to simply
+     * return {@code false}, without calling {@link WebView#loadUrl(String)}.
+     *
+     * <p class="note"><b>Note:</b> This method is not called for POST requests.
+     *
+     * <p class="note"><b>Note:</b> This method may be called for subframes and with non-HTTP(S)
+     * schemes; calling {@link WebView#loadUrl(String)} with such a URL will fail.
      *
      * @param view The WebView that is initiating the callback.
-     * @param url The url to be loaded.
-     * @return {@code true} if the host application wants to leave the current WebView
-     *         and handle the url itself, otherwise return {@code false}.
+     * @param url The URL to be loaded.
+     * @return {@code true} to cancel the current load, otherwise return {@code false}.
      * @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest)
      *             shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead.
      */
@@ -52,26 +59,25 @@
     }
 
     /**
-     * Give the host application a chance to take over the control when a new
-     * url is about to be loaded in the current WebView. If WebViewClient is not
-     * provided, by default WebView will ask Activity Manager to choose the
-     * proper handler for the url. If WebViewClient is provided, return {@code true}
-     * means the host application handles the url, while return {@code false} means the
-     * current WebView handles the url.
+     * Give the host application a chance to take control when a URL is about to be loaded in the
+     * current WebView. If a WebViewClient is not provided, by default WebView will ask Activity
+     * Manager to choose the proper handler for the URL. If a WebViewClient is provided, returning
+     * {@code true} causes the current WebView to abort loading the URL, while returning
+     * {@code false} causes the WebView to continue loading the URL as usual.
      *
-     * <p>Notes:
-     * <ul>
-     * <li>This method is not called for requests using the POST &quot;method&quot;.</li>
-     * <li>This method is also called for subframes with non-http schemes, thus it is
-     * strongly disadvised to unconditionally call {@link WebView#loadUrl(String)}
-     * with the request's url from inside the method and then return {@code true},
-     * as this will make WebView to attempt loading a non-http url, and thus fail.</li>
-     * </ul>
+     * <p class="note"><b>Note:</b> Do not call {@link WebView#loadUrl(String)} with the request's
+     * URL and then return {@code true}. This unnecessarily cancels the current load and starts a
+     * new load with the same URL. The correct way to continue loading a given URL is to simply
+     * return {@code false}, without calling {@link WebView#loadUrl(String)}.
+     *
+     * <p class="note"><b>Note:</b> This method is not called for POST requests.
+     *
+     * <p class="note"><b>Note:</b> This method may be called for subframes and with non-HTTP(S)
+     * schemes; calling {@link WebView#loadUrl(String)} with such a URL will fail.
      *
      * @param view The WebView that is initiating the callback.
      * @param request Object containing the details of the request.
-     * @return {@code true} if the host application wants to leave the current WebView
-     *         and handle the url itself, otherwise return {@code false}.
+     * @return {@code true} to cancel the current load, otherwise return {@code false}.
      */
     public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
         return shouldOverrideUrlLoading(view, request.getUrl().toString());
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 3956215..66ce0ee 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -812,7 +812,7 @@
          * @param firstVisibleItem the index of the first visible cell (ignore if
          *        visibleItemCount == 0)
          * @param visibleItemCount the number of visible cells
-         * @param totalItemCount the number of items in the list adaptor
+         * @param totalItemCount the number of items in the list adapter
          */
         public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                 int totalItemCount);
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 9171959..fed0a89 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -32,6 +32,8 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import com.android.internal.R;
+
 /**
  * Utility method for dealing with the assistant aspects of
  * {@link com.android.internal.app.IVoiceInteractionManagerService IVoiceInteractionManagerService}.
@@ -40,6 +42,14 @@
 
     private static final String TAG = "AssistUtils";
 
+    /**
+     * Sentinel value for "no default assistant specified."
+     *
+     * Empty string is already used to represent an explicit setting of No Assistant. null cannot
+     * be used because we can't represent a null value in XML.
+     */
+    private static final String UNSET = "#+UNSET";
+
     private final Context mContext;
     private final IVoiceInteractionManagerService mVoiceInteractionManagerService;
 
@@ -152,10 +162,21 @@
             return ComponentName.unflattenFromString(setting);
         }
 
+        final String defaultSetting = mContext.getResources().getString(
+                R.string.config_defaultAssistantComponentName);
+        if (defaultSetting != null && !defaultSetting.equals(UNSET)) {
+            return ComponentName.unflattenFromString(defaultSetting);
+        }
+
         // Fallback to keep backward compatible behavior when there is no user setting.
         if (activeServiceSupportsAssistGesture()) {
             return getActiveServiceComponentName();
         }
+
+        if (UNSET.equals(defaultSetting)) {
+            return null;
+        }
+
         final SearchManager searchManager =
             (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
         if (searchManager == null) {
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 398d087..4728124 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -16,14 +16,21 @@
 
 package com.android.internal.app;
 
+import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
+
+import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.admin.DevicePolicyManager;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -31,12 +38,11 @@
 import android.os.UserManager;
 import android.util.Slog;
 import android.widget.Toast;
-
 import com.android.internal.annotations.VisibleForTesting;
-
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
-
-import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
+import java.util.Set;
 
 /**
  * This is used in conjunction with
@@ -44,7 +50,6 @@
  * be passed in and out of a managed profile.
  */
 public class IntentForwarderActivity extends Activity  {
-
     public static String TAG = "IntentForwarderActivity";
 
     public static String FORWARD_INTENT_TO_PARENT
@@ -53,6 +58,9 @@
     public static String FORWARD_INTENT_TO_MANAGED_PROFILE
             = "com.android.internal.app.ForwardIntentToManagedProfile";
 
+    private static final Set<String> ALLOWED_TEXT_MESSAGE_SCHEME
+            = new HashSet<>(Arrays.asList("sms", "smsto", "mms", "mmsto"));
+
     private Injector mInjector;
 
     @Override
@@ -93,19 +101,8 @@
                 newIntent.prepareToLeaveUser(callingUserId);
             }
 
-            final android.content.pm.ResolveInfo ri =
-                    mInjector.getPackageManager().resolveActivityAsUser(
-                            newIntent,
-                            MATCH_DEFAULT_ONLY,
-                            targetUserId);
-
-            // Don't show the disclosure if next activity is ResolverActivity or ChooserActivity
-            // as those will already have shown work / personal as neccesary etc.
-            final boolean shouldShowDisclosure = ri == null || ri.activityInfo == null ||
-                    !"android".equals(ri.activityInfo.packageName) ||
-                    !(ResolverActivity.class.getName().equals(ri.activityInfo.name)
-                            || ChooserActivity.class.getName().equals(ri.activityInfo.name));
-
+            final ResolveInfo ri = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY,
+                    targetUserId);
             try {
                 startActivityAsCaller(newIntent, null, false, targetUserId);
             } catch (RuntimeException e) {
@@ -124,8 +121,8 @@
                         + ActivityThread.currentProcessName(), e);
             }
 
-            if (shouldShowDisclosure) {
-                Toast.makeText(this, getString(userMessageId), Toast.LENGTH_LONG).show();
+            if (shouldShowDisclosure(ri, intentReceived)) {
+                mInjector.showToast(userMessageId, Toast.LENGTH_LONG);
             }
         } else {
             Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user "
@@ -134,6 +131,35 @@
         finish();
     }
 
+    private boolean shouldShowDisclosure(@Nullable ResolveInfo ri, Intent intent) {
+        if (ri == null || ri.activityInfo == null) {
+            return true;
+        }
+        if (ri.activityInfo.applicationInfo.isSystemApp()
+                && (isDialerIntent(intent) || isTextMessageIntent(intent))) {
+            return false;
+        }
+        return !isTargetResolverOrChooserActivity(ri.activityInfo);
+    }
+
+    private boolean isTextMessageIntent(Intent intent) {
+        return Intent.ACTION_SENDTO.equals(intent.getAction()) && intent.getData() != null
+            && ALLOWED_TEXT_MESSAGE_SCHEME.contains(intent.getData().getScheme());
+    }
+
+    private boolean isDialerIntent(Intent intent) {
+        return Intent.ACTION_DIAL.equals(intent.getAction())
+            || Intent.ACTION_CALL.equals(intent.getAction());
+    }
+
+    private boolean isTargetResolverOrChooserActivity(ActivityInfo activityInfo) {
+        if (!"android".equals(activityInfo.packageName)) {
+            return false;
+        }
+        return ResolverActivity.class.getName().equals(activityInfo.name)
+            || ChooserActivity.class.getName().equals(activityInfo.name);
+    }
+
     /**
      * Check whether the intent can be forwarded to target user. Return the intent used for
      * forwarding if it can be forwarded, {@code null} otherwise.
@@ -241,6 +267,16 @@
         public PackageManager getPackageManager() {
             return IntentForwarderActivity.this.getPackageManager();
         }
+
+        @Override
+        public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
+            return getPackageManager().resolveActivityAsUser(intent, flags, userId);
+        }
+
+        @Override
+        public void showToast(int messageId, int duration) {
+            Toast.makeText(IntentForwarderActivity.this, getString(messageId), duration).show();
+        }
     }
 
     public interface Injector {
@@ -249,5 +285,9 @@
         UserManager getUserManager();
 
         PackageManager getPackageManager();
+
+        ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId);
+
+        void showToast(@StringRes int messageId, int duration);
     }
 }
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 486c836..8b06c47 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -4031,7 +4031,9 @@
         try {
             IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface(
                     ServiceManager.getService("batteryproperties"));
-            registrar.scheduleUpdate();
+            if (registrar != null) {
+                registrar.scheduleUpdate();
+            }
         } catch (RemoteException e) {
             // Ignore.
         }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 8bdb000..c2c6ae6 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -536,9 +536,11 @@
     static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
         String libraryPath = System.getProperty("java.library.path");
 
+        // We use the boot class loader, that's what the runtime expects at AOT.
+        ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
+
         return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
-                ClassLoader.getSystemClassLoader(), targetSdkVersion, true /* isNamespaceShared */,
-                null /* classLoaderName */);
+                parent, targetSdkVersion, true /* isNamespaceShared */, null /* classLoaderName */);
     }
 
     /**
diff --git a/core/java/com/android/internal/widget/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java
index 64b1f24..0c8613b 100644
--- a/core/java/com/android/internal/widget/MessagingLinearLayout.java
+++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java
@@ -111,14 +111,16 @@
             final int childHeight = child.getMeasuredHeight();
             int newHeight = Math.max(totalHeight, totalHeight + childHeight + lp.topMargin +
                     lp.bottomMargin + spacing);
-            first = false;
             int measureType = MessagingChild.MEASURED_NORMAL;
             if (messagingChild != null) {
                 measureType = messagingChild.getMeasuredType();
                 linesRemaining -= messagingChild.getConsumedLines();
             }
-            boolean isShortened = measureType == MessagingChild.MEASURED_SHORTENED;
-            boolean isTooSmall = measureType == MessagingChild.MEASURED_TOO_SMALL;
+
+            // We never measure the first item as too small, we want to at least show something.
+            boolean isTooSmall = measureType == MessagingChild.MEASURED_TOO_SMALL && !first;
+            boolean isShortened = measureType == MessagingChild.MEASURED_SHORTENED
+                    || measureType == MessagingChild.MEASURED_TOO_SMALL && first;
             if (newHeight <= targetHeight && !isTooSmall) {
                 totalHeight = newHeight;
                 measuredWidth = Math.max(measuredWidth,
@@ -131,6 +133,7 @@
             } else {
                 break;
             }
+            first = false;
         }
 
         setMeasuredDimension(
diff --git a/core/java/com/android/internal/widget/NumericTextView.java b/core/java/com/android/internal/widget/NumericTextView.java
index 27c5834..d215670 100644
--- a/core/java/com/android/internal/widget/NumericTextView.java
+++ b/core/java/com/android/internal/widget/NumericTextView.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
@@ -53,6 +54,7 @@
 
     private OnValueChangedListener mListener;
 
+    @UnsupportedAppUsage
     public NumericTextView(Context context, AttributeSet attrs) {
         super(context, attrs);
 
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 45069ca..a07c96c 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -25,6 +25,7 @@
 import android.os.Build;
 import android.os.Environment;
 import android.os.Process;
+import android.os.SystemProperties;
 import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -67,6 +68,9 @@
     private static final int ALLOW_HIDDENAPI_WHITELISTING = 0x40;
     private static final int ALLOW_ALL = ~0;
 
+    // property for runtime configuration differentiation
+    private static final String SKU_PROPERTY = "ro.boot.product.hardware.sku";
+
     // Group-ids that are given to all packages as read from etc/permissions/*.xml.
     int[] mGlobalGids;
 
@@ -312,6 +316,17 @@
         readPermissions(Environment.buildPath(
                 Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag);
 
+        String skuProperty = SystemProperties.get(SKU_PROPERTY, "");
+        if (!skuProperty.isEmpty()) {
+            String skuDir = "sku_" + skuProperty;
+
+            readPermissions(Environment.buildPath(
+                    Environment.getOdmDirectory(), "etc", "sysconfig", skuDir), odmPermissionFlag);
+            readPermissions(Environment.buildPath(
+                    Environment.getOdmDirectory(), "etc", "permissions", skuDir),
+                    odmPermissionFlag);
+        }
+
         // Allow OEM to customize features and OEM permissions
         int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS;
         readPermissions(Environment.buildPath(
@@ -342,6 +357,10 @@
         // Iterate over the files in the directory and scan .xml files
         File platformFile = null;
         for (File f : libraryDir.listFiles()) {
+            if (!f.isFile()) {
+                continue;
+            }
+
             // We'll read platform.xml last
             if (f.getPath().endsWith("etc/permissions/platform.xml")) {
                 platformFile = f;
diff --git a/core/java/com/android/server/net/BaseNetdEventCallback.java b/core/java/com/android/server/net/BaseNetdEventCallback.java
index 97247aa..a65214a 100644
--- a/core/java/com/android/server/net/BaseNetdEventCallback.java
+++ b/core/java/com/android/server/net/BaseNetdEventCallback.java
@@ -32,6 +32,12 @@
     }
 
     @Override
+    public void onNat64PrefixEvent(int netId, boolean added, String prefixString,
+            int prefixLength) {
+        // default no-op
+    }
+
+    @Override
     public void onPrivateDnsValidationEvent(int netId, String ipAddress,
             String hostname, boolean validated) {
         // default no-op
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index ec24980..c81a77d 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -41,6 +41,7 @@
         "com_google_android_gles_jni_EGLImpl.cpp",
         "com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm
         "android_app_Activity.cpp",
+	"android_app_ActivityThread.cpp",
         "android_app_NativeActivity.cpp",
         "android_app_admin_SecurityLog.cpp",
         "android_opengl_EGL14.cpp",
@@ -263,7 +264,7 @@
         "libhardware",
         "libhardware_legacy",
         "libselinux",
-        "libicuuc",
+        "libandroidicu",
         "libmedia",
         "libmediametrics",
         "libaudioclient",
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 5a74a24..b085bc9 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -48,7 +48,7 @@
 
 class BitmapWrapper {
 public:
-    BitmapWrapper(Bitmap* bitmap)
+    explicit BitmapWrapper(Bitmap* bitmap)
         : mBitmap(bitmap) { }
 
     void freePixels() {
diff --git a/core/jni/android/graphics/FontUtils.h b/core/jni/android/graphics/FontUtils.h
index 9eaaa49..30fdf24 100644
--- a/core/jni/android/graphics/FontUtils.h
+++ b/core/jni/android/graphics/FontUtils.h
@@ -27,7 +27,7 @@
 namespace android {
 
 struct FontFamilyWrapper {
-  FontFamilyWrapper(std::shared_ptr<minikin::FontFamily>&& family) : family(family) {}
+  explicit FontFamilyWrapper(std::shared_ptr<minikin::FontFamily>&& family) : family(family) {}
   std::shared_ptr<minikin::FontFamily> family;
 };
 
diff --git a/core/jni/android/graphics/GIFMovie.cpp b/core/jni/android/graphics/GIFMovie.cpp
index dd99b37..f84a4bd 100644
--- a/core/jni/android/graphics/GIFMovie.cpp
+++ b/core/jni/android/graphics/GIFMovie.cpp
@@ -21,7 +21,7 @@
 
 class GIFMovie : public Movie {
 public:
-    GIFMovie(SkStream* stream);
+    explicit GIFMovie(SkStream* stream);
     virtual ~GIFMovie();
 
 protected:
diff --git a/core/jni/android_app_ActivityThread.cpp b/core/jni/android_app_ActivityThread.cpp
new file mode 100644
index 0000000..d56e4c5
--- /dev/null
+++ b/core/jni/android_app_ActivityThread.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jni.h"
+#include "GraphicsJNI.h"
+#include <nativehelper/JNIHelp.h>
+
+#include <minikin/Layout.h>
+#include <renderthread/RenderProxy.h>
+
+#include "core_jni_helpers.h"
+#include <unistd.h>
+
+namespace android {
+
+static void android_app_ActivityThread_purgePendingResources(JNIEnv* env, jobject clazz) {
+    // Don't care about return values.
+    mallopt(M_PURGE, 0);
+}
+
+static void
+android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
+    int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
+    android::uirenderer::renderthread::RenderProxy::dumpGraphicsMemory(fd);
+    minikin::Layout::dumpMinikinStats(fd);
+}
+
+
+static JNINativeMethod gActivityThreadMethods[] = {
+    // ------------ Regular JNI ------------------
+    { "nPurgePendingResources",        "()V",
+      (void*) android_app_ActivityThread_purgePendingResources },
+    { "nDumpGraphicsInfo",        "(Ljava/io/FileDescriptor;)V",
+      (void*) android_app_ActivityThread_dumpGraphics }
+};
+
+int register_android_app_ActivityThread(JNIEnv* env) {
+    return RegisterMethodsOrDie(env, "android/app/ActivityThread",
+            gActivityThreadMethods, NELEM(gActivityThreadMethods));
+}
+
+};
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 6c9f463..9963a45 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -20,7 +20,6 @@
 #include "android_media_AudioTrack.h"
 
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include "core_jni_helpers.h"
 
 #include <utils/Log.h>
diff --git a/core/jni/android_media_DeviceCallback.cpp b/core/jni/android_media_DeviceCallback.cpp
index 108fa00..a1a0351 100644
--- a/core/jni/android_media_DeviceCallback.cpp
+++ b/core/jni/android_media_DeviceCallback.cpp
@@ -20,7 +20,6 @@
 
 #include <utils/Log.h>
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include "core_jni_helpers.h"
 #include <media/AudioSystem.h>
 
diff --git a/core/jni/android_os_SharedMemory.cpp b/core/jni/android_os_SharedMemory.cpp
index f6e5c7a..c33405d 100644
--- a/core/jni/android_os_SharedMemory.cpp
+++ b/core/jni/android_os_SharedMemory.cpp
@@ -20,8 +20,9 @@
 
 #include <cutils/ashmem.h>
 #include <utils/Log.h>
+
+#include <nativehelper/jni_macros.h>
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedLocalRef.h>
 
 #include <algorithm>
@@ -31,10 +32,10 @@
 
 namespace {
 
-static void throwErrnoException(JNIEnv* env, const char* functionName, int error) {
-    static jmethodID ctor = env->GetMethodID(JniConstants::errnoExceptionClass,
-            "<init>", "(Ljava/lang/String;I)V");
+jclass errnoExceptionClass;
+jmethodID errnoExceptionCtor;  // MethodID for ErrnoException.<init>(String,I)
 
+void throwErrnoException(JNIEnv* env, const char* functionName, int error) {
     ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName));
     if (detailMessage.get() == NULL) {
         // Not really much we can do here. We're probably dead in the water,
@@ -42,12 +43,14 @@
         env->ExceptionClear();
     }
 
-    jobject exception = env->NewObject(JniConstants::errnoExceptionClass, ctor,
-            detailMessage.get(), error);
+    jobject exception = env->NewObject(errnoExceptionClass,
+                                       errnoExceptionCtor,
+                                       detailMessage.get(),
+                                       error);
     env->Throw(reinterpret_cast<jthrowable>(exception));
 }
 
-static jobject SharedMemory_create(JNIEnv* env, jobject, jstring jname, jint size) {
+jobject SharedMemory_nCreate(JNIEnv* env, jobject, jstring jname, jint size) {
 
     // Name is optional so we can't use ScopedUtfChars for this as it throws NPE on null
     const char* name = jname ? env->GetStringUTFChars(jname, nullptr) : nullptr;
@@ -69,7 +72,7 @@
     return jniCreateFileDescriptor(env, fd);
 }
 
-static jint SharedMemory_getSize(JNIEnv* env, jobject, jobject fileDescriptor) {
+jint SharedMemory_nGetSize(JNIEnv* env, jobject, jobject fileDescriptor) {
     int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
     if (!ashmem_valid(fd)) {
         return -1;
@@ -78,7 +81,7 @@
     return static_cast<jint>(std::min(size, static_cast<size_t>(std::numeric_limits<jint>::max())));
 }
 
-static jint SharedMemory_setProt(JNIEnv* env, jobject, jobject fileDescriptor, jint prot) {
+jint SharedMemory_nSetProt(JNIEnv* env, jobject, jobject fileDescriptor, jint prot) {
     int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
     int err = 0;
     if (ashmem_set_prot_region(fd, prot)) {
@@ -87,18 +90,21 @@
     return err;
 }
 
-static const JNINativeMethod methods[] = {
-    {"nCreate", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)SharedMemory_create},
-    {"nGetSize", "(Ljava/io/FileDescriptor;)I", (void*)SharedMemory_getSize},
-    {"nSetProt", "(Ljava/io/FileDescriptor;I)I", (void*)SharedMemory_setProt},
+const JNINativeMethod methods[] = {
+  NATIVE_METHOD(SharedMemory, nCreate, "(Ljava/lang/String;I)Ljava/io/FileDescriptor;"),
+  NATIVE_METHOD(SharedMemory, nGetSize, "(Ljava/io/FileDescriptor;)I"),
+  NATIVE_METHOD(SharedMemory, nSetProt, "(Ljava/io/FileDescriptor;I)I")
 };
 
 } // anonymous namespace
 
 namespace android {
 
-int register_android_os_SharedMemory(JNIEnv* env)
-{
+int register_android_os_SharedMemory(JNIEnv* env) {
+    errnoExceptionClass =
+        MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/system/ErrnoException"));
+    errnoExceptionCtor =
+        GetMethodIDOrDie(env, errnoExceptionClass, "<init>", "(Ljava/lang/String;I)V");
     return RegisterMethodsOrDie(env, "android/os/SharedMemory", methods, NELEM(methods));
 }
 
diff --git a/core/jni/android_util_jar_StrictJarFile.cpp b/core/jni/android_util_jar_StrictJarFile.cpp
index 4ab8db4..182a621 100644
--- a/core/jni/android_util_jar_StrictJarFile.cpp
+++ b/core/jni/android_util_jar_StrictJarFile.cpp
@@ -22,24 +22,26 @@
 
 #include <log/log.h>
 
+#include <nativehelper/jni_macros.h>
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedUtfChars.h>
-#include "jni.h"
+
+#include "core_jni_helpers.h"
 #include "ziparchive/zip_archive.h"
 
-namespace android {
+namespace {
 
+jclass zipEntryClass;
 // The method ID for ZipEntry.<init>(String,String,JJJIII[BJJ)
-static jmethodID zipEntryCtor;
+jmethodID zipEntryCtor;
 
-static void throwIoException(JNIEnv* env, const int32_t errorCode) {
+void throwIoException(JNIEnv* env, const int32_t errorCode) {
   jniThrowException(env, "java/io/IOException", ErrorCodeString(errorCode));
 }
 
-static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName) {
-  return env->NewObject(JniConstants::zipEntryClass,
+jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName) {
+  return env->NewObject(zipEntryClass,
                         zipEntryCtor,
                         entryName,
                         NULL,  // comment
@@ -52,7 +54,7 @@
                         static_cast<jlong>(entry.offset));
 }
 
-static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring name, jint fd) {
+jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring name, jint fd) {
   // Name argument is used for logging, and can be any string.
   ScopedUtfChars nameChars(env, name);
   if (nameChars.c_str() == NULL) {
@@ -90,7 +92,7 @@
 };
 
 
-static jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nativeHandle,
+jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nativeHandle,
                                                 jstring prefix) {
   ScopedUtfChars prefixChars(env, prefix);
   if (prefixChars.c_str() == NULL) {
@@ -116,7 +118,7 @@
   return reinterpret_cast<jlong>(handle);
 }
 
-static jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterationHandle) {
+jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterationHandle) {
   ZipEntry data;
   ZipString entryName;
 
@@ -135,7 +137,7 @@
   return newZipEntry(env, data, entryNameString.get());
 }
 
-static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle,
+jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle,
                                              jstring entryName) {
   ScopedUtfChars entryNameChars(env, entryName);
   if (entryNameChars.c_str() == NULL) {
@@ -152,11 +154,11 @@
   return newZipEntry(env, data, entryName);
 }
 
-static void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) {
+void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) {
   CloseArchive(reinterpret_cast<ZipArchiveHandle>(nativeHandle));
 }
 
-static JNINativeMethod gMethods[] = {
+JNINativeMethod gMethods[] = {
   NATIVE_METHOD(StrictJarFile, nativeOpenJarFile, "(Ljava/lang/String;I)J"),
   NATIVE_METHOD(StrictJarFile, nativeStartIteration, "(JLjava/lang/String;)J"),
   NATIVE_METHOD(StrictJarFile, nativeNextEntry, "(J)Ljava/util/zip/ZipEntry;"),
@@ -164,14 +166,15 @@
   NATIVE_METHOD(StrictJarFile, nativeClose, "(J)V"),
 };
 
+}  // namespace
+
+namespace android {
+
 int register_android_util_jar_StrictJarFile(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "android/util/jar/StrictJarFile", gMethods, NELEM(gMethods));
-
-  zipEntryCtor = env->GetMethodID(JniConstants::zipEntryClass, "<init>",
-      "(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V");
-  LOG_ALWAYS_FATAL_IF(zipEntryCtor == NULL, "Unable to find ZipEntry.<init>");
-
-  return 0;
+  zipEntryClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/zip/ZipEntry"));
+  zipEntryCtor = GetMethodIDOrDie(env, zipEntryClass, "<init>",
+                                  "(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V");
+  return jniRegisterNativeMethods(env, "android/util/jar/StrictJarFile", gMethods, NELEM(gMethods));
 }
 
 }; // namespace android
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 7956bf4..5197e7d 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -88,17 +88,6 @@
     sp<InvokeRunnableMessage> mMessage;
 };
 
-
-// ---------------- Regular JNI -----------------------------
-
-static void
-android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
-    int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
-    android::uirenderer::renderthread::RenderProxy::dumpGraphicsMemory(fd);
-    minikin::Layout::dumpMinikinStats(fd);
-}
-
-
 // ---------------- @FastNative -----------------------------
 
 static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz,
@@ -215,12 +204,6 @@
     { "nDrawRoundRect",           "(JJJJJJJJ)V",(void*) android_view_DisplayListCanvas_drawRoundRectProps },
 };
 
-static JNINativeMethod gActivityThreadMethods[] = {
-        // ------------ Regular JNI ------------------
-    { "nDumpGraphicsInfo",        "(Ljava/io/FileDescriptor;)V",
-                                               (void*) android_app_ActivityThread_dumpGraphics }
-};
-
 int register_android_view_DisplayListCanvas(JNIEnv* env) {
     jclass runnableClass = FindClassOrDie(env, "java/lang/Runnable");
     gRunnableMethodId = GetMethodIDOrDie(env, runnableClass, "run", "()V");
@@ -228,9 +211,4 @@
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
-int register_android_app_ActivityThread(JNIEnv* env) {
-    return RegisterMethodsOrDie(env, "android/app/ActivityThread",
-            gActivityThreadMethods, NELEM(gActivityThreadMethods));
-}
-
 };
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index b708735..24bafca 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -35,7 +35,6 @@
 #include "bpf/BpfUtils.h"
 #include "netdbpf/BpfNetworkStats.h"
 
-using android::bpf::hasBpfSupport;
 using android::bpf::parseBpfNetworkStatsDetail;
 using android::bpf::stats_line;
 
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 7a3f49a..d4fe1ed 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -273,15 +273,17 @@
     }
   }
 
-  // We don't want core dumps, though, so set the soft limit on core dump size
-  // to 0 without changing the hard limit.
-  rlimit rl;
-  if (getrlimit(RLIMIT_CORE, &rl) == -1) {
-    ALOGE("getrlimit(RLIMIT_CORE) failed");
-  } else {
-    rl.rlim_cur = 0;
-    if (setrlimit(RLIMIT_CORE, &rl) == -1) {
-      ALOGE("setrlimit(RLIMIT_CORE) failed");
+  // Set the core dump size to zero unless wanted (see also coredump_setup in build/envsetup.sh).
+  if (!GetBoolProperty("persist.zygote.core_dump", false)) {
+    // Set the soft limit on core dump size to 0 without changing the hard limit.
+    rlimit rl;
+    if (getrlimit(RLIMIT_CORE, &rl) == -1) {
+      ALOGE("getrlimit(RLIMIT_CORE) failed");
+    } else {
+      rl.rlim_cur = 0;
+      if (setrlimit(RLIMIT_CORE, &rl) == -1) {
+        ALOGE("setrlimit(RLIMIT_CORE) failed");
+      }
     }
   }
 }
@@ -412,7 +414,7 @@
     }
     endmntent(fp);
 
-    for (auto path : toUnmount) {
+    for (const auto& path : toUnmount) {
         if (umount2(path.c_str(), MNT_DETACH)) {
             ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
         }
@@ -915,6 +917,13 @@
     capabilities |= (1LL << CAP_SYS_NICE);
   }
 
+  if (multiuser_get_app_id(uid) == AID_NETWORK_STACK) {
+    capabilities |= (1LL << CAP_NET_ADMIN);
+    capabilities |= (1LL << CAP_NET_BROADCAST);
+    capabilities |= (1LL << CAP_NET_BIND_SERVICE);
+    capabilities |= (1LL << CAP_NET_RAW);
+  }
+
   /*
    * Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
    */
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index d457a1b..d8d919d 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -148,7 +148,7 @@
   const bool is_sock;
 
  private:
-  FileDescriptorInfo(int fd);
+  explicit FileDescriptorInfo(int fd);
 
   FileDescriptorInfo(struct stat stat, const std::string& file_path, int fd, int open_flags,
                      int fd_flags, int fs_flags, off_t offset);
@@ -327,11 +327,13 @@
     return false;
   }
 
-  if (TEMP_FAILURE_RETRY(dup2(new_fd, fd)) == -1) {
+  int dupFlags = (fd_flags & FD_CLOEXEC) ? O_CLOEXEC : 0;
+  if (TEMP_FAILURE_RETRY(dup3(new_fd, fd, dupFlags)) == -1) {
     close(new_fd);
-    *error_msg = android::base::StringPrintf("Failed dup2(%d, %d) (%s): %s",
+    *error_msg = android::base::StringPrintf("Failed dup3(%d, %d, %d) (%s): %s",
                                              fd,
                                              new_fd,
+                                             dupFlags,
                                              file_path.c_str(),
                                              strerror(errno));
     return false;
diff --git a/core/jni/fd_utils.h b/core/jni/fd_utils.h
index a3570d7..09022a2 100644
--- a/core/jni/fd_utils.h
+++ b/core/jni/fd_utils.h
@@ -86,7 +86,7 @@
   bool ReopenOrDetach(std::string* error_msg);
 
  private:
-  FileDescriptorTable(const std::unordered_map<int, FileDescriptorInfo*>& map);
+  explicit FileDescriptorTable(const std::unordered_map<int, FileDescriptorInfo*>& map);
 
   bool RestatInternal(std::set<int>& open_fds, std::string* error_msg);
 
diff --git a/core/proto/android/stats/launcher/launcher.proto b/core/proto/android/stats/launcher/launcher.proto
new file mode 100644
index 0000000..dbd0e03
--- /dev/null
+++ b/core/proto/android/stats/launcher/launcher.proto
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+syntax = "proto2";
+package android.stats.launcher;
+option java_multiple_files = true;
+
+enum LauncherAction {
+    DEFAULT_ACTION = 0;
+    LAUNCH_APP = 1;
+    LAUNCH_TASK = 2;
+    DISMISS_TASK = 3;
+    LONGPRESS = 4;
+    DRAGDROP = 5;
+    SWIPE_UP = 6;
+    SWIPE_DOWN = 7;
+    SWIPE_LEFT = 8;
+    SWIPE_RIGHT = 9;
+}
+
+enum LauncherState {
+    BACKGROUND = 0;
+    HOME = 1;
+    OVERVIEW = 2;
+    ALLAPPS = 3;
+}
+
+message LauncherTarget {
+    enum Type {
+        NONE = 0;
+        ITEM_TYPE = 1;
+        CONTROL_TYPE = 2;
+        CONTAINER_TYPE = 3;
+    }
+    enum Item {
+        DEFAULT_ITEM = 0;
+        APP_ICON = 1;
+        SHORTCUT = 2;
+        WIDGET = 3;
+        FOLDER_ICON = 4;
+        DEEPSHORTCUT = 5;
+        SEARCHBOX = 6;
+        EDITTEXT = 7;
+        NOTIFICATION = 8;
+        TASK = 9;
+    }
+    enum Container {
+        DEFAULT_CONTAINER = 0;
+        HOTSEAT = 1;
+        FOLDER = 2;
+        PREDICTION = 3;
+        SEARCHRESULT = 4;
+    }
+    enum Control {
+        DEFAULT_CONTROL = 0;
+        MENU = 1;
+        UNINSTALL = 2;
+        REMOVE = 3;
+    }
+    optional Type type = 1;
+    optional Item item = 2;
+    optional Container container = 3;
+    optional Control control = 4;
+    optional string launch_component = 5;
+    optional int32 page_id = 6;
+    optional int32 grid_x = 7;
+    optional int32 grid_y = 8;
+}
+
+message LauncherExtension {
+    repeated LauncherTarget src_target = 1;
+    repeated LauncherTarget dst_target = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9ce6044..344b74c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1230,7 +1230,7 @@
     <!-- ================================== -->
     <eat-comment />
 
-    <!-- @SystemApi Allows an application (Phone) to send a request to other applications
+    <!-- Allows an application (Phone) to send a request to other applications
          to handle the respond-via-message action during incoming calls.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE"
@@ -1314,7 +1314,7 @@
         android:description="@string/permdesc_accessLocationExtraCommands"
         android:protectionLevel="normal" />
 
-    <!-- @SystemApi Allows an application to install a location provider into the Location Manager.
+    <!-- Allows an application to install a location provider into the Location Manager.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"
         android:protectionLevel="signature|privileged" />
@@ -1325,7 +1325,7 @@
     <permission android:name="android.permission.HDMI_CEC"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to use location features in hardware,
+    <!-- Allows an application to use location features in hardware,
          such as the geofencing api.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.LOCATION_HARDWARE"
@@ -1512,7 +1512,7 @@
         android:label="@string/permlab_bluetoothAdmin"
         android:protectionLevel="normal" />
 
-    <!-- @SystemApi Allows applications to pair bluetooth devices without user interaction, and to
+    <!-- Allows applications to pair bluetooth devices without user interaction, and to
          allow or disallow phonebook access or message access.
          This is not available to third party applications. -->
     <permission android:name="android.permission.BLUETOOTH_PRIVILEGED"
@@ -1602,7 +1602,7 @@
         android:label="@string/permlab_getAccounts" />
     <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
 
-    <!-- @SystemApi Allows applications to call into AccountAuthenticators.
+    <!-- Allows applications to call into AccountAuthenticators.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCOUNT_MANAGER"
         android:protectionLevel="signature" />
@@ -1775,7 +1775,7 @@
     <!-- =========================================== -->
     <eat-comment />
 
-    <!-- @SystemApi Allows modification of the telephony state - power on, mmi, etc.
+    <!-- Allows modification of the telephony state - power on, mmi, etc.
          Does not include placing calls.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MODIFY_PHONE_STATE"
@@ -1832,6 +1832,15 @@
     <permission android:name="android.permission.BIND_SCREENING_SERVICE"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Must be required by a {@link android.telecom.PhoneAccountSuggestionService},
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature|privileged
+         @SystemApi
+         @hide
+    -->
+    <permission android:name="android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE"
+        android:protectionLevel="signature|privileged" />
+
     <!-- Must be required by a {@link android.telecom.CallRedirectionService},
          to ensure that only the system can bind to it.
          <p>Protection level: signature|privileged
@@ -2206,7 +2215,7 @@
     <!-- ============================================ -->
     <eat-comment />
 
-    <!-- @SystemApi Allows applications to set the system time.
+    <!-- Allows applications to set the system time.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_TIME"
         android:protectionLevel="signature|privileged" />
@@ -2296,7 +2305,7 @@
     <permission android:name="android.permission.SET_SCREEN_COMPATIBILITY"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Allows an application to modify the current configuration, such
+    <!-- Allows an application to modify the current configuration, such
          as locale. -->
     <permission android:name="android.permission.CHANGE_CONFIGURATION"
         android:protectionLevel="signature|privileged|development" />
@@ -2318,7 +2327,7 @@
         android:description="@string/permdesc_writeSettings"
         android:protectionLevel="signature|preinstalled|appop|pre23" />
 
-    <!-- @SystemApi Allows an application to modify the Google service map.
+    <!-- Allows an application to modify the Google service map.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_GSERVICES"
         android:protectionLevel="signature|privileged" />
@@ -2334,7 +2343,7 @@
     <permission android:name="android.permission.RETRIEVE_WINDOW_CONTENT"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Modify the global animation scaling factor.
+    <!-- Modify the global animation scaling factor.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_ANIMATION_SCALE"
         android:protectionLevel="signature|privileged|development" />
@@ -2389,12 +2398,12 @@
         android:description="@string/permdesc_broadcastSticky"
         android:protectionLevel="normal" />
 
-    <!-- @SystemApi Allows mounting and unmounting file systems for removable storage.
+    <!-- Allows mounting and unmounting file systems for removable storage.
     <p>Not for use by third-party applications.-->
     <permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows formatting file systems for removable storage.
+    <!-- Allows formatting file systems for removable storage.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"
         android:protectionLevel="signature|privileged" />
@@ -2428,7 +2437,7 @@
     <permission android:name="android.permission.ASEC_RENAME"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Allows applications to write the apn settings and read sensitive fields of
+    <!-- Allows applications to write the apn settings and read sensitive fields of
          an existing apn settings like user and password.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_APN_SETTINGS"
@@ -2529,40 +2538,40 @@
     <!-- ========================================= -->
     <eat-comment />
 
-    <!-- @SystemApi Allows an application to read or write the secure system settings.
+    <!-- Allows an application to read or write the secure system settings.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.WRITE_SECURE_SETTINGS"
         android:protectionLevel="signature|privileged|development" />
 
-    <!-- @SystemApi Allows an application to retrieve state dump information from system services.
+    <!-- Allows an application to retrieve state dump information from system services.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DUMP"
         android:protectionLevel="signature|privileged|development" />
 
-    <!-- @SystemApi Allows an application to read the low-level system log files.
+    <!-- Allows an application to read the low-level system log files.
     <p>Not for use by third-party applications, because
     Log entries can contain the user's private information. -->
     <permission android:name="android.permission.READ_LOGS"
         android:protectionLevel="signature|privileged|development" />
 
-    <!-- @SystemApi Configure an application for debugging.
+    <!-- Configure an application for debugging.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_DEBUG_APP"
         android:protectionLevel="signature|privileged|development" />
 
-    <!-- @SystemApi Allows an application to set the maximum number of (not needed)
+    <!-- Allows an application to set the maximum number of (not needed)
          application processes that can be running.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_PROCESS_LIMIT"
         android:protectionLevel="signature|privileged|development" />
 
-    <!-- @SystemApi Allows an application to control whether activities are immediately
+    <!-- Allows an application to control whether activities are immediately
          finished when put in the background.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SET_ALWAYS_FINISH"
         android:protectionLevel="signature|privileged|development" />
 
-    <!-- @SystemApi Allow an application to request that a signal be sent to all persistent processes.
+    <!-- Allow an application to request that a signal be sent to all persistent processes.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.SIGNAL_PERSISTENT_PROCESSES"
         android:protectionLevel="signature|privileged|development" />
@@ -2572,7 +2581,7 @@
     <!-- ==================================== -->
     <eat-comment />
 
-    <!-- @SystemApi Allows access to the list of accounts in the Accounts Service. -->
+    <!-- Allows access to the list of accounts in the Accounts Service. -->
     <permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"
         android:protectionLevel="signature|privileged" />
 
@@ -2581,12 +2590,12 @@
     <permission android:name="android.permission.GET_PASSWORD"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Allows applications to RW to diagnostic resources.
+    <!-- Allows applications to RW to diagnostic resources.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.DIAGNOSTIC"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Allows an application to open, close, or disable the status bar
+    <!-- Allows an application to open, close, or disable the status bar
          and its icons.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.STATUS_BAR"
@@ -2611,7 +2620,7 @@
     <permission android:name="android.permission.FORCE_BACK"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Allows an application to update device statistics.
+    <!-- Allows an application to update device statistics.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.UPDATE_DEVICE_STATS"
         android:protectionLevel="signature|privileged" />
@@ -3017,7 +3026,7 @@
         android:description="@string/permdesc_requestDeletePackages"
         android:protectionLevel="normal" />
 
-    <!-- @SystemApi Allows an application to install packages.
+    <!-- Allows an application to install packages.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.INSTALL_PACKAGES"
       android:protectionLevel="signature|privileged" />
@@ -3090,7 +3099,7 @@
     <permission android:name="android.permission.FORCE_PERSISTABLE_URI_PERMISSIONS"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Old permission for deleting an app's cache files, no longer used,
+    <!-- Old permission for deleting an app's cache files, no longer used,
          but signals for us to quietly ignore calls instead of throwing an exception. -->
     <permission android:name="android.permission.DELETE_CACHE_FILES"
         android:protectionLevel="signature|privileged" />
@@ -3100,7 +3109,7 @@
     <permission android:name="android.permission.INTERNAL_DELETE_CACHE_FILES"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Allows an application to delete packages.
+    <!-- Allows an application to delete packages.
          <p>Not for use by third-party applications.
          <p>Starting in {@link android.os.Build.VERSION_CODES#N}, user confirmation is requested
          when the application deleting the package is not the same application that installed the
@@ -3113,7 +3122,7 @@
     <permission android:name="android.permission.MOVE_PACKAGE"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to change whether an application component (other than its own) is
+    <!-- Allows an application to change whether an application component (other than its own) is
          enabled or not.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
@@ -3146,7 +3155,7 @@
     <permission android:name="android.permission.ACCESS_SURFACE_FLINGER"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Allows an application to take screen shots and more generally
+    <!-- Allows an application to take screen shots and more generally
          get access to the frame buffer data.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.READ_FRAME_BUFFER"
@@ -3222,7 +3231,7 @@
         android:protectionLevel="signature|privileged" />
     <uses-permission android:name="android.permission.CONTROL_VPN" />
 
-    <!-- @SystemApi Allows an application to capture audio output.
+    <!-- Allows an application to capture audio output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"
         android:protectionLevel="signature|privileged" />
@@ -3239,17 +3248,17 @@
     <permission android:name="android.permission.MODIFY_AUDIO_ROUTING"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to capture video output.
+    <!-- Allows an application to capture video output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to capture secure video output.
+    <!-- Allows an application to capture secure video output.
          <p>Not for use by third-party applications.</p> -->
     <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to know what content is playing and control its playback.
+    <!-- Allows an application to know what content is playing and control its playback.
          <p>Not for use by third-party applications due to privacy of media consumption</p>  -->
     <permission android:name="android.permission.MEDIA_CONTENT_CONTROL"
         android:protectionLevel="signature|privileged" />
@@ -3276,7 +3285,7 @@
     <permission android:name="android.permission.BRICK"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Required to be able to reboot the device.
+    <!-- Required to be able to reboot the device.
     <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.REBOOT"
         android:protectionLevel="signature|privileged" />
@@ -3331,11 +3340,11 @@
     <permission android:name="android.permission.BROADCAST_NETWORK_PRIVILEGED"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Not for use by third-party applications. -->
+    <!-- Not for use by third-party applications. -->
     <permission android:name="android.permission.MASTER_CLEAR"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to call any phone number, including emergency
+    <!-- Allows an application to call any phone number, including emergency
          numbers, without going through the Dialer user interface for the user
          to confirm the call being placed.
          <p>Not for use by third-party applications. -->
@@ -3350,19 +3359,19 @@
     <permission android:name="android.permission.PERFORM_SIM_ACTIVATION"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows enabling/disabling location update notifications from
+    <!-- Allows enabling/disabling location update notifications from
          the radio.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.CONTROL_LOCATION_UPDATES"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows read/write access to the "properties" table in the checkin
+    <!-- Allows read/write access to the "properties" table in the checkin
          database, to change values that get uploaded.
          <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to collect component usage
+    <!-- Allows an application to collect component usage
          statistics
          <p>Declaring the permission implies intention to use the API and the user of the
          device can grant permission through the Settings application. -->
@@ -3395,7 +3404,7 @@
         android:description="@string/permdesc_requestIgnoreBatteryOptimizations"
         android:protectionLevel="normal" />
 
-    <!-- @SystemApi Allows an application to collect battery statistics -->
+    <!-- Allows an application to collect battery statistics -->
     <permission android:name="android.permission.BATTERY_STATS"
         android:protectionLevel="signature|privileged|development" />
 
@@ -3424,12 +3433,12 @@
     <permission android:name="android.permission.CONFIRM_FULL_BACKUP"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi Must be required by a {@link android.widget.RemoteViewsService},
+    <!-- Must be required by a {@link android.widget.RemoteViewsService},
          to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_REMOTEVIEWS"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows an application to tell the AppWidget service which application
+    <!-- Allows an application to tell the AppWidget service which application
          can access AppWidget's data.  The normal user flow is that a user
          picks an AppWidget to go into a particular host, thereby giving that
          host application access to the private data from the AppWidget app.
@@ -3460,7 +3469,7 @@
     <permission android:name="android.permission.CHANGE_BACKGROUND_DATA_SETTING"
         android:protectionLevel="signature" />
 
-    <!-- @SystemApi This permission can be used on content providers to allow the global
+    <!-- This permission can be used on content providers to allow the global
          search system to access their data.  Typically it used when the
          provider has some permissions protecting it (which global search
          would not be expected to hold), and added as a read-only permission
diff --git a/core/res/res/values-mcc214-mnc01/config.xml b/core/res/res/values-mcc214-mnc01/config.xml
index 876c26e..b34696b 100644
--- a/core/res/res/values-mcc214-mnc01/config.xml
+++ b/core/res/res/values-mcc214-mnc01/config.xml
@@ -30,4 +30,8 @@
       <item>7</item>
       <item>9</item>
     </integer-array>
+
+    <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+    <bool name="config_safe_media_disable_on_volume_up">false</bool>
+
 </resources>
diff --git a/telephony/java/android/telephony/rcs/RcsThread.aidl b/core/res/res/values-mcc234-mnc15/config.xml
similarity index 67%
rename from telephony/java/android/telephony/rcs/RcsThread.aidl
rename to core/res/res/values-mcc234-mnc15/config.xml
index e2e0da5d..84e779d 100644
--- a/telephony/java/android/telephony/rcs/RcsThread.aidl
+++ b/core/res/res/values-mcc234-mnc15/config.xml
@@ -1,5 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
 /*
-**
 ** Copyright 2018, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +15,11 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
+-->
 
-package android.telephony;
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-parcelable RcsThread;
\ No newline at end of file
+    <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+    <bool name="config_safe_media_disable_on_volume_up">false</bool>
+
+</resources>
diff --git a/telephony/java/android/telephony/rcs/RcsThread.aidl b/core/res/res/values-mcc234-mnc91/config.xml
similarity index 67%
copy from telephony/java/android/telephony/rcs/RcsThread.aidl
copy to core/res/res/values-mcc234-mnc91/config.xml
index e2e0da5d..84e779d 100644
--- a/telephony/java/android/telephony/rcs/RcsThread.aidl
+++ b/core/res/res/values-mcc234-mnc91/config.xml
@@ -1,5 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
 /*
-**
 ** Copyright 2018, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +15,11 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
+-->
 
-package android.telephony;
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-parcelable RcsThread;
\ No newline at end of file
+    <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+    <bool name="config_safe_media_disable_on_volume_up">false</bool>
+
+</resources>
diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml
index 7289b4f..36efd0a 100644
--- a/core/res/res/values-mcc302-mnc220/config.xml
+++ b/core/res/res/values-mcc302-mnc220/config.xml
@@ -29,7 +29,7 @@
         <item>SUPL_PORT=7275</item>
         <item>SUPL_VER=0x20000</item>
         <item>SUPL_MODE=1</item>
-        <item>SUPL_ES=0</item>
+        <item>SUPL_ES=1</item>
         <item>LPP_PROFILE=3</item>
         <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
         <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
diff --git a/core/res/res/values-mcc302-mnc221/config.xml b/core/res/res/values-mcc302-mnc221/config.xml
index ff14075..a11dd95 100644
--- a/core/res/res/values-mcc302-mnc221/config.xml
+++ b/core/res/res/values-mcc302-mnc221/config.xml
@@ -26,7 +26,7 @@
         <item>SUPL_PORT=7275</item>
         <item>SUPL_VER=0x20000</item>
         <item>SUPL_MODE=1</item>
-        <item>SUPL_ES=0</item>
+        <item>SUPL_ES=1</item>
         <item>LPP_PROFILE=3</item>
         <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
         <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
diff --git a/core/res/res/values-mcc302-mnc370/config.xml b/core/res/res/values-mcc302-mnc370/config.xml
index ad3a654..8d29ec1 100644
--- a/core/res/res/values-mcc302-mnc370/config.xml
+++ b/core/res/res/values-mcc302-mnc370/config.xml
@@ -30,7 +30,7 @@
         <item>SUPL_PORT=7275</item>
         <item>SUPL_VER=0x20000</item>
         <item>SUPL_MODE=1</item>
-        <item>SUPL_ES=0</item>
+        <item>SUPL_ES=1</item>
         <item>LPP_PROFILE=2</item>
         <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
         <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
diff --git a/core/res/res/values-mcc302-mnc610/config.xml b/core/res/res/values-mcc302-mnc610/config.xml
index 232f149..650aa62 100644
--- a/core/res/res/values-mcc302-mnc610/config.xml
+++ b/core/res/res/values-mcc302-mnc610/config.xml
@@ -28,7 +28,7 @@
         <item>SUPL_PORT=7275</item>
         <item>SUPL_VER=0x20000</item>
         <item>SUPL_MODE=1</item>
-        <item>SUPL_ES=0</item>
+        <item>SUPL_ES=1</item>
         <item>LPP_PROFILE=2</item>
         <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
         <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
diff --git a/core/res/res/values-mcc302-mnc640/config.xml b/core/res/res/values-mcc302-mnc640/config.xml
index 1d2e625..4bb68dc 100644
--- a/core/res/res/values-mcc302-mnc640/config.xml
+++ b/core/res/res/values-mcc302-mnc640/config.xml
@@ -24,7 +24,7 @@
         <item>SUPL_PORT=7275</item>
         <item>SUPL_VER=0x20000</item>
         <item>SUPL_MODE=1</item>
-        <item>SUPL_ES=0</item>
+        <item>SUPL_ES=1</item>
         <item>LPP_PROFILE=2</item>
         <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
         <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml
index cfcf1f8..735a8c8 100644
--- a/core/res/res/values-mcc302-mnc720/config.xml
+++ b/core/res/res/values-mcc302-mnc720/config.xml
@@ -30,7 +30,7 @@
         <item>SUPL_PORT=7275</item>
         <item>SUPL_VER=0x20000</item>
         <item>SUPL_MODE=1</item>
-        <item>SUPL_ES=0</item>
+        <item>SUPL_ES=1</item>
         <item>LPP_PROFILE=2</item>
         <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
         <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 98cb640..31e799d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -659,6 +659,10 @@
     <!-- Boolean indicating whether framework needs to set the tx power limit for meeting SAR requirements -->
     <bool translatable="false" name="config_wifi_framework_enable_sar_tx_power_limit">false</bool>
 
+    <!-- Boolean indicating whether framework should use detection of softAP mode to set the tx
+         power limit for meeting SAR requirements -->
+    <bool translatable="false" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit">false</bool>
+
     <!-- Boolean indicating whether framework needs to use body proximity to set the tx power limit
          for meeting SAR requirements -->
     <bool translatable="false" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit">false</bool>
@@ -2346,6 +2350,9 @@
     <!-- Whether safe headphone volume is enabled or not (country specific). -->
     <bool name="config_safe_media_volume_enabled">true</bool>
 
+    <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+    <bool name="config_safe_media_disable_on_volume_up">true</bool>
+
     <!-- Set to true if the wifi display supports compositing content stored
          in gralloc protected buffers.  For this to be true, there must exist
          a protected hardware path for surface flinger to composite and send
@@ -2768,7 +2775,7 @@
         <item>SUPL_PORT=7275</item>
         <item>SUPL_VER=0x20000</item>
         <item>SUPL_MODE=1</item>
-        <item>SUPL_ES=0</item>
+        <item>SUPL_ES=1</item>
         <item>LPP_PROFILE=0</item>
         <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item>
         <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item>
@@ -2968,6 +2975,10 @@
          -->
     <bool name="config_fillMainBuiltInDisplayCutout">false</bool>
 
+    <!-- If true, and there is a cutout on the main built in display, the cutout will be masked
+         by shrinking the display such that it does not overlap the cutout area. -->
+    <bool name="config_maskMainBuiltInDisplayCutout">false</bool>
+
     <!-- Ultrasound support for Mic/speaker path -->
     <!-- Whether the default microphone audio source supports near-ultrasound frequencies
          (range of 18 - 21 kHz). -->
@@ -3492,6 +3503,13 @@
     <!-- Whether or not we should show the option to show battery percentage -->
     <bool name="config_battery_percentage_setting_available">true</bool>
 
+    <!-- Model of potentially misprovisioned devices. If none is specified in an overlay, an
+         empty string is passed in. -->
+    <string name="config_misprovisionedDeviceModel" translatable="false"></string>
+
+    <!-- Brand value for attestation of misprovisioned device. -->
+    <string name="config_misprovisionedBrandValue" translatable="false"></string>
+
     <!-- Pre-scale volume at volume step 1 for Absolute Volume -->
     <fraction name="config_prescaleAbsoluteVolume_index1">50%</fraction>
 
@@ -3500,4 +3518,8 @@
 
     <!-- Pre-scale volume at volume step 3 for Absolute Volume -->
     <fraction name="config_prescaleAbsoluteVolume_index3">85%</fraction>
+
+    <!-- Component name for default assistant on this device -->
+    <string name="config_defaultAssistantComponentName"></string>
+
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 471170b..73cb59e 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -61,6 +61,15 @@
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
     <dimen name="status_bar_edge_ignore">5dp</dimen>
 
+    <!-- Default radius of the software rounded corners. -->
+    <dimen name="rounded_corner_radius">0dp</dimen>
+    <!-- Radius of the software rounded corners at the top of the display in its natural
+        orientation. If zero, the value of rounded_corner_radius is used. -->
+    <dimen name="rounded_corner_radius_top">0dp</dimen>
+    <!-- Radius of the software rounded corners at the bottom of the display in its natural
+        orientation. If zero, the value of rounded_corner_radius is used. -->
+    <dimen name="rounded_corner_radius_bottom">0dp</dimen>
+
     <!-- Width of the window of the divider bar used to resize docked stacks. -->
     <dimen name="docked_stack_divider_thickness">48dp</dimen>
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 4d5ef68..310aaf4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -310,6 +310,7 @@
   <java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" />
   <java-symbol type="bool" name="config_useDevInputEventForAudioJack" />
   <java-symbol type="bool" name="config_safe_media_volume_enabled" />
+  <java-symbol type="bool" name="config_safe_media_disable_on_volume_up" />
   <java-symbol type="bool" name="config_camera_sound_forced" />
   <java-symbol type="bool" name="config_dontPreferApn" />
   <java-symbol type="bool" name="config_restartRadioAfterProvisioning" />
@@ -338,6 +339,7 @@
   <java-symbol type="bool" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection" />
   <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" />
   <java-symbol type="bool" name="config_wifi_framework_enable_sar_tx_power_limit" />
+  <java-symbol type="bool" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit" />
   <java-symbol type="bool" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit" />
   <java-symbol type="string" name="config_wifi_sar_sensor_type" />
   <java-symbol type="integer" name="config_wifi_framework_sar_free_space_event_id" />
@@ -3406,11 +3408,18 @@
   <java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" />
   <java-symbol type="integer" name="config_defaultNotificationVibrationIntensity" />
 
+  <java-symbol type="bool" name="config_maskMainBuiltInDisplayCutout" />
+
   <java-symbol type="array" name="config_disableApksUnlessMatchedSku_apk_list" />
   <java-symbol type="array" name="config_disableApkUnlessMatchedSku_skus_list" />
 
+  <java-symbol type="string" name="config_misprovisionedDeviceModel" />
+  <java-symbol type="string" name="config_misprovisionedBrandValue" />
+
   <!-- For Bluetooth AbsoluteVolume -->
   <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index1" />
   <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index2" />
   <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index3" />
+
+  <java-symbol type="string" name="config_defaultAssistantComponentName" />
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 4833816..090f9af 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -306,6 +306,7 @@
         <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.QuickContactBadgeSmall.WindowLarge</item>
         <item name="listPopupWindowStyle">@style/Widget.ListPopupWindow</item>
         <item name="popupMenuStyle">@style/Widget.PopupMenu</item>
+        <item name="popupTheme">@null</item>
         <item name="activityChooserViewStyle">@style/Widget.ActivityChooserView</item>
         <item name="fragmentBreadCrumbsStyle">@style/Widget.FragmentBreadCrumbs</item>
         <item name="contextPopupMenuStyle">?attr/popupMenuStyle</item>
diff --git a/core/res/res/values/themes_holo.xml b/core/res/res/values/themes_holo.xml
index cb5b93d..33832d4 100644
--- a/core/res/res/values/themes_holo.xml
+++ b/core/res/res/values/themes_holo.xml
@@ -296,6 +296,7 @@
         <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Holo.QuickContactBadgeSmall.WindowLarge</item>
         <item name="listPopupWindowStyle">@style/Widget.Holo.ListPopupWindow</item>
         <item name="popupMenuStyle">@style/Widget.Holo.PopupMenu</item>
+        <item name="popupTheme">@null</item>
         <item name="stackViewStyle">@style/Widget.Holo.StackView</item>
         <item name="activityChooserViewStyle">@style/Widget.Holo.ActivityChooserView</item>
         <item name="fragmentBreadCrumbsStyle">@style/Widget.Holo.FragmentBreadCrumbs</item>
@@ -658,9 +659,11 @@
         <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Holo.QuickContactBadgeSmall.WindowLarge</item>
         <item name="listPopupWindowStyle">@style/Widget.Holo.Light.ListPopupWindow</item>
         <item name="popupMenuStyle">@style/Widget.Holo.Light.PopupMenu</item>
+        <item name="popupTheme">@null</item>
         <item name="stackViewStyle">@style/Widget.Holo.StackView</item>
         <item name="activityChooserViewStyle">@style/Widget.Holo.Light.ActivityChooserView</item>
         <item name="fragmentBreadCrumbsStyle">@style/Widget.Holo.Light.FragmentBreadCrumbs</item>
+        <item name="contextPopupMenuStyle">?attr/popupMenuStyle</item>
 
         <!-- Preference styles -->
         <item name="preferenceScreenStyle">@style/Preference.Holo.PreferenceScreen</item>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index f2f28937..7f23edf 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -99,6 +99,7 @@
     private static final Set<String> BACKUP_BLACKLISTED_GLOBAL_SETTINGS =
             newHashSet(
                     Settings.Global.ACTIVITY_MANAGER_CONSTANTS,
+                    Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED,
                     Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED,
                     Settings.Global.ADB_ENABLED,
                     Settings.Global.ADD_USERS_WHEN_LOCKED,
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index 6ee74cb..fe45fe7 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -19,6 +19,7 @@
 import static android.view.DisplayCutout.NO_CUTOUT;
 import static android.view.DisplayCutout.fromSpec;
 
+import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.not;
 import static org.hamcrest.Matchers.sameInstance;
 import static org.junit.Assert.assertEquals;
@@ -220,6 +221,19 @@
     }
 
     @Test
+    public void fromSpec_setsSafeInsets_top() {
+        DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z", 200, 400, 2f);
+        assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 20, 0, 0)));
+    }
+
+    @Test
+    public void fromSpec_setsSafeInsets_top_and_bottom() {
+        DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z"
+                + "@bottom M -50,0 v -10,0 h 100 v 20 z", 200, 400, 2f);
+        assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 20, 0, 10)));
+    }
+
+    @Test
     public void parcel_unparcel_nocutout() {
         Parcel p = Parcel.obtain();
 
diff --git a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
index b18fa74..c165b6b 100644
--- a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java
@@ -16,33 +16,6 @@
 
 package com.android.internal.app;
 
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.rule.ActivityTestRule;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.Log;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
@@ -51,11 +24,42 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
 @RunWith(AndroidJUnit4.class)
 public class IntentForwarderActivityTest {
+
     private static final ComponentName FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME =
             new ComponentName(
                     "android",
@@ -77,22 +81,26 @@
 
     private static IntentForwarderActivity.Injector sInjector;
     private static ComponentName sComponentName;
+    private static String sActivityName;
+    private static String sPackageName;
 
     @Mock private IPackageManager mIPm;
     @Mock private PackageManager mPm;
     @Mock private UserManager mUserManager;
+    @Mock private ApplicationInfo mApplicationInfo;
 
     @Rule
     public ActivityTestRule<IntentForwarderWrapperActivity> mActivityRule =
             new ActivityTestRule<>(IntentForwarderWrapperActivity.class, true, false);
 
     private Context mContext;
+    public static final String PHONE_NUMBER = "123-456-789";
 
     @Before
     public void setup() {
         MockitoAnnotations.initMocks(this);
         mContext = InstrumentationRegistry.getTargetContext();
-        sInjector = new TestInjector();
+        sInjector = spy(new TestInjector());
     }
 
     @Test
@@ -252,6 +260,149 @@
         assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn);
     }
 
+    @Test
+    public void shouldSkipDisclosure_notWhitelisted() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_SEND)
+            .setType(TYPE_PLAIN_TEXT);
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector).showToast(anyInt(), anyInt());
+    }
+
+    @Test
+    public void shouldSkipDisclosure_withResolverActivity() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        sActivityName = ResolverActivity.class.getName();
+        sPackageName = "android";
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_SEND)
+            .setType(TYPE_PLAIN_TEXT);
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector, never()).showToast(anyInt(), anyInt());
+    }
+
+    @Test
+    public void shouldSkipDisclosure_callIntent_call() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_CALL);
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector, never()).showToast(anyInt(), anyInt());
+    }
+
+    @Test
+    public void shouldSkipDisclosure_callIntent_dial() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_DIAL);
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector, never()).showToast(anyInt(), anyInt());
+    }
+
+    @Test
+    public void shouldSkipDisclosure_callIntent_notCallOrDial() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_ALARM_CHANGED);
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector).showToast(anyInt(), anyInt());
+    }
+
+    @Test
+    public void shouldSkipDisclosure_textMessageIntent_sms() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_SENDTO)
+            .setData(Uri.fromParts("sms", PHONE_NUMBER, null));
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector, never()).showToast(anyInt(), anyInt());
+    }
+
+    @Test
+    public void shouldSkipDisclosure_textMessageIntent_smsto() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_SENDTO)
+            .setData(Uri.fromParts("smsto", PHONE_NUMBER, null));
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector, never()).showToast(anyInt(), anyInt());
+    }
+
+    @Test
+    public void shouldSkipDisclosure_textMessageIntent_mms() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_SENDTO)
+            .setData(Uri.fromParts("mms", PHONE_NUMBER, null));
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector, never()).showToast(anyInt(), anyInt());
+    }
+
+    @Test
+    public void shouldSkipDisclosure_textMessageIntent_mmsto() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_SENDTO)
+            .setData(Uri.fromParts("mmsto", PHONE_NUMBER, null));
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector, never()).showToast(anyInt(), anyInt());
+    }
+
+    @Test
+    public void shouldSkipDisclosure_textMessageIntent_invalidUri() throws RemoteException {
+        setupShouldSkipDisclosureTest();
+        Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class)
+            .setAction(Intent.ACTION_SENDTO)
+            .setData(Uri.fromParts("invalid", PHONE_NUMBER, null));
+
+        mActivityRule.launchActivity(intent);
+
+        verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt());
+        verify(sInjector).showToast(anyInt(), anyInt());
+    }
+
+    private void setupShouldSkipDisclosureTest() throws RemoteException {
+        sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME;
+        sActivityName = "MyTestActivity";
+        sPackageName = "test.package.name";
+        when(mApplicationInfo.isSystemApp()).thenReturn(true);
+        // Managed profile exists.
+        List<UserInfo> profiles = new ArrayList<>();
+        profiles.add(CURRENT_USER_INFO);
+        profiles.add(MANAGED_PROFILE_INFO);
+        when(mUserManager.getProfiles(anyInt())).thenReturn(profiles);
+        // Intent can be forwarded.
+        when(mIPm.canForwardTo(
+            any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true);
+    }
 
     public static class IntentForwarderWrapperActivity extends IntentForwarderActivity {
         private Intent mStartActivityIntent;
@@ -276,7 +427,7 @@
         }
     }
 
-    class TestInjector implements IntentForwarderActivity.Injector {
+    public class TestInjector implements IntentForwarderActivity.Injector {
 
         @Override
         public IPackageManager getIPackageManager() {
@@ -292,5 +443,21 @@
         public PackageManager getPackageManager() {
             return mPm;
         }
+
+        @Override
+        public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) {
+            ActivityInfo activityInfo = new ActivityInfo();
+            activityInfo.packageName = sPackageName;
+            activityInfo.name = sActivityName;
+            activityInfo.applicationInfo = mApplicationInfo;
+
+            ResolveInfo resolveInfo = new ResolveInfo();
+            resolveInfo.activityInfo = activityInfo;
+
+            return resolveInfo;
+        }
+
+        @Override
+        public void showToast(int messageId, int duration) {}
     }
 }
\ No newline at end of file
diff --git a/data/etc/OWNERS b/data/etc/OWNERS
index bbec474..ea66ee3 100644
--- a/data/etc/OWNERS
+++ b/data/etc/OWNERS
@@ -1 +1 @@
-per-file privapp-permissions-platform.xml = hackbod@android.com, jsharkey@android.com, svetoslavganov@google.com, toddke@google.com, yamasani@google.com
+per-file privapp-permissions-platform.xml = hackbod@android.com, jsharkey@android.com, svetoslavganov@google.com, toddke@google.com, yamasani@google.com, cbrubaker@google.com, jeffv@google.com, moltmann@google.com
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 0082f4b..c8bd847 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -33,6 +33,10 @@
         <permission name="android.permission.CRYPT_KEEPER"/>
     </privapp-permissions>
 
+    <privapp-permissions package="com.android.carrierconfig">
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+    </privapp-permissions>
+
     <privapp-permissions package="com.android.cellbroadcastreceiver">
         <permission name="android.permission.INTERACT_ACROSS_USERS"/>
         <permission name="android.permission.MANAGE_USERS"/>
@@ -315,6 +319,8 @@
         <permission name="android.permission.PACKAGE_USAGE_STATS" />
         <permission name="android.permission.READ_FRAME_BUFFER"/>
         <permission name="android.permission.READ_LOWPAN_CREDENTIAL"/>
+        <!-- Needed for test only -->
+        <permission name="android.permission.READ_PRECISE_PHONE_STATE" />
         <permission name="android.permission.REAL_GET_TASKS"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.REGISTER_CALL_PROVIDER"/>
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 66f4db3..36c1c21 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1600,9 +1600,9 @@
      * Draw the specified circle using the specified paint. If radius is <= 0, then nothing will be
      * drawn. The circle will be filled or framed based on the Style in the paint.
      *
-     * @param cx The x-coordinate of the center of the cirle to be drawn
-     * @param cy The y-coordinate of the center of the cirle to be drawn
-     * @param radius The radius of the cirle to be drawn
+     * @param cx The x-coordinate of the center of the circle to be drawn
+     * @param cy The y-coordinate of the center of the circle to be drawn
+     * @param radius The radius of the circle to be drawn
      * @param paint The paint used to draw the circle
      */
     public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 6ac52d1..36b7e37 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -54,6 +54,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.security.InvalidKeyException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
@@ -303,13 +304,14 @@
     }
 
     /**
-     * List uids of all keys that are auth bound to the current user. 
+     * List uids of all keys that are auth bound to the current user.
      * Only system is allowed to call this method.
      */
     @UnsupportedAppUsage
     public int[] listUidsOfAuthBoundKeys() {
-        final int MAX_RESULT_SIZE = 100;
-        int[] uidsOut = new int[MAX_RESULT_SIZE];
+        // uids are returned as a list of strings because list of integers
+        // as an output parameter is not supported by aidl-cpp.
+        List<String> uidsOut = new ArrayList<>();
         try {
             int rc = mBinder.listUidsOfAuthBoundKeys(uidsOut);
             if (rc != NO_ERROR) {
@@ -323,8 +325,8 @@
             Log.w(TAG, "KeyStore exception", e);
             return null;
         }
-        // Remove any 0 entries
-        return Arrays.stream(uidsOut).filter(x -> x > 0).toArray();
+        // Turn list of strings into an array of uid integers.
+        return uidsOut.stream().mapToInt(Integer::parseInt).toArray();
    }
 
     public String[] list(String prefix) {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 2d04d72..aa29174 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -305,6 +305,9 @@
                 KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
                         mRng, (mKeySizeBits + 7) / 8);
         int flags = 0;
+        if (spec.isStrongBoxBacked()) {
+            flags |= KeyStore.FLAG_STRONGBOX;
+        }
         String keyAliasInKeystore = Credentials.USER_PRIVATE_KEY + spec.getKeystoreAlias();
         KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics();
         boolean success = false;
@@ -318,8 +321,12 @@
                     flags,
                     resultingKeyCharacteristics);
             if (errorCode != KeyStore.NO_ERROR) {
-                throw new ProviderException(
-                        "Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
+                if (errorCode == KeyStore.HARDWARE_TYPE_UNAVAILABLE) {
+                    throw new StrongBoxUnavailableException("Failed to generate key");
+                } else {
+                    throw new ProviderException(
+                            "Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
+                }
             }
             @KeyProperties.KeyAlgorithmEnum String keyAlgorithmJCA;
             try {
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java
index 1be8309..f7993ef 100644
--- a/keystore/java/android/security/keystore/AttestationUtils.java
+++ b/keystore/java/android/security/keystore/AttestationUtils.java
@@ -22,9 +22,9 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.content.Context;
+import android.content.res.Resources;
 import android.os.Build;
 import android.security.KeyStore;
-import android.security.KeyStoreException;
 import android.security.keymaster.KeymasterArguments;
 import android.security.keymaster.KeymasterCertificateChain;
 import android.security.keymaster.KeymasterDefs;
@@ -117,6 +117,40 @@
     @NonNull public static KeymasterArguments prepareAttestationArguments(Context context,
             @NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws
             DeviceIdAttestationException {
+        return prepareAttestationArguments(context, idTypes,attestationChallenge, Build.BRAND);
+    }
+
+    /**
+     * Prepares Keymaster Arguments with attestation data for misprovisioned Pixel 2 device.
+     * See http://go/keyAttestationFailure and http://b/69471841 for more info.
+     * @hide should only be used by KeyChain.
+     */
+    @NonNull public static KeymasterArguments prepareAttestationArgumentsIfMisprovisioned(
+            Context context, @NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws
+            DeviceIdAttestationException {
+        if (!isPotentiallyMisprovisionedDevice(context)) {
+            return null;
+        }
+        Resources resources = context.getResources();
+        String misprovisionedBrand = resources.getString(
+                com.android.internal.R.string.config_misprovisionedBrandValue);
+        return prepareAttestationArguments(
+                    context, idTypes, attestationChallenge, misprovisionedBrand);
+    }
+
+    @NonNull private static boolean isPotentiallyMisprovisionedDevice(Context context) {
+        Resources resources = context.getResources();
+        String misprovisionedModel = resources.getString(
+                com.android.internal.R.string.config_misprovisionedDeviceModel);
+        String misprovisionedBrand = resources.getString(
+                com.android.internal.R.string.config_misprovisionedBrandValue);
+
+        return (Build.MODEL.equals(misprovisionedModel));
+    }
+
+    @NonNull private static KeymasterArguments prepareAttestationArguments(Context context,
+            @NonNull int[] idTypes, @NonNull byte[] attestationChallenge, String brand) throws
+            DeviceIdAttestationException {
         // Check method arguments, retrieve requested device IDs and prepare attestation arguments.
         if (attestationChallenge == null) {
             throw new NullPointerException("Missing attestation challenge");
@@ -169,7 +203,7 @@
             }
         }
         attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND,
-                Build.BRAND.getBytes(StandardCharsets.UTF_8));
+                brand.getBytes(StandardCharsets.UTF_8));
         attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE,
                 Build.DEVICE.getBytes(StandardCharsets.UTF_8));
         attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT,
diff --git a/libs/androidfw/LocaleData.cpp b/libs/androidfw/LocaleData.cpp
index 889d166..020cef6 100644
--- a/libs/androidfw/LocaleData.cpp
+++ b/libs/androidfw/LocaleData.cpp
@@ -34,11 +34,11 @@
 }
 
 inline uint32_t dropRegion(uint32_t packed_locale) {
-    return packed_locale & 0xFFFF0000lu;
+    return packed_locale & 0xFFFF0000LU;
 }
 
 inline bool hasRegion(uint32_t packed_locale) {
-    return (packed_locale & 0x0000FFFFlu) != 0;
+    return (packed_locale & 0x0000FFFFLU) != 0;
 }
 
 const size_t SCRIPT_LENGTH = 4;
@@ -122,9 +122,9 @@
     return (REPRESENTATIVE_LOCALES.count(packed_locale) != 0);
 }
 
-const uint32_t US_SPANISH = 0x65735553lu; // es-US
-const uint32_t MEXICAN_SPANISH = 0x65734D58lu; // es-MX
-const uint32_t LATIN_AMERICAN_SPANISH = 0x6573A424lu; // es-419
+const uint32_t US_SPANISH = 0x65735553LU; // es-US
+const uint32_t MEXICAN_SPANISH = 0x65734D58LU; // es-MX
+const uint32_t LATIN_AMERICAN_SPANISH = 0x6573A424LU; // es-419
 
 // The two locales es-US and es-MX are treated as special fallbacks for es-419.
 // If there is no es-419, they are considered its equivalent.
@@ -225,8 +225,8 @@
 }
 
 const uint32_t ENGLISH_STOP_LIST[2] = {
-    0x656E0000lu, // en
-    0x656E8400lu, // en-001
+    0x656E0000LU, // en
+    0x656E8400LU, // en-001
 };
 const char ENGLISH_CHARS[2] = {'e', 'n'};
 const char LATIN_CHARS[4] = {'L', 'a', 't', 'n'};
diff --git a/libs/androidfw/LocaleDataTables.cpp b/libs/androidfw/LocaleDataTables.cpp
index 7c381ef..c276a23 100644
--- a/libs/androidfw/LocaleDataTables.cpp
+++ b/libs/androidfw/LocaleDataTables.cpp
@@ -1446,733 +1446,733 @@
 });
 
 std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({
-    0x616145544C61746Ellu, // aa_Latn_ET
-    0x616247454379726Cllu, // ab_Cyrl_GE
-    0xC42047484C61746Ellu, // abr_Latn_GH
-    0x904049444C61746Ellu, // ace_Latn_ID
-    0x9C4055474C61746Ellu, // ach_Latn_UG
-    0x806047484C61746Ellu, // ada_Latn_GH
-    0xE06052554379726Cllu, // ady_Cyrl_RU
-    0x6165495241767374llu, // ae_Avst_IR
-    0x8480544E41726162llu, // aeb_Arab_TN
-    0x61665A414C61746Ellu, // af_Latn_ZA
-    0xC0C0434D4C61746Ellu, // agq_Latn_CM
-    0xB8E0494E41686F6Dllu, // aho_Ahom_IN
-    0x616B47484C61746Ellu, // ak_Latn_GH
-    0xA940495158737578llu, // akk_Xsux_IQ
-    0xB560584B4C61746Ellu, // aln_Latn_XK
-    0xCD6052554379726Cllu, // alt_Cyrl_RU
-    0x616D455445746869llu, // am_Ethi_ET
-    0xB9804E474C61746Ellu, // amo_Latn_NG
-    0xE5C049444C61746Ellu, // aoz_Latn_ID
-    0x8DE0544741726162llu, // apd_Arab_TG
-    0x6172454741726162llu, // ar_Arab_EG
-    0x8A20495241726D69llu, // arc_Armi_IR
-    0x8A204A4F4E626174llu, // arc_Nbat_JO
-    0x8A20535950616C6Dllu, // arc_Palm_SY
-    0xB620434C4C61746Ellu, // arn_Latn_CL
-    0xBA20424F4C61746Ellu, // aro_Latn_BO
-    0xC220445A41726162llu, // arq_Arab_DZ
-    0xE2204D4141726162llu, // ary_Arab_MA
-    0xE620454741726162llu, // arz_Arab_EG
-    0x6173494E42656E67llu, // as_Beng_IN
-    0x8240545A4C61746Ellu, // asa_Latn_TZ
-    0x9240555353676E77llu, // ase_Sgnw_US
-    0xCE4045534C61746Ellu, // ast_Latn_ES
-    0xA66043414C61746Ellu, // atj_Latn_CA
-    0x617652554379726Cllu, // av_Cyrl_RU
-    0x82C0494E44657661llu, // awa_Deva_IN
-    0x6179424F4C61746Ellu, // ay_Latn_BO
-    0x617A495241726162llu, // az_Arab_IR
-    0x617A415A4C61746Ellu, // az_Latn_AZ
-    0x626152554379726Cllu, // ba_Cyrl_RU
-    0xAC01504B41726162llu, // bal_Arab_PK
-    0xB40149444C61746Ellu, // ban_Latn_ID
-    0xBC014E5044657661llu, // bap_Deva_NP
-    0xC40141544C61746Ellu, // bar_Latn_AT
-    0xC801434D4C61746Ellu, // bas_Latn_CM
-    0xDC01434D42616D75llu, // bax_Bamu_CM
-    0x882149444C61746Ellu, // bbc_Latn_ID
-    0xA421434D4C61746Ellu, // bbj_Latn_CM
-    0xA04143494C61746Ellu, // bci_Latn_CI
-    0x626542594379726Cllu, // be_Cyrl_BY
-    0xA481534441726162llu, // bej_Arab_SD
-    0xB0815A4D4C61746Ellu, // bem_Latn_ZM
-    0xD88149444C61746Ellu, // bew_Latn_ID
-    0xE481545A4C61746Ellu, // bez_Latn_TZ
-    0x8CA1434D4C61746Ellu, // bfd_Latn_CM
-    0xC0A1494E54616D6Cllu, // bfq_Taml_IN
-    0xCCA1504B41726162llu, // bft_Arab_PK
-    0xE0A1494E44657661llu, // bfy_Deva_IN
-    0x626742474379726Cllu, // bg_Cyrl_BG
-    0x88C1494E44657661llu, // bgc_Deva_IN
-    0xB4C1504B41726162llu, // bgn_Arab_PK
-    0xDCC154524772656Bllu, // bgx_Grek_TR
-    0x84E1494E44657661llu, // bhb_Deva_IN
-    0xA0E1494E44657661llu, // bhi_Deva_IN
-    0xA8E150484C61746Ellu, // bhk_Latn_PH
-    0xB8E1494E44657661llu, // bho_Deva_IN
-    0x626956554C61746Ellu, // bi_Latn_VU
-    0xA90150484C61746Ellu, // bik_Latn_PH
-    0xB5014E474C61746Ellu, // bin_Latn_NG
-    0xA521494E44657661llu, // bjj_Deva_IN
-    0xB52149444C61746Ellu, // bjn_Latn_ID
-    0xB141434D4C61746Ellu, // bkm_Latn_CM
-    0xD14150484C61746Ellu, // bku_Latn_PH
-    0xCD61564E54617674llu, // blt_Tavt_VN
-    0x626D4D4C4C61746Ellu, // bm_Latn_ML
-    0xC1814D4C4C61746Ellu, // bmq_Latn_ML
-    0x626E424442656E67llu, // bn_Beng_BD
-    0x626F434E54696274llu, // bo_Tibt_CN
-    0xE1E1494E42656E67llu, // bpy_Beng_IN
-    0xA201495241726162llu, // bqi_Arab_IR
-    0xD60143494C61746Ellu, // bqv_Latn_CI
-    0x627246524C61746Ellu, // br_Latn_FR
-    0x8221494E44657661llu, // bra_Deva_IN
-    0x9E21504B41726162llu, // brh_Arab_PK
-    0xDE21494E44657661llu, // brx_Deva_IN
-    0x627342414C61746Ellu, // bs_Latn_BA
-    0xC2414C5242617373llu, // bsq_Bass_LR
-    0xCA41434D4C61746Ellu, // bss_Latn_CM
-    0xBA6150484C61746Ellu, // bto_Latn_PH
-    0xD661504B44657661llu, // btv_Deva_PK
-    0x828152554379726Cllu, // bua_Cyrl_RU
-    0x8A8159544C61746Ellu, // buc_Latn_YT
-    0x9A8149444C61746Ellu, // bug_Latn_ID
-    0xB281434D4C61746Ellu, // bum_Latn_CM
-    0x86A147514C61746Ellu, // bvb_Latn_GQ
-    0xB701455245746869llu, // byn_Ethi_ER
-    0xD701434D4C61746Ellu, // byv_Latn_CM
-    0x93214D4C4C61746Ellu, // bze_Latn_ML
-    0x636145534C61746Ellu, // ca_Latn_ES
-    0x9C424E474C61746Ellu, // cch_Latn_NG
-    0xBC42494E42656E67llu, // ccp_Beng_IN
-    0xBC42424443616B6Dllu, // ccp_Cakm_BD
-    0x636552554379726Cllu, // ce_Cyrl_RU
-    0x848250484C61746Ellu, // ceb_Latn_PH
-    0x98C255474C61746Ellu, // cgg_Latn_UG
-    0x636847554C61746Ellu, // ch_Latn_GU
-    0xA8E2464D4C61746Ellu, // chk_Latn_FM
-    0xB0E252554379726Cllu, // chm_Cyrl_RU
-    0xB8E255534C61746Ellu, // cho_Latn_US
-    0xBCE243414C61746Ellu, // chp_Latn_CA
-    0xC4E2555343686572llu, // chr_Cher_US
-    0x81224B4841726162llu, // cja_Arab_KH
-    0xB122564E4368616Dllu, // cjm_Cham_VN
-    0x8542495141726162llu, // ckb_Arab_IQ
-    0x636F46524C61746Ellu, // co_Latn_FR
-    0xBDC24547436F7074llu, // cop_Copt_EG
-    0xC9E250484C61746Ellu, // cps_Latn_PH
-    0x6372434143616E73llu, // cr_Cans_CA
-    0xA622434143616E73llu, // crj_Cans_CA
-    0xAA22434143616E73llu, // crk_Cans_CA
-    0xAE22434143616E73llu, // crl_Cans_CA
-    0xB222434143616E73llu, // crm_Cans_CA
-    0xCA2253434C61746Ellu, // crs_Latn_SC
-    0x6373435A4C61746Ellu, // cs_Latn_CZ
-    0x8642504C4C61746Ellu, // csb_Latn_PL
-    0xDA42434143616E73llu, // csw_Cans_CA
-    0x8E624D4D50617563llu, // ctd_Pauc_MM
-    0x637552554379726Cllu, // cu_Cyrl_RU
-    0x63754247476C6167llu, // cu_Glag_BG
-    0x637652554379726Cllu, // cv_Cyrl_RU
-    0x637947424C61746Ellu, // cy_Latn_GB
-    0x6461444B4C61746Ellu, // da_Latn_DK
-    0xA80355534C61746Ellu, // dak_Latn_US
-    0xC40352554379726Cllu, // dar_Cyrl_RU
-    0xD4034B454C61746Ellu, // dav_Latn_KE
-    0x8843494E41726162llu, // dcc_Arab_IN
-    0x646544454C61746Ellu, // de_Latn_DE
-    0xB48343414C61746Ellu, // den_Latn_CA
-    0xC4C343414C61746Ellu, // dgr_Latn_CA
-    0x91234E454C61746Ellu, // dje_Latn_NE
-    0xA5A343494C61746Ellu, // dnj_Latn_CI
-    0xA1C3494E41726162llu, // doi_Arab_IN
-    0x864344454C61746Ellu, // dsb_Latn_DE
-    0xB2634D4C4C61746Ellu, // dtm_Latn_ML
-    0xBE634D594C61746Ellu, // dtp_Latn_MY
-    0xE2634E5044657661llu, // dty_Deva_NP
-    0x8283434D4C61746Ellu, // dua_Latn_CM
-    0x64764D5654686161llu, // dv_Thaa_MV
-    0xBB03534E4C61746Ellu, // dyo_Latn_SN
-    0xD30342464C61746Ellu, // dyu_Latn_BF
-    0x647A425454696274llu, // dz_Tibt_BT
-    0xD0244B454C61746Ellu, // ebu_Latn_KE
-    0x656547484C61746Ellu, // ee_Latn_GH
-    0xA0A44E474C61746Ellu, // efi_Latn_NG
-    0xACC449544C61746Ellu, // egl_Latn_IT
-    0xE0C4454745677970llu, // egy_Egyp_EG
-    0xE1444D4D4B616C69llu, // eky_Kali_MM
-    0x656C47524772656Bllu, // el_Grek_GR
-    0x656E47424C61746Ellu, // en_Latn_GB
-    0x656E55534C61746Ellu, // en_Latn_US
-    0x656E474253686177llu, // en_Shaw_GB
-    0x657345534C61746Ellu, // es_Latn_ES
-    0x65734D584C61746Ellu, // es_Latn_MX
-    0x657355534C61746Ellu, // es_Latn_US
-    0xD24455534C61746Ellu, // esu_Latn_US
-    0x657445454C61746Ellu, // et_Latn_EE
-    0xCE6449544974616Cllu, // ett_Ital_IT
-    0x657545534C61746Ellu, // eu_Latn_ES
-    0xBAC4434D4C61746Ellu, // ewo_Latn_CM
-    0xCEE445534C61746Ellu, // ext_Latn_ES
-    0x6661495241726162llu, // fa_Arab_IR
-    0xB40547514C61746Ellu, // fan_Latn_GQ
-    0x6666474E41646C6Dllu, // ff_Adlm_GN
-    0x6666534E4C61746Ellu, // ff_Latn_SN
-    0xB0A54D4C4C61746Ellu, // ffm_Latn_ML
-    0x666946494C61746Ellu, // fi_Latn_FI
-    0x8105534441726162llu, // fia_Arab_SD
-    0xAD0550484C61746Ellu, // fil_Latn_PH
-    0xCD0553454C61746Ellu, // fit_Latn_SE
-    0x666A464A4C61746Ellu, // fj_Latn_FJ
-    0x666F464F4C61746Ellu, // fo_Latn_FO
-    0xB5C5424A4C61746Ellu, // fon_Latn_BJ
-    0x667246524C61746Ellu, // fr_Latn_FR
-    0x8A2555534C61746Ellu, // frc_Latn_US
-    0xBE2546524C61746Ellu, // frp_Latn_FR
-    0xC62544454C61746Ellu, // frr_Latn_DE
-    0xCA2544454C61746Ellu, // frs_Latn_DE
-    0x8685434D41726162llu, // fub_Arab_CM
-    0x8E8557464C61746Ellu, // fud_Latn_WF
-    0x9685474E4C61746Ellu, // fuf_Latn_GN
-    0xC2854E454C61746Ellu, // fuq_Latn_NE
-    0xC68549544C61746Ellu, // fur_Latn_IT
-    0xD6854E474C61746Ellu, // fuv_Latn_NG
-    0xC6A553444C61746Ellu, // fvr_Latn_SD
-    0x66794E4C4C61746Ellu, // fy_Latn_NL
-    0x676149454C61746Ellu, // ga_Latn_IE
-    0x800647484C61746Ellu, // gaa_Latn_GH
-    0x98064D444C61746Ellu, // gag_Latn_MD
-    0xB406434E48616E73llu, // gan_Hans_CN
-    0xE00649444C61746Ellu, // gay_Latn_ID
-    0xB026494E44657661llu, // gbm_Deva_IN
-    0xE426495241726162llu, // gbz_Arab_IR
-    0xC44647464C61746Ellu, // gcr_Latn_GF
-    0x676447424C61746Ellu, // gd_Latn_GB
-    0xE486455445746869llu, // gez_Ethi_ET
-    0xB4C64E5044657661llu, // ggn_Deva_NP
-    0xAD064B494C61746Ellu, // gil_Latn_KI
-    0xA926504B41726162llu, // gjk_Arab_PK
-    0xD126504B41726162llu, // gju_Arab_PK
-    0x676C45534C61746Ellu, // gl_Latn_ES
-    0xA966495241726162llu, // glk_Arab_IR
-    0x676E50594C61746Ellu, // gn_Latn_PY
-    0xB1C6494E44657661llu, // gom_Deva_IN
-    0xB5C6494E54656C75llu, // gon_Telu_IN
-    0xC5C649444C61746Ellu, // gor_Latn_ID
-    0xC9C64E4C4C61746Ellu, // gos_Latn_NL
-    0xCDC65541476F7468llu, // got_Goth_UA
-    0x8A26435943707274llu, // grc_Cprt_CY
-    0x8A2647524C696E62llu, // grc_Linb_GR
-    0xCE26494E42656E67llu, // grt_Beng_IN
-    0xDA4643484C61746Ellu, // gsw_Latn_CH
-    0x6775494E47756A72llu, // gu_Gujr_IN
-    0x868642524C61746Ellu, // gub_Latn_BR
-    0x8A86434F4C61746Ellu, // guc_Latn_CO
-    0xC68647484C61746Ellu, // gur_Latn_GH
-    0xE6864B454C61746Ellu, // guz_Latn_KE
-    0x6776494D4C61746Ellu, // gv_Latn_IM
-    0xC6A64E5044657661llu, // gvr_Deva_NP
-    0xA2C643414C61746Ellu, // gwi_Latn_CA
-    0x68614E474C61746Ellu, // ha_Latn_NG
-    0xA807434E48616E73llu, // hak_Hans_CN
-    0xD80755534C61746Ellu, // haw_Latn_US
-    0xE407414641726162llu, // haz_Arab_AF
-    0x6865494C48656272llu, // he_Hebr_IL
-    0x6869494E44657661llu, // hi_Deva_IN
-    0x9507464A4C61746Ellu, // hif_Latn_FJ
-    0xAD0750484C61746Ellu, // hil_Latn_PH
-    0xD1675452486C7577llu, // hlu_Hluw_TR
-    0x8D87434E506C7264llu, // hmd_Plrd_CN
-    0x8DA7504B41726162llu, // hnd_Arab_PK
-    0x91A7494E44657661llu, // hne_Deva_IN
-    0xA5A74C41486D6E67llu, // hnj_Hmng_LA
-    0xB5A750484C61746Ellu, // hnn_Latn_PH
-    0xB9A7504B41726162llu, // hno_Arab_PK
-    0x686F50474C61746Ellu, // ho_Latn_PG
-    0x89C7494E44657661llu, // hoc_Deva_IN
-    0xA5C7494E44657661llu, // hoj_Deva_IN
-    0x687248524C61746Ellu, // hr_Latn_HR
-    0x864744454C61746Ellu, // hsb_Latn_DE
-    0xB647434E48616E73llu, // hsn_Hans_CN
-    0x687448544C61746Ellu, // ht_Latn_HT
-    0x687548554C61746Ellu, // hu_Latn_HU
-    0x6879414D41726D6Ellu, // hy_Armn_AM
-    0x687A4E414C61746Ellu, // hz_Latn_NA
-    0x696146524C61746Ellu, // ia_Latn_FR
-    0x80284D594C61746Ellu, // iba_Latn_MY
-    0x84284E474C61746Ellu, // ibb_Latn_NG
-    0x696449444C61746Ellu, // id_Latn_ID
-    0x69674E474C61746Ellu, // ig_Latn_NG
-    0x6969434E59696969llu, // ii_Yiii_CN
-    0x696B55534C61746Ellu, // ik_Latn_US
-    0xCD4843414C61746Ellu, // ikt_Latn_CA
-    0xB96850484C61746Ellu, // ilo_Latn_PH
-    0x696E49444C61746Ellu, // in_Latn_ID
-    0x9DA852554379726Cllu, // inh_Cyrl_RU
-    0x697349534C61746Ellu, // is_Latn_IS
-    0x697449544C61746Ellu, // it_Latn_IT
-    0x6975434143616E73llu, // iu_Cans_CA
-    0x6977494C48656272llu, // iw_Hebr_IL
-    0x9F2852554C61746Ellu, // izh_Latn_RU
-    0x6A614A504A70616Ellu, // ja_Jpan_JP
-    0xB0094A4D4C61746Ellu, // jam_Latn_JM
-    0xB8C9434D4C61746Ellu, // jgo_Latn_CM
-    0x8989545A4C61746Ellu, // jmc_Latn_TZ
-    0xAD894E5044657661llu, // jml_Deva_NP
-    0xCE89444B4C61746Ellu, // jut_Latn_DK
-    0x6A7649444C61746Ellu, // jv_Latn_ID
-    0x6A7749444C61746Ellu, // jw_Latn_ID
-    0x6B61474547656F72llu, // ka_Geor_GE
-    0x800A555A4379726Cllu, // kaa_Cyrl_UZ
-    0x840A445A4C61746Ellu, // kab_Latn_DZ
-    0x880A4D4D4C61746Ellu, // kac_Latn_MM
-    0xA40A4E474C61746Ellu, // kaj_Latn_NG
-    0xB00A4B454C61746Ellu, // kam_Latn_KE
-    0xB80A4D4C4C61746Ellu, // kao_Latn_ML
-    0x8C2A52554379726Cllu, // kbd_Cyrl_RU
-    0xE02A4E4541726162llu, // kby_Arab_NE
-    0x984A4E474C61746Ellu, // kcg_Latn_NG
-    0xA84A5A574C61746Ellu, // kck_Latn_ZW
-    0x906A545A4C61746Ellu, // kde_Latn_TZ
-    0x9C6A544741726162llu, // kdh_Arab_TG
-    0xCC6A544854686169llu, // kdt_Thai_TH
-    0x808A43564C61746Ellu, // kea_Latn_CV
-    0xB48A434D4C61746Ellu, // ken_Latn_CM
-    0xB8AA43494C61746Ellu, // kfo_Latn_CI
-    0xC4AA494E44657661llu, // kfr_Deva_IN
-    0xE0AA494E44657661llu, // kfy_Deva_IN
-    0x6B6743444C61746Ellu, // kg_Latn_CD
-    0x90CA49444C61746Ellu, // kge_Latn_ID
-    0xBCCA42524C61746Ellu, // kgp_Latn_BR
-    0x80EA494E4C61746Ellu, // kha_Latn_IN
-    0x84EA434E54616C75llu, // khb_Talu_CN
-    0xB4EA494E44657661llu, // khn_Deva_IN
-    0xC0EA4D4C4C61746Ellu, // khq_Latn_ML
-    0xCCEA494E4D796D72llu, // kht_Mymr_IN
-    0xD8EA504B41726162llu, // khw_Arab_PK
-    0x6B694B454C61746Ellu, // ki_Latn_KE
-    0xD10A54524C61746Ellu, // kiu_Latn_TR
-    0x6B6A4E414C61746Ellu, // kj_Latn_NA
-    0x992A4C414C616F6Fllu, // kjg_Laoo_LA
-    0x6B6B434E41726162llu, // kk_Arab_CN
-    0x6B6B4B5A4379726Cllu, // kk_Cyrl_KZ
-    0xA54A434D4C61746Ellu, // kkj_Latn_CM
-    0x6B6C474C4C61746Ellu, // kl_Latn_GL
-    0xB56A4B454C61746Ellu, // kln_Latn_KE
-    0x6B6D4B484B686D72llu, // km_Khmr_KH
-    0x858A414F4C61746Ellu, // kmb_Latn_AO
-    0x6B6E494E4B6E6461llu, // kn_Knda_IN
-    0x6B6F4B524B6F7265llu, // ko_Kore_KR
-    0xA1CA52554379726Cllu, // koi_Cyrl_RU
-    0xA9CA494E44657661llu, // kok_Deva_IN
-    0xC9CA464D4C61746Ellu, // kos_Latn_FM
-    0x91EA4C524C61746Ellu, // kpe_Latn_LR
-    0x8A2A52554379726Cllu, // krc_Cyrl_RU
-    0xA22A534C4C61746Ellu, // kri_Latn_SL
-    0xA62A50484C61746Ellu, // krj_Latn_PH
-    0xAE2A52554C61746Ellu, // krl_Latn_RU
-    0xD22A494E44657661llu, // kru_Deva_IN
-    0x6B73494E41726162llu, // ks_Arab_IN
-    0x864A545A4C61746Ellu, // ksb_Latn_TZ
-    0x964A434D4C61746Ellu, // ksf_Latn_CM
-    0x9E4A44454C61746Ellu, // ksh_Latn_DE
-    0x6B75495141726162llu, // ku_Arab_IQ
-    0x6B7554524C61746Ellu, // ku_Latn_TR
-    0xB28A52554379726Cllu, // kum_Cyrl_RU
-    0x6B7652554379726Cllu, // kv_Cyrl_RU
-    0xC6AA49444C61746Ellu, // kvr_Latn_ID
-    0xDEAA504B41726162llu, // kvx_Arab_PK
-    0x6B7747424C61746Ellu, // kw_Latn_GB
-    0xB2EA544854686169llu, // kxm_Thai_TH
-    0xBEEA504B41726162llu, // kxp_Arab_PK
-    0x6B79434E41726162llu, // ky_Arab_CN
-    0x6B794B474379726Cllu, // ky_Cyrl_KG
-    0x6B7954524C61746Ellu, // ky_Latn_TR
-    0x6C6156414C61746Ellu, // la_Latn_VA
-    0x840B47524C696E61llu, // lab_Lina_GR
-    0x8C0B494C48656272llu, // lad_Hebr_IL
-    0x980B545A4C61746Ellu, // lag_Latn_TZ
-    0x9C0B504B41726162llu, // lah_Arab_PK
-    0xA40B55474C61746Ellu, // laj_Latn_UG
-    0x6C624C554C61746Ellu, // lb_Latn_LU
-    0x902B52554379726Cllu, // lbe_Cyrl_RU
-    0xD82B49444C61746Ellu, // lbw_Latn_ID
-    0xBC4B434E54686169llu, // lcp_Thai_CN
-    0xBC8B494E4C657063llu, // lep_Lepc_IN
-    0xE48B52554379726Cllu, // lez_Cyrl_RU
-    0x6C6755474C61746Ellu, // lg_Latn_UG
-    0x6C694E4C4C61746Ellu, // li_Latn_NL
-    0x950B4E5044657661llu, // lif_Deva_NP
-    0x950B494E4C696D62llu, // lif_Limb_IN
-    0xA50B49544C61746Ellu, // lij_Latn_IT
-    0xC90B434E4C697375llu, // lis_Lisu_CN
-    0xBD2B49444C61746Ellu, // ljp_Latn_ID
-    0xA14B495241726162llu, // lki_Arab_IR
-    0xCD4B55534C61746Ellu, // lkt_Latn_US
-    0xB58B494E54656C75llu, // lmn_Telu_IN
-    0xB98B49544C61746Ellu, // lmo_Latn_IT
-    0x6C6E43444C61746Ellu, // ln_Latn_CD
-    0x6C6F4C414C616F6Fllu, // lo_Laoo_LA
-    0xADCB43444C61746Ellu, // lol_Latn_CD
-    0xE5CB5A4D4C61746Ellu, // loz_Latn_ZM
-    0x8A2B495241726162llu, // lrc_Arab_IR
-    0x6C744C544C61746Ellu, // lt_Latn_LT
-    0x9A6B4C564C61746Ellu, // ltg_Latn_LV
-    0x6C7543444C61746Ellu, // lu_Latn_CD
-    0x828B43444C61746Ellu, // lua_Latn_CD
-    0xBA8B4B454C61746Ellu, // luo_Latn_KE
-    0xE28B4B454C61746Ellu, // luy_Latn_KE
-    0xE68B495241726162llu, // luz_Arab_IR
-    0x6C764C564C61746Ellu, // lv_Latn_LV
-    0xAECB544854686169llu, // lwl_Thai_TH
-    0x9F2B434E48616E73llu, // lzh_Hans_CN
-    0xE72B54524C61746Ellu, // lzz_Latn_TR
-    0x8C0C49444C61746Ellu, // mad_Latn_ID
-    0x940C434D4C61746Ellu, // maf_Latn_CM
-    0x980C494E44657661llu, // mag_Deva_IN
-    0xA00C494E44657661llu, // mai_Deva_IN
-    0xA80C49444C61746Ellu, // mak_Latn_ID
-    0xB40C474D4C61746Ellu, // man_Latn_GM
-    0xB40C474E4E6B6F6Fllu, // man_Nkoo_GN
-    0xC80C4B454C61746Ellu, // mas_Latn_KE
-    0xE40C4D584C61746Ellu, // maz_Latn_MX
-    0x946C52554379726Cllu, // mdf_Cyrl_RU
-    0x9C6C50484C61746Ellu, // mdh_Latn_PH
-    0xC46C49444C61746Ellu, // mdr_Latn_ID
-    0xB48C534C4C61746Ellu, // men_Latn_SL
-    0xC48C4B454C61746Ellu, // mer_Latn_KE
-    0x80AC544841726162llu, // mfa_Arab_TH
-    0x90AC4D554C61746Ellu, // mfe_Latn_MU
-    0x6D674D474C61746Ellu, // mg_Latn_MG
-    0x9CCC4D5A4C61746Ellu, // mgh_Latn_MZ
-    0xB8CC434D4C61746Ellu, // mgo_Latn_CM
-    0xBCCC4E5044657661llu, // mgp_Deva_NP
-    0xE0CC545A4C61746Ellu, // mgy_Latn_TZ
-    0x6D684D484C61746Ellu, // mh_Latn_MH
-    0x6D694E5A4C61746Ellu, // mi_Latn_NZ
-    0xB50C49444C61746Ellu, // min_Latn_ID
-    0xC90C495148617472llu, // mis_Hatr_IQ
-    0x6D6B4D4B4379726Cllu, // mk_Cyrl_MK
-    0x6D6C494E4D6C796Dllu, // ml_Mlym_IN
-    0xC96C53444C61746Ellu, // mls_Latn_SD
-    0x6D6E4D4E4379726Cllu, // mn_Cyrl_MN
-    0x6D6E434E4D6F6E67llu, // mn_Mong_CN
-    0xA1AC494E42656E67llu, // mni_Beng_IN
-    0xD9AC4D4D4D796D72llu, // mnw_Mymr_MM
-    0x91CC43414C61746Ellu, // moe_Latn_CA
-    0x9DCC43414C61746Ellu, // moh_Latn_CA
-    0xC9CC42464C61746Ellu, // mos_Latn_BF
-    0x6D72494E44657661llu, // mr_Deva_IN
-    0x8E2C4E5044657661llu, // mrd_Deva_NP
-    0xA62C52554379726Cllu, // mrj_Cyrl_RU
-    0xBA2C42444D726F6Fllu, // mro_Mroo_BD
-    0x6D734D594C61746Ellu, // ms_Latn_MY
-    0x6D744D544C61746Ellu, // mt_Latn_MT
-    0xC66C494E44657661llu, // mtr_Deva_IN
-    0x828C434D4C61746Ellu, // mua_Latn_CM
-    0xCA8C55534C61746Ellu, // mus_Latn_US
-    0xE2AC504B41726162llu, // mvy_Arab_PK
-    0xAACC4D4C4C61746Ellu, // mwk_Latn_ML
-    0xC6CC494E44657661llu, // mwr_Deva_IN
-    0xD6CC49444C61746Ellu, // mwv_Latn_ID
-    0x8AEC5A574C61746Ellu, // mxc_Latn_ZW
-    0x6D794D4D4D796D72llu, // my_Mymr_MM
-    0xD70C52554379726Cllu, // myv_Cyrl_RU
-    0xDF0C55474C61746Ellu, // myx_Latn_UG
-    0xE70C49524D616E64llu, // myz_Mand_IR
-    0xB72C495241726162llu, // mzn_Arab_IR
-    0x6E614E524C61746Ellu, // na_Latn_NR
-    0xB40D434E48616E73llu, // nan_Hans_CN
-    0xBC0D49544C61746Ellu, // nap_Latn_IT
-    0xC00D4E414C61746Ellu, // naq_Latn_NA
-    0x6E624E4F4C61746Ellu, // nb_Latn_NO
-    0x9C4D4D584C61746Ellu, // nch_Latn_MX
-    0x6E645A574C61746Ellu, // nd_Latn_ZW
-    0x886D4D5A4C61746Ellu, // ndc_Latn_MZ
-    0xC86D44454C61746Ellu, // nds_Latn_DE
-    0x6E654E5044657661llu, // ne_Deva_NP
-    0xD88D4E5044657661llu, // new_Deva_NP
-    0x6E674E414C61746Ellu, // ng_Latn_NA
-    0xACCD4D5A4C61746Ellu, // ngl_Latn_MZ
-    0x90ED4D584C61746Ellu, // nhe_Latn_MX
-    0xD8ED4D584C61746Ellu, // nhw_Latn_MX
-    0xA50D49444C61746Ellu, // nij_Latn_ID
-    0xD10D4E554C61746Ellu, // niu_Latn_NU
-    0xB92D494E4C61746Ellu, // njo_Latn_IN
-    0x6E6C4E4C4C61746Ellu, // nl_Latn_NL
-    0x998D434D4C61746Ellu, // nmg_Latn_CM
-    0x6E6E4E4F4C61746Ellu, // nn_Latn_NO
-    0x9DAD434D4C61746Ellu, // nnh_Latn_CM
-    0x6E6F4E4F4C61746Ellu, // no_Latn_NO
-    0x8DCD54484C616E61llu, // nod_Lana_TH
-    0x91CD494E44657661llu, // noe_Deva_IN
-    0xB5CD534552756E72llu, // non_Runr_SE
-    0xBA0D474E4E6B6F6Fllu, // nqo_Nkoo_GN
-    0x6E725A414C61746Ellu, // nr_Latn_ZA
-    0xAA4D434143616E73llu, // nsk_Cans_CA
-    0xBA4D5A414C61746Ellu, // nso_Latn_ZA
-    0xCA8D53534C61746Ellu, // nus_Latn_SS
-    0x6E7655534C61746Ellu, // nv_Latn_US
-    0xC2ED434E4C61746Ellu, // nxq_Latn_CN
-    0x6E794D574C61746Ellu, // ny_Latn_MW
-    0xB30D545A4C61746Ellu, // nym_Latn_TZ
-    0xB70D55474C61746Ellu, // nyn_Latn_UG
-    0xA32D47484C61746Ellu, // nzi_Latn_GH
-    0x6F6346524C61746Ellu, // oc_Latn_FR
-    0x6F6D45544C61746Ellu, // om_Latn_ET
-    0x6F72494E4F727961llu, // or_Orya_IN
-    0x6F7347454379726Cllu, // os_Cyrl_GE
-    0x824E55534F736765llu, // osa_Osge_US
-    0xAA6E4D4E4F726B68llu, // otk_Orkh_MN
-    0x7061504B41726162llu, // pa_Arab_PK
-    0x7061494E47757275llu, // pa_Guru_IN
-    0x980F50484C61746Ellu, // pag_Latn_PH
-    0xAC0F495250686C69llu, // pal_Phli_IR
-    0xAC0F434E50686C70llu, // pal_Phlp_CN
-    0xB00F50484C61746Ellu, // pam_Latn_PH
-    0xBC0F41574C61746Ellu, // pap_Latn_AW
-    0xD00F50574C61746Ellu, // pau_Latn_PW
-    0x8C4F46524C61746Ellu, // pcd_Latn_FR
-    0xB04F4E474C61746Ellu, // pcm_Latn_NG
-    0x886F55534C61746Ellu, // pdc_Latn_US
-    0xCC6F43414C61746Ellu, // pdt_Latn_CA
-    0xB88F49525870656Fllu, // peo_Xpeo_IR
-    0xACAF44454C61746Ellu, // pfl_Latn_DE
-    0xB4EF4C4250686E78llu, // phn_Phnx_LB
-    0x814F494E42726168llu, // pka_Brah_IN
-    0xB94F4B454C61746Ellu, // pko_Latn_KE
-    0x706C504C4C61746Ellu, // pl_Latn_PL
-    0xC98F49544C61746Ellu, // pms_Latn_IT
-    0xCDAF47524772656Bllu, // pnt_Grek_GR
-    0xB5CF464D4C61746Ellu, // pon_Latn_FM
-    0x822F504B4B686172llu, // pra_Khar_PK
-    0x8E2F495241726162llu, // prd_Arab_IR
-    0x7073414641726162llu, // ps_Arab_AF
-    0x707442524C61746Ellu, // pt_Latn_BR
-    0xD28F47414C61746Ellu, // puu_Latn_GA
-    0x717550454C61746Ellu, // qu_Latn_PE
-    0x8A9047544C61746Ellu, // quc_Latn_GT
-    0x9A9045434C61746Ellu, // qug_Latn_EC
-    0xA411494E44657661llu, // raj_Deva_IN
-    0x945152454C61746Ellu, // rcf_Latn_RE
-    0xA49149444C61746Ellu, // rej_Latn_ID
-    0xB4D149544C61746Ellu, // rgn_Latn_IT
-    0x8111494E4C61746Ellu, // ria_Latn_IN
-    0x95114D4154666E67llu, // rif_Tfng_MA
-    0xC9314E5044657661llu, // rjs_Deva_NP
-    0xCD51424442656E67llu, // rkt_Beng_BD
-    0x726D43484C61746Ellu, // rm_Latn_CH
-    0x959146494C61746Ellu, // rmf_Latn_FI
-    0xB99143484C61746Ellu, // rmo_Latn_CH
-    0xCD91495241726162llu, // rmt_Arab_IR
-    0xD19153454C61746Ellu, // rmu_Latn_SE
-    0x726E42494C61746Ellu, // rn_Latn_BI
-    0x99B14D5A4C61746Ellu, // rng_Latn_MZ
-    0x726F524F4C61746Ellu, // ro_Latn_RO
-    0x85D149444C61746Ellu, // rob_Latn_ID
-    0x95D1545A4C61746Ellu, // rof_Latn_TZ
-    0xB271464A4C61746Ellu, // rtm_Latn_FJ
-    0x727552554379726Cllu, // ru_Cyrl_RU
-    0x929155414379726Cllu, // rue_Cyrl_UA
-    0x9A9153424C61746Ellu, // rug_Latn_SB
-    0x727752574C61746Ellu, // rw_Latn_RW
-    0xAAD1545A4C61746Ellu, // rwk_Latn_TZ
-    0xD3114A504B616E61llu, // ryu_Kana_JP
-    0x7361494E44657661llu, // sa_Deva_IN
-    0x941247484C61746Ellu, // saf_Latn_GH
-    0x9C1252554379726Cllu, // sah_Cyrl_RU
-    0xC0124B454C61746Ellu, // saq_Latn_KE
-    0xC81249444C61746Ellu, // sas_Latn_ID
-    0xCC12494E4C61746Ellu, // sat_Latn_IN
-    0xE412494E53617572llu, // saz_Saur_IN
-    0xBC32545A4C61746Ellu, // sbp_Latn_TZ
-    0x736349544C61746Ellu, // sc_Latn_IT
-    0xA852494E44657661llu, // sck_Deva_IN
-    0xB45249544C61746Ellu, // scn_Latn_IT
-    0xB85247424C61746Ellu, // sco_Latn_GB
-    0xC85243414C61746Ellu, // scs_Latn_CA
-    0x7364504B41726162llu, // sd_Arab_PK
-    0x7364494E44657661llu, // sd_Deva_IN
-    0x7364494E4B686F6Allu, // sd_Khoj_IN
-    0x7364494E53696E64llu, // sd_Sind_IN
-    0x887249544C61746Ellu, // sdc_Latn_IT
-    0x9C72495241726162llu, // sdh_Arab_IR
-    0x73654E4F4C61746Ellu, // se_Latn_NO
-    0x949243494C61746Ellu, // sef_Latn_CI
-    0x9C924D5A4C61746Ellu, // seh_Latn_MZ
-    0xA0924D584C61746Ellu, // sei_Latn_MX
-    0xC8924D4C4C61746Ellu, // ses_Latn_ML
-    0x736743464C61746Ellu, // sg_Latn_CF
-    0x80D249454F67616Dllu, // sga_Ogam_IE
-    0xC8D24C544C61746Ellu, // sgs_Latn_LT
-    0xA0F24D4154666E67llu, // shi_Tfng_MA
-    0xB4F24D4D4D796D72llu, // shn_Mymr_MM
-    0x73694C4B53696E68llu, // si_Sinh_LK
-    0x8D1245544C61746Ellu, // sid_Latn_ET
-    0x736B534B4C61746Ellu, // sk_Latn_SK
-    0xC552504B41726162llu, // skr_Arab_PK
-    0x736C53494C61746Ellu, // sl_Latn_SI
-    0xA172504C4C61746Ellu, // sli_Latn_PL
-    0xE17249444C61746Ellu, // sly_Latn_ID
-    0x736D57534C61746Ellu, // sm_Latn_WS
-    0x819253454C61746Ellu, // sma_Latn_SE
-    0xA59253454C61746Ellu, // smj_Latn_SE
-    0xB59246494C61746Ellu, // smn_Latn_FI
-    0xBD92494C53616D72llu, // smp_Samr_IL
-    0xC99246494C61746Ellu, // sms_Latn_FI
-    0x736E5A574C61746Ellu, // sn_Latn_ZW
-    0xA9B24D4C4C61746Ellu, // snk_Latn_ML
-    0x736F534F4C61746Ellu, // so_Latn_SO
-    0xD1D2544854686169llu, // sou_Thai_TH
-    0x7371414C4C61746Ellu, // sq_Latn_AL
-    0x737252534379726Cllu, // sr_Cyrl_RS
-    0x737252534C61746Ellu, // sr_Latn_RS
-    0x8632494E536F7261llu, // srb_Sora_IN
-    0xB63253524C61746Ellu, // srn_Latn_SR
-    0xC632534E4C61746Ellu, // srr_Latn_SN
-    0xDE32494E44657661llu, // srx_Deva_IN
-    0x73735A414C61746Ellu, // ss_Latn_ZA
-    0xE25245524C61746Ellu, // ssy_Latn_ER
-    0x73745A414C61746Ellu, // st_Latn_ZA
-    0xC27244454C61746Ellu, // stq_Latn_DE
-    0x737549444C61746Ellu, // su_Latn_ID
-    0xAA92545A4C61746Ellu, // suk_Latn_TZ
-    0xCA92474E4C61746Ellu, // sus_Latn_GN
-    0x737653454C61746Ellu, // sv_Latn_SE
-    0x7377545A4C61746Ellu, // sw_Latn_TZ
-    0x86D2595441726162llu, // swb_Arab_YT
-    0x8AD243444C61746Ellu, // swc_Latn_CD
-    0x9AD244454C61746Ellu, // swg_Latn_DE
-    0xD6D2494E44657661llu, // swv_Deva_IN
-    0xB6F249444C61746Ellu, // sxn_Latn_ID
-    0xAF12424442656E67llu, // syl_Beng_BD
-    0xC712495153797263llu, // syr_Syrc_IQ
-    0xAF32504C4C61746Ellu, // szl_Latn_PL
-    0x7461494E54616D6Cllu, // ta_Taml_IN
-    0xA4134E5044657661llu, // taj_Deva_NP
-    0xD83350484C61746Ellu, // tbw_Latn_PH
-    0xE053494E4B6E6461llu, // tcy_Knda_IN
-    0x8C73434E54616C65llu, // tdd_Tale_CN
-    0x98734E5044657661llu, // tdg_Deva_NP
-    0x9C734E5044657661llu, // tdh_Deva_NP
-    0x7465494E54656C75llu, // te_Telu_IN
-    0xB093534C4C61746Ellu, // tem_Latn_SL
-    0xB89355474C61746Ellu, // teo_Latn_UG
-    0xCC93544C4C61746Ellu, // tet_Latn_TL
-    0x7467504B41726162llu, // tg_Arab_PK
-    0x7467544A4379726Cllu, // tg_Cyrl_TJ
-    0x7468544854686169llu, // th_Thai_TH
-    0xACF34E5044657661llu, // thl_Deva_NP
-    0xC0F34E5044657661llu, // thq_Deva_NP
-    0xC4F34E5044657661llu, // thr_Deva_NP
-    0x7469455445746869llu, // ti_Ethi_ET
-    0x9913455245746869llu, // tig_Ethi_ER
-    0xD5134E474C61746Ellu, // tiv_Latn_NG
-    0x746B544D4C61746Ellu, // tk_Latn_TM
-    0xAD53544B4C61746Ellu, // tkl_Latn_TK
-    0xC553415A4C61746Ellu, // tkr_Latn_AZ
-    0xCD534E5044657661llu, // tkt_Deva_NP
-    0x746C50484C61746Ellu, // tl_Latn_PH
-    0xE173415A4C61746Ellu, // tly_Latn_AZ
-    0x9D934E454C61746Ellu, // tmh_Latn_NE
-    0x746E5A414C61746Ellu, // tn_Latn_ZA
-    0x746F544F4C61746Ellu, // to_Latn_TO
-    0x99D34D574C61746Ellu, // tog_Latn_MW
-    0xA1F350474C61746Ellu, // tpi_Latn_PG
-    0x747254524C61746Ellu, // tr_Latn_TR
-    0xD23354524C61746Ellu, // tru_Latn_TR
-    0xD63354574C61746Ellu, // trv_Latn_TW
-    0x74735A414C61746Ellu, // ts_Latn_ZA
-    0x8E5347524772656Bllu, // tsd_Grek_GR
-    0x96534E5044657661llu, // tsf_Deva_NP
-    0x9A5350484C61746Ellu, // tsg_Latn_PH
-    0xA653425454696274llu, // tsj_Tibt_BT
-    0x747452554379726Cllu, // tt_Cyrl_RU
-    0xA67355474C61746Ellu, // ttj_Latn_UG
-    0xCA73544854686169llu, // tts_Thai_TH
-    0xCE73415A4C61746Ellu, // ttt_Latn_AZ
-    0xB2934D574C61746Ellu, // tum_Latn_MW
-    0xAEB354564C61746Ellu, // tvl_Latn_TV
-    0xC2D34E454C61746Ellu, // twq_Latn_NE
-    0x9AF3434E54616E67llu, // txg_Tang_CN
-    0x747950464C61746Ellu, // ty_Latn_PF
-    0xD71352554379726Cllu, // tyv_Cyrl_RU
-    0xB3334D414C61746Ellu, // tzm_Latn_MA
-    0xB07452554379726Cllu, // udm_Cyrl_RU
-    0x7567434E41726162llu, // ug_Arab_CN
-    0x75674B5A4379726Cllu, // ug_Cyrl_KZ
-    0x80D4535955676172llu, // uga_Ugar_SY
-    0x756B55414379726Cllu, // uk_Cyrl_UA
-    0xA174464D4C61746Ellu, // uli_Latn_FM
-    0x8594414F4C61746Ellu, // umb_Latn_AO
-    0xC5B4494E42656E67llu, // unr_Beng_IN
-    0xC5B44E5044657661llu, // unr_Deva_NP
-    0xDDB4494E42656E67llu, // unx_Beng_IN
-    0x7572504B41726162llu, // ur_Arab_PK
-    0x757A414641726162llu, // uz_Arab_AF
-    0x757A555A4C61746Ellu, // uz_Latn_UZ
-    0xA0154C5256616969llu, // vai_Vaii_LR
-    0x76655A414C61746Ellu, // ve_Latn_ZA
-    0x889549544C61746Ellu, // vec_Latn_IT
-    0xBC9552554C61746Ellu, // vep_Latn_RU
-    0x7669564E4C61746Ellu, // vi_Latn_VN
-    0x891553584C61746Ellu, // vic_Latn_SX
-    0xC97542454C61746Ellu, // vls_Latn_BE
-    0x959544454C61746Ellu, // vmf_Latn_DE
-    0xD9954D5A4C61746Ellu, // vmw_Latn_MZ
-    0xCDD552554C61746Ellu, // vot_Latn_RU
-    0xBA3545454C61746Ellu, // vro_Latn_EE
-    0xB695545A4C61746Ellu, // vun_Latn_TZ
-    0x776142454C61746Ellu, // wa_Latn_BE
-    0x901643484C61746Ellu, // wae_Latn_CH
-    0xAC16455445746869llu, // wal_Ethi_ET
-    0xC41650484C61746Ellu, // war_Latn_PH
-    0xBC3641554C61746Ellu, // wbp_Latn_AU
-    0xC036494E54656C75llu, // wbq_Telu_IN
-    0xC436494E44657661llu, // wbr_Deva_IN
-    0xC97657464C61746Ellu, // wls_Latn_WF
-    0xA1B64B4D41726162llu, // wni_Arab_KM
-    0x776F534E4C61746Ellu, // wo_Latn_SN
-    0xB276494E44657661llu, // wtm_Deva_IN
-    0xD296434E48616E73llu, // wuu_Hans_CN
-    0xD41742524C61746Ellu, // xav_Latn_BR
-    0xC457545243617269llu, // xcr_Cari_TR
-    0x78685A414C61746Ellu, // xh_Latn_ZA
-    0x897754524C796369llu, // xlc_Lyci_TR
-    0x8D7754524C796469llu, // xld_Lydi_TR
-    0x9597474547656F72llu, // xmf_Geor_GE
-    0xB597434E4D616E69llu, // xmn_Mani_CN
-    0xC59753444D657263llu, // xmr_Merc_SD
-    0x81B753414E617262llu, // xna_Narb_SA
-    0xC5B7494E44657661llu, // xnr_Deva_IN
-    0x99D755474C61746Ellu, // xog_Latn_UG
-    0xC5F7495250727469llu, // xpr_Prti_IR
-    0x8257594553617262llu, // xsa_Sarb_YE
-    0xC6574E5044657661llu, // xsr_Deva_NP
-    0xB8184D5A4C61746Ellu, // yao_Latn_MZ
-    0xBC18464D4C61746Ellu, // yap_Latn_FM
-    0xD418434D4C61746Ellu, // yav_Latn_CM
-    0x8438434D4C61746Ellu, // ybb_Latn_CM
-    0x796F4E474C61746Ellu, // yo_Latn_NG
-    0xAE3842524C61746Ellu, // yrl_Latn_BR
-    0x82984D584C61746Ellu, // yua_Latn_MX
-    0x9298434E48616E73llu, // yue_Hans_CN
-    0x9298484B48616E74llu, // yue_Hant_HK
-    0x7A61434E4C61746Ellu, // za_Latn_CN
-    0x981953444C61746Ellu, // zag_Latn_SD
-    0xA4794B4D41726162llu, // zdj_Arab_KM
-    0x80994E4C4C61746Ellu, // zea_Latn_NL
-    0x9CD94D4154666E67llu, // zgh_Tfng_MA
-    0x7A685457426F706Fllu, // zh_Bopo_TW
-    0x7A68545748616E62llu, // zh_Hanb_TW
-    0x7A68434E48616E73llu, // zh_Hans_CN
-    0x7A68545748616E74llu, // zh_Hant_TW
-    0xB17954474C61746Ellu, // zlm_Latn_TG
-    0xA1994D594C61746Ellu, // zmi_Latn_MY
-    0x7A755A414C61746Ellu, // zu_Latn_ZA
-    0x833954524C61746Ellu, // zza_Latn_TR
+    0x616145544C61746ELLU, // aa_Latn_ET
+    0x616247454379726CLLU, // ab_Cyrl_GE
+    0xC42047484C61746ELLU, // abr_Latn_GH
+    0x904049444C61746ELLU, // ace_Latn_ID
+    0x9C4055474C61746ELLU, // ach_Latn_UG
+    0x806047484C61746ELLU, // ada_Latn_GH
+    0xE06052554379726CLLU, // ady_Cyrl_RU
+    0x6165495241767374LLU, // ae_Avst_IR
+    0x8480544E41726162LLU, // aeb_Arab_TN
+    0x61665A414C61746ELLU, // af_Latn_ZA
+    0xC0C0434D4C61746ELLU, // agq_Latn_CM
+    0xB8E0494E41686F6DLLU, // aho_Ahom_IN
+    0x616B47484C61746ELLU, // ak_Latn_GH
+    0xA940495158737578LLU, // akk_Xsux_IQ
+    0xB560584B4C61746ELLU, // aln_Latn_XK
+    0xCD6052554379726CLLU, // alt_Cyrl_RU
+    0x616D455445746869LLU, // am_Ethi_ET
+    0xB9804E474C61746ELLU, // amo_Latn_NG
+    0xE5C049444C61746ELLU, // aoz_Latn_ID
+    0x8DE0544741726162LLU, // apd_Arab_TG
+    0x6172454741726162LLU, // ar_Arab_EG
+    0x8A20495241726D69LLU, // arc_Armi_IR
+    0x8A204A4F4E626174LLU, // arc_Nbat_JO
+    0x8A20535950616C6DLLU, // arc_Palm_SY
+    0xB620434C4C61746ELLU, // arn_Latn_CL
+    0xBA20424F4C61746ELLU, // aro_Latn_BO
+    0xC220445A41726162LLU, // arq_Arab_DZ
+    0xE2204D4141726162LLU, // ary_Arab_MA
+    0xE620454741726162LLU, // arz_Arab_EG
+    0x6173494E42656E67LLU, // as_Beng_IN
+    0x8240545A4C61746ELLU, // asa_Latn_TZ
+    0x9240555353676E77LLU, // ase_Sgnw_US
+    0xCE4045534C61746ELLU, // ast_Latn_ES
+    0xA66043414C61746ELLU, // atj_Latn_CA
+    0x617652554379726CLLU, // av_Cyrl_RU
+    0x82C0494E44657661LLU, // awa_Deva_IN
+    0x6179424F4C61746ELLU, // ay_Latn_BO
+    0x617A495241726162LLU, // az_Arab_IR
+    0x617A415A4C61746ELLU, // az_Latn_AZ
+    0x626152554379726CLLU, // ba_Cyrl_RU
+    0xAC01504B41726162LLU, // bal_Arab_PK
+    0xB40149444C61746ELLU, // ban_Latn_ID
+    0xBC014E5044657661LLU, // bap_Deva_NP
+    0xC40141544C61746ELLU, // bar_Latn_AT
+    0xC801434D4C61746ELLU, // bas_Latn_CM
+    0xDC01434D42616D75LLU, // bax_Bamu_CM
+    0x882149444C61746ELLU, // bbc_Latn_ID
+    0xA421434D4C61746ELLU, // bbj_Latn_CM
+    0xA04143494C61746ELLU, // bci_Latn_CI
+    0x626542594379726CLLU, // be_Cyrl_BY
+    0xA481534441726162LLU, // bej_Arab_SD
+    0xB0815A4D4C61746ELLU, // bem_Latn_ZM
+    0xD88149444C61746ELLU, // bew_Latn_ID
+    0xE481545A4C61746ELLU, // bez_Latn_TZ
+    0x8CA1434D4C61746ELLU, // bfd_Latn_CM
+    0xC0A1494E54616D6CLLU, // bfq_Taml_IN
+    0xCCA1504B41726162LLU, // bft_Arab_PK
+    0xE0A1494E44657661LLU, // bfy_Deva_IN
+    0x626742474379726CLLU, // bg_Cyrl_BG
+    0x88C1494E44657661LLU, // bgc_Deva_IN
+    0xB4C1504B41726162LLU, // bgn_Arab_PK
+    0xDCC154524772656BLLU, // bgx_Grek_TR
+    0x84E1494E44657661LLU, // bhb_Deva_IN
+    0xA0E1494E44657661LLU, // bhi_Deva_IN
+    0xA8E150484C61746ELLU, // bhk_Latn_PH
+    0xB8E1494E44657661LLU, // bho_Deva_IN
+    0x626956554C61746ELLU, // bi_Latn_VU
+    0xA90150484C61746ELLU, // bik_Latn_PH
+    0xB5014E474C61746ELLU, // bin_Latn_NG
+    0xA521494E44657661LLU, // bjj_Deva_IN
+    0xB52149444C61746ELLU, // bjn_Latn_ID
+    0xB141434D4C61746ELLU, // bkm_Latn_CM
+    0xD14150484C61746ELLU, // bku_Latn_PH
+    0xCD61564E54617674LLU, // blt_Tavt_VN
+    0x626D4D4C4C61746ELLU, // bm_Latn_ML
+    0xC1814D4C4C61746ELLU, // bmq_Latn_ML
+    0x626E424442656E67LLU, // bn_Beng_BD
+    0x626F434E54696274LLU, // bo_Tibt_CN
+    0xE1E1494E42656E67LLU, // bpy_Beng_IN
+    0xA201495241726162LLU, // bqi_Arab_IR
+    0xD60143494C61746ELLU, // bqv_Latn_CI
+    0x627246524C61746ELLU, // br_Latn_FR
+    0x8221494E44657661LLU, // bra_Deva_IN
+    0x9E21504B41726162LLU, // brh_Arab_PK
+    0xDE21494E44657661LLU, // brx_Deva_IN
+    0x627342414C61746ELLU, // bs_Latn_BA
+    0xC2414C5242617373LLU, // bsq_Bass_LR
+    0xCA41434D4C61746ELLU, // bss_Latn_CM
+    0xBA6150484C61746ELLU, // bto_Latn_PH
+    0xD661504B44657661LLU, // btv_Deva_PK
+    0x828152554379726CLLU, // bua_Cyrl_RU
+    0x8A8159544C61746ELLU, // buc_Latn_YT
+    0x9A8149444C61746ELLU, // bug_Latn_ID
+    0xB281434D4C61746ELLU, // bum_Latn_CM
+    0x86A147514C61746ELLU, // bvb_Latn_GQ
+    0xB701455245746869LLU, // byn_Ethi_ER
+    0xD701434D4C61746ELLU, // byv_Latn_CM
+    0x93214D4C4C61746ELLU, // bze_Latn_ML
+    0x636145534C61746ELLU, // ca_Latn_ES
+    0x9C424E474C61746ELLU, // cch_Latn_NG
+    0xBC42494E42656E67LLU, // ccp_Beng_IN
+    0xBC42424443616B6DLLU, // ccp_Cakm_BD
+    0x636552554379726CLLU, // ce_Cyrl_RU
+    0x848250484C61746ELLU, // ceb_Latn_PH
+    0x98C255474C61746ELLU, // cgg_Latn_UG
+    0x636847554C61746ELLU, // ch_Latn_GU
+    0xA8E2464D4C61746ELLU, // chk_Latn_FM
+    0xB0E252554379726CLLU, // chm_Cyrl_RU
+    0xB8E255534C61746ELLU, // cho_Latn_US
+    0xBCE243414C61746ELLU, // chp_Latn_CA
+    0xC4E2555343686572LLU, // chr_Cher_US
+    0x81224B4841726162LLU, // cja_Arab_KH
+    0xB122564E4368616DLLU, // cjm_Cham_VN
+    0x8542495141726162LLU, // ckb_Arab_IQ
+    0x636F46524C61746ELLU, // co_Latn_FR
+    0xBDC24547436F7074LLU, // cop_Copt_EG
+    0xC9E250484C61746ELLU, // cps_Latn_PH
+    0x6372434143616E73LLU, // cr_Cans_CA
+    0xA622434143616E73LLU, // crj_Cans_CA
+    0xAA22434143616E73LLU, // crk_Cans_CA
+    0xAE22434143616E73LLU, // crl_Cans_CA
+    0xB222434143616E73LLU, // crm_Cans_CA
+    0xCA2253434C61746ELLU, // crs_Latn_SC
+    0x6373435A4C61746ELLU, // cs_Latn_CZ
+    0x8642504C4C61746ELLU, // csb_Latn_PL
+    0xDA42434143616E73LLU, // csw_Cans_CA
+    0x8E624D4D50617563LLU, // ctd_Pauc_MM
+    0x637552554379726CLLU, // cu_Cyrl_RU
+    0x63754247476C6167LLU, // cu_Glag_BG
+    0x637652554379726CLLU, // cv_Cyrl_RU
+    0x637947424C61746ELLU, // cy_Latn_GB
+    0x6461444B4C61746ELLU, // da_Latn_DK
+    0xA80355534C61746ELLU, // dak_Latn_US
+    0xC40352554379726CLLU, // dar_Cyrl_RU
+    0xD4034B454C61746ELLU, // dav_Latn_KE
+    0x8843494E41726162LLU, // dcc_Arab_IN
+    0x646544454C61746ELLU, // de_Latn_DE
+    0xB48343414C61746ELLU, // den_Latn_CA
+    0xC4C343414C61746ELLU, // dgr_Latn_CA
+    0x91234E454C61746ELLU, // dje_Latn_NE
+    0xA5A343494C61746ELLU, // dnj_Latn_CI
+    0xA1C3494E41726162LLU, // doi_Arab_IN
+    0x864344454C61746ELLU, // dsb_Latn_DE
+    0xB2634D4C4C61746ELLU, // dtm_Latn_ML
+    0xBE634D594C61746ELLU, // dtp_Latn_MY
+    0xE2634E5044657661LLU, // dty_Deva_NP
+    0x8283434D4C61746ELLU, // dua_Latn_CM
+    0x64764D5654686161LLU, // dv_Thaa_MV
+    0xBB03534E4C61746ELLU, // dyo_Latn_SN
+    0xD30342464C61746ELLU, // dyu_Latn_BF
+    0x647A425454696274LLU, // dz_Tibt_BT
+    0xD0244B454C61746ELLU, // ebu_Latn_KE
+    0x656547484C61746ELLU, // ee_Latn_GH
+    0xA0A44E474C61746ELLU, // efi_Latn_NG
+    0xACC449544C61746ELLU, // egl_Latn_IT
+    0xE0C4454745677970LLU, // egy_Egyp_EG
+    0xE1444D4D4B616C69LLU, // eky_Kali_MM
+    0x656C47524772656BLLU, // el_Grek_GR
+    0x656E47424C61746ELLU, // en_Latn_GB
+    0x656E55534C61746ELLU, // en_Latn_US
+    0x656E474253686177LLU, // en_Shaw_GB
+    0x657345534C61746ELLU, // es_Latn_ES
+    0x65734D584C61746ELLU, // es_Latn_MX
+    0x657355534C61746ELLU, // es_Latn_US
+    0xD24455534C61746ELLU, // esu_Latn_US
+    0x657445454C61746ELLU, // et_Latn_EE
+    0xCE6449544974616CLLU, // ett_Ital_IT
+    0x657545534C61746ELLU, // eu_Latn_ES
+    0xBAC4434D4C61746ELLU, // ewo_Latn_CM
+    0xCEE445534C61746ELLU, // ext_Latn_ES
+    0x6661495241726162LLU, // fa_Arab_IR
+    0xB40547514C61746ELLU, // fan_Latn_GQ
+    0x6666474E41646C6DLLU, // ff_Adlm_GN
+    0x6666534E4C61746ELLU, // ff_Latn_SN
+    0xB0A54D4C4C61746ELLU, // ffm_Latn_ML
+    0x666946494C61746ELLU, // fi_Latn_FI
+    0x8105534441726162LLU, // fia_Arab_SD
+    0xAD0550484C61746ELLU, // fil_Latn_PH
+    0xCD0553454C61746ELLU, // fit_Latn_SE
+    0x666A464A4C61746ELLU, // fj_Latn_FJ
+    0x666F464F4C61746ELLU, // fo_Latn_FO
+    0xB5C5424A4C61746ELLU, // fon_Latn_BJ
+    0x667246524C61746ELLU, // fr_Latn_FR
+    0x8A2555534C61746ELLU, // frc_Latn_US
+    0xBE2546524C61746ELLU, // frp_Latn_FR
+    0xC62544454C61746ELLU, // frr_Latn_DE
+    0xCA2544454C61746ELLU, // frs_Latn_DE
+    0x8685434D41726162LLU, // fub_Arab_CM
+    0x8E8557464C61746ELLU, // fud_Latn_WF
+    0x9685474E4C61746ELLU, // fuf_Latn_GN
+    0xC2854E454C61746ELLU, // fuq_Latn_NE
+    0xC68549544C61746ELLU, // fur_Latn_IT
+    0xD6854E474C61746ELLU, // fuv_Latn_NG
+    0xC6A553444C61746ELLU, // fvr_Latn_SD
+    0x66794E4C4C61746ELLU, // fy_Latn_NL
+    0x676149454C61746ELLU, // ga_Latn_IE
+    0x800647484C61746ELLU, // gaa_Latn_GH
+    0x98064D444C61746ELLU, // gag_Latn_MD
+    0xB406434E48616E73LLU, // gan_Hans_CN
+    0xE00649444C61746ELLU, // gay_Latn_ID
+    0xB026494E44657661LLU, // gbm_Deva_IN
+    0xE426495241726162LLU, // gbz_Arab_IR
+    0xC44647464C61746ELLU, // gcr_Latn_GF
+    0x676447424C61746ELLU, // gd_Latn_GB
+    0xE486455445746869LLU, // gez_Ethi_ET
+    0xB4C64E5044657661LLU, // ggn_Deva_NP
+    0xAD064B494C61746ELLU, // gil_Latn_KI
+    0xA926504B41726162LLU, // gjk_Arab_PK
+    0xD126504B41726162LLU, // gju_Arab_PK
+    0x676C45534C61746ELLU, // gl_Latn_ES
+    0xA966495241726162LLU, // glk_Arab_IR
+    0x676E50594C61746ELLU, // gn_Latn_PY
+    0xB1C6494E44657661LLU, // gom_Deva_IN
+    0xB5C6494E54656C75LLU, // gon_Telu_IN
+    0xC5C649444C61746ELLU, // gor_Latn_ID
+    0xC9C64E4C4C61746ELLU, // gos_Latn_NL
+    0xCDC65541476F7468LLU, // got_Goth_UA
+    0x8A26435943707274LLU, // grc_Cprt_CY
+    0x8A2647524C696E62LLU, // grc_Linb_GR
+    0xCE26494E42656E67LLU, // grt_Beng_IN
+    0xDA4643484C61746ELLU, // gsw_Latn_CH
+    0x6775494E47756A72LLU, // gu_Gujr_IN
+    0x868642524C61746ELLU, // gub_Latn_BR
+    0x8A86434F4C61746ELLU, // guc_Latn_CO
+    0xC68647484C61746ELLU, // gur_Latn_GH
+    0xE6864B454C61746ELLU, // guz_Latn_KE
+    0x6776494D4C61746ELLU, // gv_Latn_IM
+    0xC6A64E5044657661LLU, // gvr_Deva_NP
+    0xA2C643414C61746ELLU, // gwi_Latn_CA
+    0x68614E474C61746ELLU, // ha_Latn_NG
+    0xA807434E48616E73LLU, // hak_Hans_CN
+    0xD80755534C61746ELLU, // haw_Latn_US
+    0xE407414641726162LLU, // haz_Arab_AF
+    0x6865494C48656272LLU, // he_Hebr_IL
+    0x6869494E44657661LLU, // hi_Deva_IN
+    0x9507464A4C61746ELLU, // hif_Latn_FJ
+    0xAD0750484C61746ELLU, // hil_Latn_PH
+    0xD1675452486C7577LLU, // hlu_Hluw_TR
+    0x8D87434E506C7264LLU, // hmd_Plrd_CN
+    0x8DA7504B41726162LLU, // hnd_Arab_PK
+    0x91A7494E44657661LLU, // hne_Deva_IN
+    0xA5A74C41486D6E67LLU, // hnj_Hmng_LA
+    0xB5A750484C61746ELLU, // hnn_Latn_PH
+    0xB9A7504B41726162LLU, // hno_Arab_PK
+    0x686F50474C61746ELLU, // ho_Latn_PG
+    0x89C7494E44657661LLU, // hoc_Deva_IN
+    0xA5C7494E44657661LLU, // hoj_Deva_IN
+    0x687248524C61746ELLU, // hr_Latn_HR
+    0x864744454C61746ELLU, // hsb_Latn_DE
+    0xB647434E48616E73LLU, // hsn_Hans_CN
+    0x687448544C61746ELLU, // ht_Latn_HT
+    0x687548554C61746ELLU, // hu_Latn_HU
+    0x6879414D41726D6ELLU, // hy_Armn_AM
+    0x687A4E414C61746ELLU, // hz_Latn_NA
+    0x696146524C61746ELLU, // ia_Latn_FR
+    0x80284D594C61746ELLU, // iba_Latn_MY
+    0x84284E474C61746ELLU, // ibb_Latn_NG
+    0x696449444C61746ELLU, // id_Latn_ID
+    0x69674E474C61746ELLU, // ig_Latn_NG
+    0x6969434E59696969LLU, // ii_Yiii_CN
+    0x696B55534C61746ELLU, // ik_Latn_US
+    0xCD4843414C61746ELLU, // ikt_Latn_CA
+    0xB96850484C61746ELLU, // ilo_Latn_PH
+    0x696E49444C61746ELLU, // in_Latn_ID
+    0x9DA852554379726CLLU, // inh_Cyrl_RU
+    0x697349534C61746ELLU, // is_Latn_IS
+    0x697449544C61746ELLU, // it_Latn_IT
+    0x6975434143616E73LLU, // iu_Cans_CA
+    0x6977494C48656272LLU, // iw_Hebr_IL
+    0x9F2852554C61746ELLU, // izh_Latn_RU
+    0x6A614A504A70616ELLU, // ja_Jpan_JP
+    0xB0094A4D4C61746ELLU, // jam_Latn_JM
+    0xB8C9434D4C61746ELLU, // jgo_Latn_CM
+    0x8989545A4C61746ELLU, // jmc_Latn_TZ
+    0xAD894E5044657661LLU, // jml_Deva_NP
+    0xCE89444B4C61746ELLU, // jut_Latn_DK
+    0x6A7649444C61746ELLU, // jv_Latn_ID
+    0x6A7749444C61746ELLU, // jw_Latn_ID
+    0x6B61474547656F72LLU, // ka_Geor_GE
+    0x800A555A4379726CLLU, // kaa_Cyrl_UZ
+    0x840A445A4C61746ELLU, // kab_Latn_DZ
+    0x880A4D4D4C61746ELLU, // kac_Latn_MM
+    0xA40A4E474C61746ELLU, // kaj_Latn_NG
+    0xB00A4B454C61746ELLU, // kam_Latn_KE
+    0xB80A4D4C4C61746ELLU, // kao_Latn_ML
+    0x8C2A52554379726CLLU, // kbd_Cyrl_RU
+    0xE02A4E4541726162LLU, // kby_Arab_NE
+    0x984A4E474C61746ELLU, // kcg_Latn_NG
+    0xA84A5A574C61746ELLU, // kck_Latn_ZW
+    0x906A545A4C61746ELLU, // kde_Latn_TZ
+    0x9C6A544741726162LLU, // kdh_Arab_TG
+    0xCC6A544854686169LLU, // kdt_Thai_TH
+    0x808A43564C61746ELLU, // kea_Latn_CV
+    0xB48A434D4C61746ELLU, // ken_Latn_CM
+    0xB8AA43494C61746ELLU, // kfo_Latn_CI
+    0xC4AA494E44657661LLU, // kfr_Deva_IN
+    0xE0AA494E44657661LLU, // kfy_Deva_IN
+    0x6B6743444C61746ELLU, // kg_Latn_CD
+    0x90CA49444C61746ELLU, // kge_Latn_ID
+    0xBCCA42524C61746ELLU, // kgp_Latn_BR
+    0x80EA494E4C61746ELLU, // kha_Latn_IN
+    0x84EA434E54616C75LLU, // khb_Talu_CN
+    0xB4EA494E44657661LLU, // khn_Deva_IN
+    0xC0EA4D4C4C61746ELLU, // khq_Latn_ML
+    0xCCEA494E4D796D72LLU, // kht_Mymr_IN
+    0xD8EA504B41726162LLU, // khw_Arab_PK
+    0x6B694B454C61746ELLU, // ki_Latn_KE
+    0xD10A54524C61746ELLU, // kiu_Latn_TR
+    0x6B6A4E414C61746ELLU, // kj_Latn_NA
+    0x992A4C414C616F6FLLU, // kjg_Laoo_LA
+    0x6B6B434E41726162LLU, // kk_Arab_CN
+    0x6B6B4B5A4379726CLLU, // kk_Cyrl_KZ
+    0xA54A434D4C61746ELLU, // kkj_Latn_CM
+    0x6B6C474C4C61746ELLU, // kl_Latn_GL
+    0xB56A4B454C61746ELLU, // kln_Latn_KE
+    0x6B6D4B484B686D72LLU, // km_Khmr_KH
+    0x858A414F4C61746ELLU, // kmb_Latn_AO
+    0x6B6E494E4B6E6461LLU, // kn_Knda_IN
+    0x6B6F4B524B6F7265LLU, // ko_Kore_KR
+    0xA1CA52554379726CLLU, // koi_Cyrl_RU
+    0xA9CA494E44657661LLU, // kok_Deva_IN
+    0xC9CA464D4C61746ELLU, // kos_Latn_FM
+    0x91EA4C524C61746ELLU, // kpe_Latn_LR
+    0x8A2A52554379726CLLU, // krc_Cyrl_RU
+    0xA22A534C4C61746ELLU, // kri_Latn_SL
+    0xA62A50484C61746ELLU, // krj_Latn_PH
+    0xAE2A52554C61746ELLU, // krl_Latn_RU
+    0xD22A494E44657661LLU, // kru_Deva_IN
+    0x6B73494E41726162LLU, // ks_Arab_IN
+    0x864A545A4C61746ELLU, // ksb_Latn_TZ
+    0x964A434D4C61746ELLU, // ksf_Latn_CM
+    0x9E4A44454C61746ELLU, // ksh_Latn_DE
+    0x6B75495141726162LLU, // ku_Arab_IQ
+    0x6B7554524C61746ELLU, // ku_Latn_TR
+    0xB28A52554379726CLLU, // kum_Cyrl_RU
+    0x6B7652554379726CLLU, // kv_Cyrl_RU
+    0xC6AA49444C61746ELLU, // kvr_Latn_ID
+    0xDEAA504B41726162LLU, // kvx_Arab_PK
+    0x6B7747424C61746ELLU, // kw_Latn_GB
+    0xB2EA544854686169LLU, // kxm_Thai_TH
+    0xBEEA504B41726162LLU, // kxp_Arab_PK
+    0x6B79434E41726162LLU, // ky_Arab_CN
+    0x6B794B474379726CLLU, // ky_Cyrl_KG
+    0x6B7954524C61746ELLU, // ky_Latn_TR
+    0x6C6156414C61746ELLU, // la_Latn_VA
+    0x840B47524C696E61LLU, // lab_Lina_GR
+    0x8C0B494C48656272LLU, // lad_Hebr_IL
+    0x980B545A4C61746ELLU, // lag_Latn_TZ
+    0x9C0B504B41726162LLU, // lah_Arab_PK
+    0xA40B55474C61746ELLU, // laj_Latn_UG
+    0x6C624C554C61746ELLU, // lb_Latn_LU
+    0x902B52554379726CLLU, // lbe_Cyrl_RU
+    0xD82B49444C61746ELLU, // lbw_Latn_ID
+    0xBC4B434E54686169LLU, // lcp_Thai_CN
+    0xBC8B494E4C657063LLU, // lep_Lepc_IN
+    0xE48B52554379726CLLU, // lez_Cyrl_RU
+    0x6C6755474C61746ELLU, // lg_Latn_UG
+    0x6C694E4C4C61746ELLU, // li_Latn_NL
+    0x950B4E5044657661LLU, // lif_Deva_NP
+    0x950B494E4C696D62LLU, // lif_Limb_IN
+    0xA50B49544C61746ELLU, // lij_Latn_IT
+    0xC90B434E4C697375LLU, // lis_Lisu_CN
+    0xBD2B49444C61746ELLU, // ljp_Latn_ID
+    0xA14B495241726162LLU, // lki_Arab_IR
+    0xCD4B55534C61746ELLU, // lkt_Latn_US
+    0xB58B494E54656C75LLU, // lmn_Telu_IN
+    0xB98B49544C61746ELLU, // lmo_Latn_IT
+    0x6C6E43444C61746ELLU, // ln_Latn_CD
+    0x6C6F4C414C616F6FLLU, // lo_Laoo_LA
+    0xADCB43444C61746ELLU, // lol_Latn_CD
+    0xE5CB5A4D4C61746ELLU, // loz_Latn_ZM
+    0x8A2B495241726162LLU, // lrc_Arab_IR
+    0x6C744C544C61746ELLU, // lt_Latn_LT
+    0x9A6B4C564C61746ELLU, // ltg_Latn_LV
+    0x6C7543444C61746ELLU, // lu_Latn_CD
+    0x828B43444C61746ELLU, // lua_Latn_CD
+    0xBA8B4B454C61746ELLU, // luo_Latn_KE
+    0xE28B4B454C61746ELLU, // luy_Latn_KE
+    0xE68B495241726162LLU, // luz_Arab_IR
+    0x6C764C564C61746ELLU, // lv_Latn_LV
+    0xAECB544854686169LLU, // lwl_Thai_TH
+    0x9F2B434E48616E73LLU, // lzh_Hans_CN
+    0xE72B54524C61746ELLU, // lzz_Latn_TR
+    0x8C0C49444C61746ELLU, // mad_Latn_ID
+    0x940C434D4C61746ELLU, // maf_Latn_CM
+    0x980C494E44657661LLU, // mag_Deva_IN
+    0xA00C494E44657661LLU, // mai_Deva_IN
+    0xA80C49444C61746ELLU, // mak_Latn_ID
+    0xB40C474D4C61746ELLU, // man_Latn_GM
+    0xB40C474E4E6B6F6FLLU, // man_Nkoo_GN
+    0xC80C4B454C61746ELLU, // mas_Latn_KE
+    0xE40C4D584C61746ELLU, // maz_Latn_MX
+    0x946C52554379726CLLU, // mdf_Cyrl_RU
+    0x9C6C50484C61746ELLU, // mdh_Latn_PH
+    0xC46C49444C61746ELLU, // mdr_Latn_ID
+    0xB48C534C4C61746ELLU, // men_Latn_SL
+    0xC48C4B454C61746ELLU, // mer_Latn_KE
+    0x80AC544841726162LLU, // mfa_Arab_TH
+    0x90AC4D554C61746ELLU, // mfe_Latn_MU
+    0x6D674D474C61746ELLU, // mg_Latn_MG
+    0x9CCC4D5A4C61746ELLU, // mgh_Latn_MZ
+    0xB8CC434D4C61746ELLU, // mgo_Latn_CM
+    0xBCCC4E5044657661LLU, // mgp_Deva_NP
+    0xE0CC545A4C61746ELLU, // mgy_Latn_TZ
+    0x6D684D484C61746ELLU, // mh_Latn_MH
+    0x6D694E5A4C61746ELLU, // mi_Latn_NZ
+    0xB50C49444C61746ELLU, // min_Latn_ID
+    0xC90C495148617472LLU, // mis_Hatr_IQ
+    0x6D6B4D4B4379726CLLU, // mk_Cyrl_MK
+    0x6D6C494E4D6C796DLLU, // ml_Mlym_IN
+    0xC96C53444C61746ELLU, // mls_Latn_SD
+    0x6D6E4D4E4379726CLLU, // mn_Cyrl_MN
+    0x6D6E434E4D6F6E67LLU, // mn_Mong_CN
+    0xA1AC494E42656E67LLU, // mni_Beng_IN
+    0xD9AC4D4D4D796D72LLU, // mnw_Mymr_MM
+    0x91CC43414C61746ELLU, // moe_Latn_CA
+    0x9DCC43414C61746ELLU, // moh_Latn_CA
+    0xC9CC42464C61746ELLU, // mos_Latn_BF
+    0x6D72494E44657661LLU, // mr_Deva_IN
+    0x8E2C4E5044657661LLU, // mrd_Deva_NP
+    0xA62C52554379726CLLU, // mrj_Cyrl_RU
+    0xBA2C42444D726F6FLLU, // mro_Mroo_BD
+    0x6D734D594C61746ELLU, // ms_Latn_MY
+    0x6D744D544C61746ELLU, // mt_Latn_MT
+    0xC66C494E44657661LLU, // mtr_Deva_IN
+    0x828C434D4C61746ELLU, // mua_Latn_CM
+    0xCA8C55534C61746ELLU, // mus_Latn_US
+    0xE2AC504B41726162LLU, // mvy_Arab_PK
+    0xAACC4D4C4C61746ELLU, // mwk_Latn_ML
+    0xC6CC494E44657661LLU, // mwr_Deva_IN
+    0xD6CC49444C61746ELLU, // mwv_Latn_ID
+    0x8AEC5A574C61746ELLU, // mxc_Latn_ZW
+    0x6D794D4D4D796D72LLU, // my_Mymr_MM
+    0xD70C52554379726CLLU, // myv_Cyrl_RU
+    0xDF0C55474C61746ELLU, // myx_Latn_UG
+    0xE70C49524D616E64LLU, // myz_Mand_IR
+    0xB72C495241726162LLU, // mzn_Arab_IR
+    0x6E614E524C61746ELLU, // na_Latn_NR
+    0xB40D434E48616E73LLU, // nan_Hans_CN
+    0xBC0D49544C61746ELLU, // nap_Latn_IT
+    0xC00D4E414C61746ELLU, // naq_Latn_NA
+    0x6E624E4F4C61746ELLU, // nb_Latn_NO
+    0x9C4D4D584C61746ELLU, // nch_Latn_MX
+    0x6E645A574C61746ELLU, // nd_Latn_ZW
+    0x886D4D5A4C61746ELLU, // ndc_Latn_MZ
+    0xC86D44454C61746ELLU, // nds_Latn_DE
+    0x6E654E5044657661LLU, // ne_Deva_NP
+    0xD88D4E5044657661LLU, // new_Deva_NP
+    0x6E674E414C61746ELLU, // ng_Latn_NA
+    0xACCD4D5A4C61746ELLU, // ngl_Latn_MZ
+    0x90ED4D584C61746ELLU, // nhe_Latn_MX
+    0xD8ED4D584C61746ELLU, // nhw_Latn_MX
+    0xA50D49444C61746ELLU, // nij_Latn_ID
+    0xD10D4E554C61746ELLU, // niu_Latn_NU
+    0xB92D494E4C61746ELLU, // njo_Latn_IN
+    0x6E6C4E4C4C61746ELLU, // nl_Latn_NL
+    0x998D434D4C61746ELLU, // nmg_Latn_CM
+    0x6E6E4E4F4C61746ELLU, // nn_Latn_NO
+    0x9DAD434D4C61746ELLU, // nnh_Latn_CM
+    0x6E6F4E4F4C61746ELLU, // no_Latn_NO
+    0x8DCD54484C616E61LLU, // nod_Lana_TH
+    0x91CD494E44657661LLU, // noe_Deva_IN
+    0xB5CD534552756E72LLU, // non_Runr_SE
+    0xBA0D474E4E6B6F6FLLU, // nqo_Nkoo_GN
+    0x6E725A414C61746ELLU, // nr_Latn_ZA
+    0xAA4D434143616E73LLU, // nsk_Cans_CA
+    0xBA4D5A414C61746ELLU, // nso_Latn_ZA
+    0xCA8D53534C61746ELLU, // nus_Latn_SS
+    0x6E7655534C61746ELLU, // nv_Latn_US
+    0xC2ED434E4C61746ELLU, // nxq_Latn_CN
+    0x6E794D574C61746ELLU, // ny_Latn_MW
+    0xB30D545A4C61746ELLU, // nym_Latn_TZ
+    0xB70D55474C61746ELLU, // nyn_Latn_UG
+    0xA32D47484C61746ELLU, // nzi_Latn_GH
+    0x6F6346524C61746ELLU, // oc_Latn_FR
+    0x6F6D45544C61746ELLU, // om_Latn_ET
+    0x6F72494E4F727961LLU, // or_Orya_IN
+    0x6F7347454379726CLLU, // os_Cyrl_GE
+    0x824E55534F736765LLU, // osa_Osge_US
+    0xAA6E4D4E4F726B68LLU, // otk_Orkh_MN
+    0x7061504B41726162LLU, // pa_Arab_PK
+    0x7061494E47757275LLU, // pa_Guru_IN
+    0x980F50484C61746ELLU, // pag_Latn_PH
+    0xAC0F495250686C69LLU, // pal_Phli_IR
+    0xAC0F434E50686C70LLU, // pal_Phlp_CN
+    0xB00F50484C61746ELLU, // pam_Latn_PH
+    0xBC0F41574C61746ELLU, // pap_Latn_AW
+    0xD00F50574C61746ELLU, // pau_Latn_PW
+    0x8C4F46524C61746ELLU, // pcd_Latn_FR
+    0xB04F4E474C61746ELLU, // pcm_Latn_NG
+    0x886F55534C61746ELLU, // pdc_Latn_US
+    0xCC6F43414C61746ELLU, // pdt_Latn_CA
+    0xB88F49525870656FLLU, // peo_Xpeo_IR
+    0xACAF44454C61746ELLU, // pfl_Latn_DE
+    0xB4EF4C4250686E78LLU, // phn_Phnx_LB
+    0x814F494E42726168LLU, // pka_Brah_IN
+    0xB94F4B454C61746ELLU, // pko_Latn_KE
+    0x706C504C4C61746ELLU, // pl_Latn_PL
+    0xC98F49544C61746ELLU, // pms_Latn_IT
+    0xCDAF47524772656BLLU, // pnt_Grek_GR
+    0xB5CF464D4C61746ELLU, // pon_Latn_FM
+    0x822F504B4B686172LLU, // pra_Khar_PK
+    0x8E2F495241726162LLU, // prd_Arab_IR
+    0x7073414641726162LLU, // ps_Arab_AF
+    0x707442524C61746ELLU, // pt_Latn_BR
+    0xD28F47414C61746ELLU, // puu_Latn_GA
+    0x717550454C61746ELLU, // qu_Latn_PE
+    0x8A9047544C61746ELLU, // quc_Latn_GT
+    0x9A9045434C61746ELLU, // qug_Latn_EC
+    0xA411494E44657661LLU, // raj_Deva_IN
+    0x945152454C61746ELLU, // rcf_Latn_RE
+    0xA49149444C61746ELLU, // rej_Latn_ID
+    0xB4D149544C61746ELLU, // rgn_Latn_IT
+    0x8111494E4C61746ELLU, // ria_Latn_IN
+    0x95114D4154666E67LLU, // rif_Tfng_MA
+    0xC9314E5044657661LLU, // rjs_Deva_NP
+    0xCD51424442656E67LLU, // rkt_Beng_BD
+    0x726D43484C61746ELLU, // rm_Latn_CH
+    0x959146494C61746ELLU, // rmf_Latn_FI
+    0xB99143484C61746ELLU, // rmo_Latn_CH
+    0xCD91495241726162LLU, // rmt_Arab_IR
+    0xD19153454C61746ELLU, // rmu_Latn_SE
+    0x726E42494C61746ELLU, // rn_Latn_BI
+    0x99B14D5A4C61746ELLU, // rng_Latn_MZ
+    0x726F524F4C61746ELLU, // ro_Latn_RO
+    0x85D149444C61746ELLU, // rob_Latn_ID
+    0x95D1545A4C61746ELLU, // rof_Latn_TZ
+    0xB271464A4C61746ELLU, // rtm_Latn_FJ
+    0x727552554379726CLLU, // ru_Cyrl_RU
+    0x929155414379726CLLU, // rue_Cyrl_UA
+    0x9A9153424C61746ELLU, // rug_Latn_SB
+    0x727752574C61746ELLU, // rw_Latn_RW
+    0xAAD1545A4C61746ELLU, // rwk_Latn_TZ
+    0xD3114A504B616E61LLU, // ryu_Kana_JP
+    0x7361494E44657661LLU, // sa_Deva_IN
+    0x941247484C61746ELLU, // saf_Latn_GH
+    0x9C1252554379726CLLU, // sah_Cyrl_RU
+    0xC0124B454C61746ELLU, // saq_Latn_KE
+    0xC81249444C61746ELLU, // sas_Latn_ID
+    0xCC12494E4C61746ELLU, // sat_Latn_IN
+    0xE412494E53617572LLU, // saz_Saur_IN
+    0xBC32545A4C61746ELLU, // sbp_Latn_TZ
+    0x736349544C61746ELLU, // sc_Latn_IT
+    0xA852494E44657661LLU, // sck_Deva_IN
+    0xB45249544C61746ELLU, // scn_Latn_IT
+    0xB85247424C61746ELLU, // sco_Latn_GB
+    0xC85243414C61746ELLU, // scs_Latn_CA
+    0x7364504B41726162LLU, // sd_Arab_PK
+    0x7364494E44657661LLU, // sd_Deva_IN
+    0x7364494E4B686F6ALLU, // sd_Khoj_IN
+    0x7364494E53696E64LLU, // sd_Sind_IN
+    0x887249544C61746ELLU, // sdc_Latn_IT
+    0x9C72495241726162LLU, // sdh_Arab_IR
+    0x73654E4F4C61746ELLU, // se_Latn_NO
+    0x949243494C61746ELLU, // sef_Latn_CI
+    0x9C924D5A4C61746ELLU, // seh_Latn_MZ
+    0xA0924D584C61746ELLU, // sei_Latn_MX
+    0xC8924D4C4C61746ELLU, // ses_Latn_ML
+    0x736743464C61746ELLU, // sg_Latn_CF
+    0x80D249454F67616DLLU, // sga_Ogam_IE
+    0xC8D24C544C61746ELLU, // sgs_Latn_LT
+    0xA0F24D4154666E67LLU, // shi_Tfng_MA
+    0xB4F24D4D4D796D72LLU, // shn_Mymr_MM
+    0x73694C4B53696E68LLU, // si_Sinh_LK
+    0x8D1245544C61746ELLU, // sid_Latn_ET
+    0x736B534B4C61746ELLU, // sk_Latn_SK
+    0xC552504B41726162LLU, // skr_Arab_PK
+    0x736C53494C61746ELLU, // sl_Latn_SI
+    0xA172504C4C61746ELLU, // sli_Latn_PL
+    0xE17249444C61746ELLU, // sly_Latn_ID
+    0x736D57534C61746ELLU, // sm_Latn_WS
+    0x819253454C61746ELLU, // sma_Latn_SE
+    0xA59253454C61746ELLU, // smj_Latn_SE
+    0xB59246494C61746ELLU, // smn_Latn_FI
+    0xBD92494C53616D72LLU, // smp_Samr_IL
+    0xC99246494C61746ELLU, // sms_Latn_FI
+    0x736E5A574C61746ELLU, // sn_Latn_ZW
+    0xA9B24D4C4C61746ELLU, // snk_Latn_ML
+    0x736F534F4C61746ELLU, // so_Latn_SO
+    0xD1D2544854686169LLU, // sou_Thai_TH
+    0x7371414C4C61746ELLU, // sq_Latn_AL
+    0x737252534379726CLLU, // sr_Cyrl_RS
+    0x737252534C61746ELLU, // sr_Latn_RS
+    0x8632494E536F7261LLU, // srb_Sora_IN
+    0xB63253524C61746ELLU, // srn_Latn_SR
+    0xC632534E4C61746ELLU, // srr_Latn_SN
+    0xDE32494E44657661LLU, // srx_Deva_IN
+    0x73735A414C61746ELLU, // ss_Latn_ZA
+    0xE25245524C61746ELLU, // ssy_Latn_ER
+    0x73745A414C61746ELLU, // st_Latn_ZA
+    0xC27244454C61746ELLU, // stq_Latn_DE
+    0x737549444C61746ELLU, // su_Latn_ID
+    0xAA92545A4C61746ELLU, // suk_Latn_TZ
+    0xCA92474E4C61746ELLU, // sus_Latn_GN
+    0x737653454C61746ELLU, // sv_Latn_SE
+    0x7377545A4C61746ELLU, // sw_Latn_TZ
+    0x86D2595441726162LLU, // swb_Arab_YT
+    0x8AD243444C61746ELLU, // swc_Latn_CD
+    0x9AD244454C61746ELLU, // swg_Latn_DE
+    0xD6D2494E44657661LLU, // swv_Deva_IN
+    0xB6F249444C61746ELLU, // sxn_Latn_ID
+    0xAF12424442656E67LLU, // syl_Beng_BD
+    0xC712495153797263LLU, // syr_Syrc_IQ
+    0xAF32504C4C61746ELLU, // szl_Latn_PL
+    0x7461494E54616D6CLLU, // ta_Taml_IN
+    0xA4134E5044657661LLU, // taj_Deva_NP
+    0xD83350484C61746ELLU, // tbw_Latn_PH
+    0xE053494E4B6E6461LLU, // tcy_Knda_IN
+    0x8C73434E54616C65LLU, // tdd_Tale_CN
+    0x98734E5044657661LLU, // tdg_Deva_NP
+    0x9C734E5044657661LLU, // tdh_Deva_NP
+    0x7465494E54656C75LLU, // te_Telu_IN
+    0xB093534C4C61746ELLU, // tem_Latn_SL
+    0xB89355474C61746ELLU, // teo_Latn_UG
+    0xCC93544C4C61746ELLU, // tet_Latn_TL
+    0x7467504B41726162LLU, // tg_Arab_PK
+    0x7467544A4379726CLLU, // tg_Cyrl_TJ
+    0x7468544854686169LLU, // th_Thai_TH
+    0xACF34E5044657661LLU, // thl_Deva_NP
+    0xC0F34E5044657661LLU, // thq_Deva_NP
+    0xC4F34E5044657661LLU, // thr_Deva_NP
+    0x7469455445746869LLU, // ti_Ethi_ET
+    0x9913455245746869LLU, // tig_Ethi_ER
+    0xD5134E474C61746ELLU, // tiv_Latn_NG
+    0x746B544D4C61746ELLU, // tk_Latn_TM
+    0xAD53544B4C61746ELLU, // tkl_Latn_TK
+    0xC553415A4C61746ELLU, // tkr_Latn_AZ
+    0xCD534E5044657661LLU, // tkt_Deva_NP
+    0x746C50484C61746ELLU, // tl_Latn_PH
+    0xE173415A4C61746ELLU, // tly_Latn_AZ
+    0x9D934E454C61746ELLU, // tmh_Latn_NE
+    0x746E5A414C61746ELLU, // tn_Latn_ZA
+    0x746F544F4C61746ELLU, // to_Latn_TO
+    0x99D34D574C61746ELLU, // tog_Latn_MW
+    0xA1F350474C61746ELLU, // tpi_Latn_PG
+    0x747254524C61746ELLU, // tr_Latn_TR
+    0xD23354524C61746ELLU, // tru_Latn_TR
+    0xD63354574C61746ELLU, // trv_Latn_TW
+    0x74735A414C61746ELLU, // ts_Latn_ZA
+    0x8E5347524772656BLLU, // tsd_Grek_GR
+    0x96534E5044657661LLU, // tsf_Deva_NP
+    0x9A5350484C61746ELLU, // tsg_Latn_PH
+    0xA653425454696274LLU, // tsj_Tibt_BT
+    0x747452554379726CLLU, // tt_Cyrl_RU
+    0xA67355474C61746ELLU, // ttj_Latn_UG
+    0xCA73544854686169LLU, // tts_Thai_TH
+    0xCE73415A4C61746ELLU, // ttt_Latn_AZ
+    0xB2934D574C61746ELLU, // tum_Latn_MW
+    0xAEB354564C61746ELLU, // tvl_Latn_TV
+    0xC2D34E454C61746ELLU, // twq_Latn_NE
+    0x9AF3434E54616E67LLU, // txg_Tang_CN
+    0x747950464C61746ELLU, // ty_Latn_PF
+    0xD71352554379726CLLU, // tyv_Cyrl_RU
+    0xB3334D414C61746ELLU, // tzm_Latn_MA
+    0xB07452554379726CLLU, // udm_Cyrl_RU
+    0x7567434E41726162LLU, // ug_Arab_CN
+    0x75674B5A4379726CLLU, // ug_Cyrl_KZ
+    0x80D4535955676172LLU, // uga_Ugar_SY
+    0x756B55414379726CLLU, // uk_Cyrl_UA
+    0xA174464D4C61746ELLU, // uli_Latn_FM
+    0x8594414F4C61746ELLU, // umb_Latn_AO
+    0xC5B4494E42656E67LLU, // unr_Beng_IN
+    0xC5B44E5044657661LLU, // unr_Deva_NP
+    0xDDB4494E42656E67LLU, // unx_Beng_IN
+    0x7572504B41726162LLU, // ur_Arab_PK
+    0x757A414641726162LLU, // uz_Arab_AF
+    0x757A555A4C61746ELLU, // uz_Latn_UZ
+    0xA0154C5256616969LLU, // vai_Vaii_LR
+    0x76655A414C61746ELLU, // ve_Latn_ZA
+    0x889549544C61746ELLU, // vec_Latn_IT
+    0xBC9552554C61746ELLU, // vep_Latn_RU
+    0x7669564E4C61746ELLU, // vi_Latn_VN
+    0x891553584C61746ELLU, // vic_Latn_SX
+    0xC97542454C61746ELLU, // vls_Latn_BE
+    0x959544454C61746ELLU, // vmf_Latn_DE
+    0xD9954D5A4C61746ELLU, // vmw_Latn_MZ
+    0xCDD552554C61746ELLU, // vot_Latn_RU
+    0xBA3545454C61746ELLU, // vro_Latn_EE
+    0xB695545A4C61746ELLU, // vun_Latn_TZ
+    0x776142454C61746ELLU, // wa_Latn_BE
+    0x901643484C61746ELLU, // wae_Latn_CH
+    0xAC16455445746869LLU, // wal_Ethi_ET
+    0xC41650484C61746ELLU, // war_Latn_PH
+    0xBC3641554C61746ELLU, // wbp_Latn_AU
+    0xC036494E54656C75LLU, // wbq_Telu_IN
+    0xC436494E44657661LLU, // wbr_Deva_IN
+    0xC97657464C61746ELLU, // wls_Latn_WF
+    0xA1B64B4D41726162LLU, // wni_Arab_KM
+    0x776F534E4C61746ELLU, // wo_Latn_SN
+    0xB276494E44657661LLU, // wtm_Deva_IN
+    0xD296434E48616E73LLU, // wuu_Hans_CN
+    0xD41742524C61746ELLU, // xav_Latn_BR
+    0xC457545243617269LLU, // xcr_Cari_TR
+    0x78685A414C61746ELLU, // xh_Latn_ZA
+    0x897754524C796369LLU, // xlc_Lyci_TR
+    0x8D7754524C796469LLU, // xld_Lydi_TR
+    0x9597474547656F72LLU, // xmf_Geor_GE
+    0xB597434E4D616E69LLU, // xmn_Mani_CN
+    0xC59753444D657263LLU, // xmr_Merc_SD
+    0x81B753414E617262LLU, // xna_Narb_SA
+    0xC5B7494E44657661LLU, // xnr_Deva_IN
+    0x99D755474C61746ELLU, // xog_Latn_UG
+    0xC5F7495250727469LLU, // xpr_Prti_IR
+    0x8257594553617262LLU, // xsa_Sarb_YE
+    0xC6574E5044657661LLU, // xsr_Deva_NP
+    0xB8184D5A4C61746ELLU, // yao_Latn_MZ
+    0xBC18464D4C61746ELLU, // yap_Latn_FM
+    0xD418434D4C61746ELLU, // yav_Latn_CM
+    0x8438434D4C61746ELLU, // ybb_Latn_CM
+    0x796F4E474C61746ELLU, // yo_Latn_NG
+    0xAE3842524C61746ELLU, // yrl_Latn_BR
+    0x82984D584C61746ELLU, // yua_Latn_MX
+    0x9298434E48616E73LLU, // yue_Hans_CN
+    0x9298484B48616E74LLU, // yue_Hant_HK
+    0x7A61434E4C61746ELLU, // za_Latn_CN
+    0x981953444C61746ELLU, // zag_Latn_SD
+    0xA4794B4D41726162LLU, // zdj_Arab_KM
+    0x80994E4C4C61746ELLU, // zea_Latn_NL
+    0x9CD94D4154666E67LLU, // zgh_Tfng_MA
+    0x7A685457426F706FLLU, // zh_Bopo_TW
+    0x7A68545748616E62LLU, // zh_Hanb_TW
+    0x7A68434E48616E73LLU, // zh_Hans_CN
+    0x7A68545748616E74LLU, // zh_Hant_TW
+    0xB17954474C61746ELLU, // zlm_Latn_TG
+    0xA1994D594C61746ELLU, // zmi_Latn_MY
+    0x7A755A414C61746ELLU, // zu_Latn_ZA
+    0x833954524C61746ELLU, // zza_Latn_TR
 });
 
 const std::unordered_map<uint32_t, uint32_t> ARAB_PARENTS({
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 263d249..c6ef090 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -223,6 +223,7 @@
             break;
         case PixelStorageType::Heap:
             free(mPixelStorage.heap.address);
+            mallopt(M_PURGE, 0);
             break;
         case PixelStorageType::Hardware:
             auto buffer = mPixelStorage.hardware.buffer;
@@ -230,7 +231,6 @@
             mPixelStorage.hardware.buffer = nullptr;
             break;
     }
-
     android::uirenderer::renderthread::RenderProxy::onBitmapDestroyed(getStableID());
 }
 
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 38ad9c0..e9fba3a 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -30,7 +30,7 @@
 
 class SkiaPipeline : public renderthread::IRenderPipeline {
 public:
-    SkiaPipeline(renderthread::RenderThread& thread);
+    explicit SkiaPipeline(renderthread::RenderThread& thread);
     virtual ~SkiaPipeline();
 
     TaskManager* getTaskManager() override;
diff --git a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
index 5ae7d6b..3233c8d 100644
--- a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
+++ b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
@@ -23,7 +23,7 @@
 
 class SkiaProfileRenderer : public IProfileRenderer {
 public:
-    SkiaProfileRenderer(SkCanvas* canvas) : mCanvas(canvas) {}
+    explicit SkiaProfileRenderer(SkCanvas* canvas) : mCanvas(canvas) {}
 
     void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override;
     void drawRects(const float* rects, int count, const SkPaint& paint) override;
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 03b4c79..3d00386 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -25,7 +25,7 @@
 
 class SkiaVulkanPipeline : public SkiaPipeline {
 public:
-    SkiaVulkanPipeline(renderthread::RenderThread& thread);
+    explicit SkiaVulkanPipeline(renderthread::RenderThread& thread);
     virtual ~SkiaVulkanPipeline() {}
 
     renderthread::MakeCurrentResult makeCurrent() override;
diff --git a/libs/hwui/pipeline/skia/VectorDrawableAtlas.h b/libs/hwui/pipeline/skia/VectorDrawableAtlas.h
index 74e48ce..5e892aa 100644
--- a/libs/hwui/pipeline/skia/VectorDrawableAtlas.h
+++ b/libs/hwui/pipeline/skia/VectorDrawableAtlas.h
@@ -62,8 +62,8 @@
 public:
     enum class StorageMode { allowSharedSurface, disallowSharedSurface };
 
-    VectorDrawableAtlas(size_t surfaceArea,
-                        StorageMode storageMode = StorageMode::allowSharedSurface);
+    explicit VectorDrawableAtlas(size_t surfaceArea,
+                                 StorageMode storageMode = StorageMode::allowSharedSurface);
 
     /**
      * "prepareForDraw" may allocate a new surface if needed. It may schedule to repack the
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index 7d73352..78d2539 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -59,7 +59,7 @@
 private:
     friend class RenderThread;
 
-    CacheManager(const DisplayInfo& display);
+    explicit CacheManager(const DisplayInfo& display);
 
     void reset(sk_sp<GrContext> grContext);
     void destroy();
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index c319c9e..ea69704 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -127,6 +127,7 @@
             fPtr = ptr;
             return *this;
         }
+        // NOLINTNEXTLINE(google-explicit-constructor)
         operator FNPTR_TYPE() const { return fPtr; }
 
     private:
diff --git a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
index 0d87776..d189a93 100644
--- a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
@@ -76,7 +76,7 @@
                             paint.setStrokeWidth(strokeWidth);
                             // fill column with each op
                             int middleCount = canvas.save(SaveFlags::MatrixClip);
-                            for (auto op : ops) {
+                            for (const auto& op : ops) {
                                 int innerCount = canvas.save(SaveFlags::MatrixClip);
                                 canvas.clipRect(0, 0, cellSize, cellSize, SkClipOp::kIntersect);
                                 canvas.drawColor(Color::White, SkBlendMode::kSrcOver);
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 02f740c..4f299e3 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -251,7 +251,7 @@
 }
 
 TEST(PathParser, parseStringForData) {
-    for (TestData testData : sTestDataSet) {
+    for (const TestData& testData : sTestDataSet) {
         PathParser::ParseResult result;
         // Test generated path data against the given data.
         PathData pathData;
@@ -271,7 +271,7 @@
 }
 
 TEST(VectorDrawableUtils, createSkPathFromPathData) {
-    for (TestData testData : sTestDataSet) {
+    for (const TestData& testData : sTestDataSet) {
         SkPath expectedPath;
         testData.skPathLamda(&expectedPath);
         SkPath actualPath;
@@ -281,7 +281,7 @@
 }
 
 TEST(PathParser, parseAsciiStringForSkPath) {
-    for (TestData testData : sTestDataSet) {
+    for (const TestData& testData : sTestDataSet) {
         PathParser::ParseResult result;
         size_t length = strlen(testData.pathString);
         // Check the return value as well as the SkPath generated.
@@ -304,8 +304,8 @@
 }
 
 TEST(VectorDrawableUtils, morphPathData) {
-    for (TestData fromData : sTestDataSet) {
-        for (TestData toData : sTestDataSet) {
+    for (const TestData& fromData : sTestDataSet) {
+        for (const TestData& toData : sTestDataSet) {
             bool canMorph = VectorDrawableUtils::canMorph(fromData.pathData, toData.pathData);
             if (fromData.pathData == toData.pathData) {
                 EXPECT_TRUE(canMorph);
@@ -319,8 +319,8 @@
 
 TEST(VectorDrawableUtils, interpolatePathData) {
     // Interpolate path data with itself and every other path data
-    for (TestData fromData : sTestDataSet) {
-        for (TestData toData : sTestDataSet) {
+    for (const TestData& fromData : sTestDataSet) {
+        for (const TestData& toData : sTestDataSet) {
             PathData outData;
             bool success = VectorDrawableUtils::interpolatePathData(&outData, fromData.pathData,
                                                                     toData.pathData, 0.5);
@@ -331,7 +331,7 @@
 
     float fractions[] = {0, 0.00001, 0.28, 0.5, 0.7777, 0.9999999, 1};
     // Now try to interpolate with a slightly modified version of self and expect success
-    for (TestData fromData : sTestDataSet) {
+    for (const TestData& fromData : sTestDataSet) {
         PathData toPathData = fromData.pathData;
         for (size_t i = 0; i < toPathData.points.size(); i++) {
             toPathData.points[i]++;
diff --git a/libs/incident/include/android/os/IncidentReportArgs.h b/libs/incident/include/android/os/IncidentReportArgs.h
index c56f689..ee1e33c 100644
--- a/libs/incident/include/android/os/IncidentReportArgs.h
+++ b/libs/incident/include/android/os/IncidentReportArgs.h
@@ -40,7 +40,7 @@
 class IncidentReportArgs : public Parcelable {
 public:
     IncidentReportArgs();
-    explicit IncidentReportArgs(const IncidentReportArgs& that);
+    IncidentReportArgs(const IncidentReportArgs& that);
     virtual ~IncidentReportArgs();
 
     virtual status_t writeToParcel(Parcel* out) const;
diff --git a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
index 3643ca4..8a02a82 100644
--- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
+++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java
@@ -18,6 +18,7 @@
 
 import android.os.SystemClock;
 import android.os.connectivity.GpsBatteryStats;
+import android.os.SystemProperties;
 
 import android.text.format.DateUtils;
 import android.util.Base64;
@@ -175,6 +176,7 @@
           = topFourAverageCn0Statistics.getStandardDeviation();
     }
     msg.powerMetrics = mGnssPowerMetrics.buildProto();
+    msg.hardwareRevision = SystemProperties.get("ro.boot.revision", "");
     String s = Base64.encodeToString(GnssLog.toByteArray(msg), Base64.DEFAULT);
     reset();
     return s;
@@ -239,6 +241,7 @@
       s.append("  Energy consumed while on battery (mAh): ").append(
           stats.getEnergyConsumedMaMs() / ((double) DateUtils.HOUR_IN_MILLIS)).append("\n");
     }
+    s.append("Hardware Version: " + SystemProperties.get("ro.boot.revision", "")).append("\n");
     return s.toString();
   }
 
diff --git a/media/java/android/media/AudioFocusInfo.java b/media/java/android/media/AudioFocusInfo.java
index 5467a69..0a9ca02 100644
--- a/media/java/android/media/AudioFocusInfo.java
+++ b/media/java/android/media/AudioFocusInfo.java
@@ -80,16 +80,12 @@
      * The audio attributes for the audio focus request.
      * @return non-null {@link AudioAttributes}.
      */
-    @SystemApi
     public AudioAttributes getAttributes() { return mAttributes; }
 
-    @SystemApi
     public int getClientUid() { return mClientUid; }
 
-    @SystemApi
     public String getClientId() { return mClientId; }
 
-    @SystemApi
     public String getPackageName() { return mPackageName; }
 
     /**
@@ -99,7 +95,6 @@
      *     {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK},
      *     {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
      */
-    @SystemApi
     public int getGainRequest() { return mGainRequest; }
 
     /**
@@ -109,7 +104,6 @@
      *   {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT} or
      *   {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
      */
-    @SystemApi
     public int getLossReceived() { return mLossReceived; }
 
     /** @hide */
@@ -124,7 +118,6 @@
      *     {@link AudioManager#AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS}, and
      *     {@link AudioManager#AUDIOFOCUS_FLAG_LOCK}.
      */
-    @SystemApi
     public int getFlags() { return mFlags; }
 
     @Override
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 2443b73..d1d605f 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -406,7 +406,7 @@
  <p>
  The codec in turn will return a read-only output buffer via the {@link
  Callback#onOutputBufferAvailable onOutputBufferAvailable} callback in asynchronous mode, or in
- response to a {@link #dequeueOutputBuffer dequeuOutputBuffer} call in synchronous mode. After the
+ response to a {@link #dequeueOutputBuffer dequeueOutputBuffer} call in synchronous mode. After the
  output buffer has been processed, call one of the {@link #releaseOutputBuffer
  releaseOutputBuffer} methods to return the buffer to the codec.
  <p>
diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java
index 8bc1d35..7fb3aa6 100644
--- a/media/java/android/media/audiopolicy/AudioMix.java
+++ b/media/java/android/media/audiopolicy/AudioMix.java
@@ -81,14 +81,12 @@
      * An audio mix behavior where the output of the mix is sent to the original destination of
      * the audio signal, i.e. an output device for an output mix, or a recording for an input mix.
      */
-    @SystemApi
     public static final int ROUTE_FLAG_RENDER    = 0x1;
     /**
      * An audio mix behavior where the output of the mix is rerouted back to the framework and
      * is accessible for injection or capture through the {@link AudioTrack} and {@link AudioRecord}
      * APIs.
      */
-    @SystemApi
     public static final int ROUTE_FLAG_LOOP_BACK = 0x1 << 1;
 
     private static final int ROUTE_FLAG_SUPPORTED = ROUTE_FLAG_RENDER | ROUTE_FLAG_LOOP_BACK;
@@ -113,31 +111,23 @@
 
     // MIX_STATE_* values to keep in sync with frameworks/av/include/media/AudioPolicy.h
     /**
-     * @hide
      * State of a mix before its policy is enabled.
      */
-    @SystemApi
     public static final int MIX_STATE_DISABLED = -1;
     /**
-     * @hide
      * State of a mix when there is no audio to mix.
      */
-    @SystemApi
     public static final int MIX_STATE_IDLE = 0;
     /**
-     * @hide
      * State of a mix that is actively mixing audio.
      */
-    @SystemApi
     public static final int MIX_STATE_MIXING = 1;
 
     /**
-     * @hide
      * The current mixing state.
      * @return one of {@link #MIX_STATE_DISABLED}, {@link #MIX_STATE_IDLE},
      *          {@link #MIX_STATE_MIXING}.
      */
-    @SystemApi
     public int getMixState() {
         return mMixState;
     }
@@ -201,9 +191,7 @@
 
     /**
      * Builder class for {@link AudioMix} objects
-     *
      */
-    @SystemApi
     public static class Builder {
         private AudioMixingRule mRule = null;
         private AudioFormat mFormat = null;
@@ -224,7 +212,6 @@
          * @param rule a non-null {@link AudioMixingRule} instance.
          * @throws IllegalArgumentException
          */
-        @SystemApi
         public Builder(AudioMixingRule rule)
                 throws IllegalArgumentException {
             if (rule == null) {
@@ -284,7 +271,6 @@
          * @return the same Builder instance.
          * @throws IllegalArgumentException
          */
-        @SystemApi
         public Builder setFormat(AudioFormat format)
                 throws IllegalArgumentException {
             if (format == null) {
@@ -302,7 +288,6 @@
          * @return the same Builder instance.
          * @throws IllegalArgumentException
          */
-        @SystemApi
         public Builder setRouteFlags(@RouteFlags int routeFlags)
                 throws IllegalArgumentException {
             if (routeFlags == 0) {
@@ -329,7 +314,6 @@
          * @return the same Builder instance
          * @throws IllegalArgumentException
          */
-        @SystemApi
         public Builder setDevice(@NonNull AudioDeviceInfo device) throws IllegalArgumentException {
             if (device == null) {
                 throw new IllegalArgumentException("Illegal null AudioDeviceInfo argument");
@@ -347,7 +331,6 @@
          * @return a new {@link AudioMix} object
          * @throws IllegalArgumentException if no {@link AudioMixingRule} has been set.
          */
-        @SystemApi
         public AudioMix build() throws IllegalArgumentException {
             if (mRule == null) {
                 throw new IllegalArgumentException("Illegal null AudioMixingRule");
diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java
index fbee62a..6c48cdb 100644
--- a/media/java/android/media/audiopolicy/AudioMixingRule.java
+++ b/media/java/android/media/audiopolicy/AudioMixingRule.java
@@ -54,7 +54,6 @@
      * {@link Builder#addMixRule(int, Object)} where the Object parameter is an instance of
      * {@link AudioAttributes}.
      */
-    @SystemApi
     public static final int RULE_MATCH_ATTRIBUTE_USAGE = 0x1;
     /**
      * A rule requiring the capture preset information of the {@link AudioAttributes} to match.
@@ -62,14 +61,12 @@
      * {@link Builder#addMixRule(int, Object)} where the Object parameter is an instance of
      * {@link AudioAttributes}.
      */
-    @SystemApi
     public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 0x1 << 1;
     /**
      * A rule requiring the UID of the audio stream to match that specified.
      * This mixing rule can be added with {@link Builder#addMixRule(int, Object)} where the Object
      * parameter is an instance of {@link java.lang.Integer}.
      */
-    @SystemApi
     public static final int RULE_MATCH_UID = 0x1 << 2;
 
     private final static int RULE_EXCLUSION_MASK = 0x8000;
@@ -239,7 +236,6 @@
     /**
      * Builder class for {@link AudioMixingRule} objects
      */
-    @SystemApi
     public static class Builder {
         private ArrayList<AudioMixMatchCriterion> mCriteria;
         private int mTargetMixType = AudioMix.MIX_TYPE_INVALID;
@@ -247,7 +243,6 @@
         /**
          * Constructs a new Builder with no rules.
          */
-        @SystemApi
         public Builder() {
             mCriteria = new ArrayList<AudioMixMatchCriterion>();
         }
@@ -262,7 +257,6 @@
          * @throws IllegalArgumentException
          * @see #excludeRule(AudioAttributes, int)
          */
-        @SystemApi
         public Builder addRule(AudioAttributes attrToMatch, int rule)
                 throws IllegalArgumentException {
             if (!isValidAttributesSystemApiRule(rule)) {
@@ -291,7 +285,6 @@
          * @throws IllegalArgumentException
          * @see #addRule(AudioAttributes, int)
          */
-        @SystemApi
         public Builder excludeRule(AudioAttributes attrToMatch, int rule)
                 throws IllegalArgumentException {
             if (!isValidAttributesSystemApiRule(rule)) {
@@ -313,7 +306,6 @@
          * @throws IllegalArgumentException
          * @see #excludeMixRule(int, Object)
          */
-        @SystemApi
         public Builder addMixRule(int rule, Object property) throws IllegalArgumentException {
             if (!isValidSystemApiRule(rule)) {
                 throw new IllegalArgumentException("Illegal rule value " + rule);
@@ -343,7 +335,6 @@
          * @return the same Builder instance.
          * @throws IllegalArgumentException
          */
-        @SystemApi
         public Builder excludeMixRule(int rule, Object property) throws IllegalArgumentException {
             if (!isValidSystemApiRule(rule)) {
                 throw new IllegalArgumentException("Illegal rule value " + rule);
diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java
index 11107e2..6103f557 100644
--- a/media/java/android/media/audiopolicy/AudioPolicy.java
+++ b/media/java/android/media/audiopolicy/AudioPolicy.java
@@ -58,12 +58,10 @@
     /**
      * The status of an audio policy that is valid but cannot be used because it is not registered.
      */
-    @SystemApi
     public static final int POLICY_STATUS_UNREGISTERED = 1;
     /**
      * The status of an audio policy that is valid, successfully registered and thus active.
      */
-    @SystemApi
     public static final int POLICY_STATUS_REGISTERED = 2;
 
     private int mStatus;
@@ -75,7 +73,6 @@
      * The behavior of a policy with regards to audio focus where it relies on the application
      * to do the ducking, the is the legacy and default behavior.
      */
-    @SystemApi
     public static final int FOCUS_POLICY_DUCKING_IN_APP = 0;
     public static final int FOCUS_POLICY_DUCKING_DEFAULT = FOCUS_POLICY_DUCKING_IN_APP;
     /**
@@ -85,7 +82,6 @@
      * <br>Can only be used after having set a listener with
      * {@link AudioPolicy#setAudioPolicyFocusListener(AudioPolicyFocusListener)}.
      */
-    @SystemApi
     public static final int FOCUS_POLICY_DUCKING_IN_POLICY = 1;
 
     private AudioPolicyFocusListener mFocusListener;
@@ -133,7 +129,6 @@
      * Builder class for {@link AudioPolicy} objects.
      * By default the policy to be created doesn't govern audio focus decisions.
      */
-    @SystemApi
     public static class Builder {
         private ArrayList<AudioMix> mMixes;
         private Context mContext;
@@ -147,7 +142,6 @@
          * Constructs a new Builder with no audio mixes.
          * @param context the context for the policy
          */
-        @SystemApi
         public Builder(Context context) {
             mMixes = new ArrayList<AudioMix>();
             mContext = context;
@@ -159,7 +153,6 @@
          * @return the same Builder instance.
          * @throws IllegalArgumentException
          */
-        @SystemApi
         public Builder addMix(@NonNull AudioMix mix) throws IllegalArgumentException {
             if (mix == null) {
                 throw new IllegalArgumentException("Illegal null AudioMix argument");
@@ -174,7 +167,6 @@
          * @return the same Builder instance.
          * @throws IllegalArgumentException
          */
-        @SystemApi
         public Builder setLooper(@NonNull Looper looper) throws IllegalArgumentException {
             if (looper == null) {
                 throw new IllegalArgumentException("Illegal null Looper argument");
@@ -187,7 +179,6 @@
          * Sets the audio focus listener for the policy.
          * @param l a {@link AudioPolicy.AudioPolicyFocusListener}
          */
-        @SystemApi
         public void setAudioPolicyFocusListener(AudioPolicyFocusListener l) {
             mFocusListener = l;
         }
@@ -201,7 +192,6 @@
          * @param enforce true if the policy will govern audio focus decisions.
          * @return the same Builder instance.
          */
-        @SystemApi
         public Builder setIsAudioFocusPolicy(boolean isFocusPolicy) {
             mIsFocusPolicy = isFocusPolicy;
             return this;
@@ -211,12 +201,10 @@
          * Sets the audio policy status listener.
          * @param l a {@link AudioPolicy.AudioPolicyStatusListener}
          */
-        @SystemApi
         public void setAudioPolicyStatusListener(AudioPolicyStatusListener l) {
             mStatusListener = l;
         }
 
-        @SystemApi
         /**
          * Sets the callback to receive all volume key-related events.
          * The callback will only be called if the device is configured to handle volume events
@@ -240,7 +228,6 @@
          *     {@link AudioPolicy.AudioPolicyStatusListener} but the policy was configured
          *     as an audio focus policy with {@link #setIsAudioFocusPolicy(boolean)}.
          */
-        @SystemApi
         public AudioPolicy build() {
             if (mStatusListener != null) {
                 // the AudioPolicy status listener includes updates on each mix activity state
@@ -258,7 +245,6 @@
     }
 
     /**
-     * @hide
      * Update the current configuration of the set of audio mixes by adding new ones, while
      * keeping the policy registered.
      * This method can only be called on a registered policy.
@@ -266,7 +252,6 @@
      * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR}
      *    otherwise.
      */
-    @SystemApi
     public int attachMixes(@NonNull List<AudioMix> mixes) {
         if (mixes == null) {
             throw new IllegalArgumentException("Illegal null list of AudioMix");
@@ -299,7 +284,6 @@
     }
 
     /**
-     * @hide
      * Update the current configuration of the set of audio mixes by removing some, while
      * keeping the policy registered.
      * This method can only be called on a registered policy.
@@ -307,7 +291,6 @@
      * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR}
      *    otherwise.
      */
-    @SystemApi
     public int detachMixes(@NonNull List<AudioMix> mixes) {
         if (mixes == null) {
             throw new IllegalArgumentException("Illegal null list of AudioMix");
@@ -405,7 +388,6 @@
      * Returns the current behavior for audio focus-related ducking.
      * @return {@link #FOCUS_POLICY_DUCKING_IN_APP} or {@link #FOCUS_POLICY_DUCKING_IN_POLICY}
      */
-    @SystemApi
     public int getFocusDuckingBehavior() {
         return mConfig.mDuckingPolicy;
     }
@@ -422,7 +404,6 @@
      * @throws IllegalArgumentException
      * @throws IllegalStateException
      */
-    @SystemApi
     public int setFocusDuckingBehavior(int behavior)
             throws IllegalArgumentException, IllegalStateException {
         if ((behavior != FOCUS_POLICY_DUCKING_IN_APP)
@@ -466,7 +447,6 @@
      *     with {@link AudioManager#registerAudioPolicy(AudioPolicy)}.
      * @throws IllegalArgumentException
      */
-    @SystemApi
     public AudioRecord createAudioRecordSink(AudioMix mix) throws IllegalArgumentException {
         if (!policyReadyToUse()) {
             Log.e(TAG, "Cannot create AudioRecord sink for AudioMix");
@@ -506,7 +486,6 @@
      *     with {@link AudioManager#registerAudioPolicy(AudioPolicy)}.
      * @throws IllegalArgumentException
      */
-    @SystemApi
     public AudioTrack createAudioTrackSource(AudioMix mix) throws IllegalArgumentException {
         if (!policyReadyToUse()) {
             Log.e(TAG, "Cannot create AudioTrack source for AudioMix");
@@ -528,18 +507,15 @@
         return at;
     }
 
-    @SystemApi
     public int getStatus() {
         return mStatus;
     }
 
-    @SystemApi
     public static abstract class AudioPolicyStatusListener {
         public void onStatusChange() {}
         public void onMixStateUpdate(AudioMix mix) {}
     }
 
-    @SystemApi
     public static abstract class AudioPolicyFocusListener {
         public void onAudioFocusGrant(AudioFocusInfo afi, int requestResult) {}
         public void onAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {}
@@ -563,7 +539,6 @@
         public void onAudioFocusAbandon(AudioFocusInfo afi) {}
     }
 
-    @SystemApi
     /**
      * Callback class to receive volume change-related events.
      * See {@link #Builder.setAudioPolicyVolumeCallback(AudioPolicyCallback)} to configure the
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 143182f..a5121a0 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -1330,7 +1330,6 @@
      *
      * @return the list of content ratings blocked by the user.
      */
-    @SystemApi
     public List<TvContentRating> getBlockedRatings() {
         try {
             List<TvContentRating> ratings = new ArrayList<>();
diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp
index 15957c6..dad0e53 100644
--- a/media/jni/android_media_MediaExtractor.cpp
+++ b/media/jni/android_media_MediaExtractor.cpp
@@ -494,17 +494,17 @@
 
     if (extractor == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     int64_t sampleTimeUs;
     status_t err = extractor->getSampleTime(&sampleTimeUs);
 
     if (err == ERROR_END_OF_STREAM) {
-        return -1ll;
+        return -1LL;
     } else if (err != OK) {
         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     return (jlong) sampleTimeUs;
@@ -516,17 +516,17 @@
 
     if (extractor == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     size_t sampleSize;
     status_t err = extractor->getSampleSize(&sampleSize);
 
     if (err == ERROR_END_OF_STREAM) {
-        return -1ll;
+        return -1LL;
     } else if (err != OK) {
         jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     return (jlong) sampleSize;
@@ -828,13 +828,13 @@
 
     if (extractor == NULL) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return -1ll;
+        return -1LL;
     }
 
     int64_t cachedDurationUs;
     bool eos;
     if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) {
-        return -1ll;
+        return -1LL;
     }
 
     return (jlong) cachedDurationUs;
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index b7d7b03..45de36e 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -440,6 +440,7 @@
         if (lpVisualizer == 0) {
             return;
         }
+        lpVisualizer->release();
     }
     // delete the JNI data
     VisualizerJniStorage* lpJniStorage =
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index ac5ded6..f840d5e 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -218,6 +218,10 @@
     android_getaddrinfofornetwork; # introduced=23
     android_setprocnetwork; # introduced=23
     android_setsocknetwork; # introduced=23
+    android_res_cancel; # introduced=29
+    android_res_nquery; # introduced=29
+    android_res_nresult; # introduced=29
+    android_res_nsend; # introduced=29
   local:
     *;
 };
diff --git a/native/android/libandroid_net.map.txt b/native/android/libandroid_net.map.txt
index 9b5a5a1..be3531d 100644
--- a/native/android/libandroid_net.map.txt
+++ b/native/android/libandroid_net.map.txt
@@ -1,10 +1,15 @@
-# These functions have been part of the NDK since API 24.
 # They are also all available to vendor code.
 LIBANDROID_NET {
   global:
+    # These functions have been part of the NDK since API 24.
+    android_getaddrinfofornetwork; # vndk
     android_setsocknetwork; # vndk
     android_setprocnetwork; # vndk
-    android_getaddrinfofornetwork; # vndk
+    # These functions have been part of the NDK since API 29.
+    android_res_cancel; # vndk
+    android_res_nquery; # vndk
+    android_res_nresult; # vndk
+    android_res_nsend; # vndk
   local:
     *;
 };
diff --git a/native/android/net.c b/native/android/net.c
index 60296a7..4cac371 100644
--- a/native/android/net.c
+++ b/native/android/net.c
@@ -83,3 +83,29 @@
 
     return android_getaddrinfofornet(node, service, hints, netid, 0, res);
 }
+
+int android_res_nquery(net_handle_t network, const char *dname, int ns_class, int ns_type) {
+    unsigned netid;
+    if (!getnetidfromhandle(network, &netid)) {
+        return -ENONET;
+    }
+
+    return resNetworkQuery(netid, dname, ns_class, ns_type);
+}
+
+int android_res_nresult(int fd, int *rcode, uint8_t *answer, size_t anslen) {
+    return resNetworkResult(fd, rcode, answer, anslen);
+}
+
+int android_res_nsend(net_handle_t network, const uint8_t *msg, size_t msglen) {
+    unsigned netid;
+    if (!getnetidfromhandle(network, &netid)) {
+        return -ENONET;
+    }
+
+    return resNetworkSend(netid, msg, msglen);
+}
+
+void android_res_cancel(int nsend_fd) {
+    resNetworkCancel(nsend_fd);
+}
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
new file mode 100644
index 0000000..55bb517
--- /dev/null
+++ b/packages/NetworkStack/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2018 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.
+//
+
+// Library including the network stack, used to compile the network stack app, or linked into the
+// system server on devices that run the stack there
+java_library {
+    name: "NetworkStackLib",
+    installable: true,
+    srcs: [
+        "src/**/*.java",
+    ],
+}
+
+// Updatable network stack packaged as an application
+android_app {
+    name: "NetworkStack",
+    platform_apis: true,
+    certificate: "platform",
+    privileged: true,
+    static_libs: [
+        "NetworkStackLib"
+    ],
+    manifest: "AndroidManifest.xml",
+}
\ No newline at end of file
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
new file mode 100644
index 0000000..d1c5cb6
--- /dev/null
+++ b/packages/NetworkStack/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2014 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.google.android.networkstack"
+          android:sharedUserId="android.uid.networkstack">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <!-- Launch captive portal app as specific user -->
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <application
+        android:label="NetworkStack"
+        android:defaultToDeviceProtectedStorage="true"
+        android:directBootAware="true"
+        android:usesCleartextTraffic="true">
+        <service android:name="com.android.server.NetworkStackService">
+            <intent-filter>
+                <action android:name="android.net.INetworkStackConnector"/>
+            </intent-filter>
+        </service>
+    </application>
+</manifest>
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
new file mode 100644
index 0000000..5afaf58
--- /dev/null
+++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2018 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 static android.os.Binder.getCallingUid;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Service;
+import android.content.Intent;
+import android.net.INetworkStackConnector;
+import android.os.IBinder;
+import android.os.Process;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Android service used to start the network stack when bound to via an intent.
+ *
+ * <p>The service returns a binder for the system server to communicate with the network stack.
+ */
+public class NetworkStackService extends Service {
+    private static final String TAG = NetworkStackService.class.getSimpleName();
+
+    /**
+     * Create a binder connector for the system server to communicate with the network stack.
+     *
+     * <p>On platforms where the network stack runs in the system server process, this method may
+     * be called directly instead of obtaining the connector by binding to the service.
+     */
+    public static IBinder makeConnector() {
+        return new NetworkStackConnector();
+    }
+
+    @NonNull
+    @Override
+    public IBinder onBind(Intent intent) {
+        return makeConnector();
+    }
+
+    private static class NetworkStackConnector extends INetworkStackConnector.Stub {
+        // TODO: makeDhcpServer(), etc. will go here.
+
+        @Override
+        protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
+                @Nullable String[] args) {
+            checkCaller();
+            fout.println("NetworkStack logs:");
+            // TODO: dump logs here
+        }
+    }
+
+    private static void checkCaller() {
+        // TODO: check that the calling PID is the system server.
+        if (getCallingUid() != Process.SYSTEM_UID && getCallingUid() != Process.ROOT_UID) {
+            throw new SecurityException("Invalid caller: " + getCallingUid());
+        }
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index a3c1fc6..fd80edf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -62,6 +62,7 @@
 import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
 import java.text.Collator;
 import java.text.Normalizer;
 import java.text.Normalizer.Form;
@@ -132,7 +133,7 @@
     boolean mSessionsChanged;
 
     // Temporary for dispatching session callbacks.  Only touched by main thread.
-    final ArrayList<Session> mActiveSessions = new ArrayList<Session>();
+    final ArrayList<WeakReference<Session>> mActiveSessions = new ArrayList<>();
 
     final HandlerThread mThread;
     final BackgroundHandler mBackgroundHandler;
@@ -618,7 +619,7 @@
             for (int i=0; i<mSessions.size(); i++) {
                 Session s = mSessions.get(i);
                 if (s.mResumed) {
-                    mActiveSessions.add(s);
+                    mActiveSessions.add(new WeakReference<>(s));
                 }
             }
         }
@@ -830,46 +831,70 @@
             rebuildActiveSessions();
             switch (msg.what) {
                 case MSG_REBUILD_COMPLETE: {
-                    Session s = (Session)msg.obj;
-                    if (mActiveSessions.contains(s)) {
-                        s.mCallbacks.onRebuildComplete(s.mLastAppList);
+                    Session s = (Session) msg.obj;
+                    for (WeakReference<Session> sessionRef : mActiveSessions) {
+                        final Session session = sessionRef.get();
+                        if (session != null && session == s) {
+                            s.mCallbacks.onRebuildComplete(s.mLastAppList);
+                        }
                     }
                 } break;
                 case MSG_PACKAGE_LIST_CHANGED: {
-                    for (int i=0; i<mActiveSessions.size(); i++) {
-                        mActiveSessions.get(i).mCallbacks.onPackageListChanged();
+                    for (WeakReference<Session> sessionRef : mActiveSessions) {
+                        final Session session = sessionRef.get();
+                        if (session != null) {
+                            session.mCallbacks.onPackageListChanged();
+                        }
                     }
                 } break;
                 case MSG_PACKAGE_ICON_CHANGED: {
-                    for (int i=0; i<mActiveSessions.size(); i++) {
-                        mActiveSessions.get(i).mCallbacks.onPackageIconChanged();
+                    for (WeakReference<Session> sessionRef : mActiveSessions) {
+                        final Session session = sessionRef.get();
+                        if (session != null) {
+                            session.mCallbacks.onPackageIconChanged();
+                        }
                     }
                 } break;
                 case MSG_PACKAGE_SIZE_CHANGED: {
-                    for (int i=0; i<mActiveSessions.size(); i++) {
-                        mActiveSessions.get(i).mCallbacks.onPackageSizeChanged(
-                                (String)msg.obj);
+                    for (WeakReference<Session> sessionRef : mActiveSessions) {
+                        final Session session = sessionRef.get();
+                        if (session != null) {
+                            session.mCallbacks.onPackageSizeChanged(
+                                    (String) msg.obj);
+                        }
                     }
                 } break;
                 case MSG_ALL_SIZES_COMPUTED: {
-                    for (int i=0; i<mActiveSessions.size(); i++) {
-                        mActiveSessions.get(i).mCallbacks.onAllSizesComputed();
+                    for (WeakReference<Session> sessionRef : mActiveSessions) {
+                        final Session session = sessionRef.get();
+                        if (session != null) {
+                            session.mCallbacks.onAllSizesComputed();
+                        }
                     }
                 } break;
                 case MSG_RUNNING_STATE_CHANGED: {
-                    for (int i=0; i<mActiveSessions.size(); i++) {
-                        mActiveSessions.get(i).mCallbacks.onRunningStateChanged(
-                                msg.arg1 != 0);
+                    for (WeakReference<Session> sessionRef : mActiveSessions) {
+                        final Session session = sessionRef.get();
+                        if (session != null) {
+                            session.mCallbacks.onRunningStateChanged(
+                                    msg.arg1 != 0);
+                        }
                     }
                 } break;
                 case MSG_LAUNCHER_INFO_CHANGED: {
-                    for (int i=0; i<mActiveSessions.size(); i++) {
-                        mActiveSessions.get(i).mCallbacks.onLauncherInfoChanged();
+                    for (WeakReference<Session> sessionRef : mActiveSessions) {
+                        final Session session = sessionRef.get();
+                        if (session != null) {
+                            session.mCallbacks.onLauncherInfoChanged();
+                        }
                     }
                 } break;
                 case MSG_LOAD_ENTRIES_COMPLETE: {
-                    for (int i=0; i<mActiveSessions.size(); i++) {
-                        mActiveSessions.get(i).mCallbacks.onLoadEntriesCompleted();
+                    for (WeakReference<Session> sessionRef : mActiveSessions) {
+                        final Session session = sessionRef.get();
+                        if (session != null) {
+                            session.mCallbacks.onLoadEntriesCompleted();
+                        }
                     }
                 } break;
             }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java
index 3732471..1c50953 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java
@@ -19,6 +19,8 @@
 import android.content.Context;
 import android.util.Log;
 
+import java.lang.ref.WeakReference;
+
 /**
  * LocalBluetoothManager provides a simplified interface on top of a subset of
  * the Bluetooth API. Note that {@link #getInstance} will return null
@@ -34,7 +36,7 @@
     private final Context mContext;
 
     /** If a BT-related activity is in the foreground, this will be it. */
-    private Context mForegroundActivity;
+    private WeakReference<Context> mForegroundActivity;
 
     private final LocalBluetoothAdapter mLocalAdapter;
 
@@ -85,17 +87,19 @@
     }
 
     public Context getForegroundActivity() {
-        return mForegroundActivity;
+        return mForegroundActivity == null
+                ? null
+                : mForegroundActivity.get();
     }
 
     public boolean isForegroundActivity() {
-        return mForegroundActivity != null;
+        return mForegroundActivity != null && mForegroundActivity.get() != null;
     }
 
     public synchronized void setForegroundActivity(Context context) {
         if (context != null) {
             Log.d(TAG, "setting foreground activity to non-null context");
-            mForegroundActivity = context;
+            mForegroundActivity = new WeakReference<>(context);
         } else {
             if (mForegroundActivity != null) {
                 Log.d(TAG, "setting foreground activity to null");
diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
index 988060e..e5d97c9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
+++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java
@@ -36,12 +36,12 @@
 import android.util.Log;
 import android.util.Xml;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -97,15 +97,15 @@
     }
 
     public DreamBackend(Context context) {
-        mContext = context;
+        mContext = context.getApplicationContext();
         mDreamManager = IDreamManager.Stub.asInterface(
                 ServiceManager.getService(DreamService.DREAM_SERVICE));
         mComparator = new DreamInfoComparator(getDefaultDream());
-        mDreamsEnabledByDefault = context.getResources()
+        mDreamsEnabledByDefault = mContext.getResources()
                 .getBoolean(com.android.internal.R.bool.config_dreamsEnabledByDefault);
-        mDreamsActivatedOnSleepByDefault = context.getResources()
+        mDreamsActivatedOnSleepByDefault = mContext.getResources()
                 .getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault);
-        mDreamsActivatedOnDockByDefault = context.getResources()
+        mDreamsActivatedOnDockByDefault = mContext.getResources()
                 .getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault);
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
index 4c45a75..cb2a088 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
@@ -25,9 +25,9 @@
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.sysprop.CarProperties;
 import android.util.Log;
 
 import com.android.internal.util.UserIcons;
@@ -43,7 +43,6 @@
 @Deprecated
 public final class UserManagerHelper {
     private static final String TAG = "UserManagerHelper";
-    private static final String HEADLESS_SYSTEM_USER = "android.car.systemuser.headless";
     private final Context mContext;
     private final UserManager mUserManager;
     private final ActivityManager mActivityManager;
@@ -84,7 +83,7 @@
      * @return {@boolean true} if headless system user.
      */
     public boolean isHeadlessSystemUser() {
-        return SystemProperties.getBoolean(HEADLESS_SYSTEM_USER, false);
+        return CarProperties.headless_system_user().orElse(false);
     }
 
     /**
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index adeff5d..9306219 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -26,6 +26,7 @@
     <uses-permission android:name="android.permission.SEND_SMS" />
     <uses-permission android:name="android.permission.CALL_PHONE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
     <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index bc9f52c..bca3530 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -43,7 +43,7 @@
     boolean isAvailable();
     void setTileSpec(String tileSpec);
 
-    void clearState();
+    @Deprecated default void clearState() {}
     void refreshState();
 
     void addCallback(Callback callback);
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index baaf699..d72021e 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -18,14 +18,16 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginStart="@dimen/rounded_corner_content_padding"
+    android:layout_marginEnd="@dimen/rounded_corner_content_padding"
+    android:paddingStart="@dimen/nav_content_padding"
+    android:paddingEnd="@dimen/nav_content_padding">
 
     <com.android.systemui.statusbar.phone.NearestTouchFrame
         android:id="@+id/nav_buttons"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:paddingStart="@dimen/rounded_corner_content_padding"
-        android:paddingEnd="@dimen/rounded_corner_content_padding"
         android:clipChildren="false"
         android:clipToPadding="false">
 
@@ -34,8 +36,6 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:orientation="horizontal"
-            android:paddingStart="@dimen/nav_content_padding"
-            android:paddingEnd="@dimen/nav_content_padding"
             android:clipToPadding="false"
             android:clipChildren="false" />
 
@@ -46,8 +46,6 @@
             android:layout_gravity="center"
             android:gravity="center"
             android:orientation="horizontal"
-            android:paddingStart="@dimen/nav_content_padding"
-            android:paddingEnd="@dimen/nav_content_padding"
             android:clipToPadding="false"
             android:clipChildren="false" />
 
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 6d5b7788..24a0c71 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -18,14 +18,16 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_marginTop="@dimen/rounded_corner_content_padding"
+    android:layout_marginBottom="@dimen/rounded_corner_content_padding"
+    android:paddingTop="@dimen/nav_content_padding"
+    android:paddingBottom="@dimen/nav_content_padding">
 
     <com.android.systemui.statusbar.phone.NearestTouchFrame
         android:id="@+id/nav_buttons"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:paddingTop="@dimen/rounded_corner_content_padding"
-        android:paddingBottom="@dimen/rounded_corner_content_padding"
         android:clipChildren="false"
         android:clipToPadding="false">
 
@@ -34,10 +36,8 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:orientation="vertical"
-            android:paddingTop="@dimen/nav_content_padding"
-            android:paddingBottom="@dimen/nav_content_padding"
-            android:clipChildren="false"
-            android:clipToPadding="false" />
+            android:clipToPadding="false"
+            android:clipChildren="false" />
 
         <com.android.systemui.statusbar.phone.ReverseLinearLayout
             android:id="@+id/center_group"
@@ -45,10 +45,8 @@
             android:layout_height="match_parent"
             android:gravity="center"
             android:orientation="vertical"
-            android:paddingTop="@dimen/nav_content_padding"
-            android:paddingBottom="@dimen/nav_content_padding"
-            android:clipChildren="false"
-            android:clipToPadding="false" />
+            android:clipToPadding="false"
+            android:clipChildren="false" />
 
     </com.android.systemui.statusbar.phone.NearestTouchFrame>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index be80d52..79e1fae 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -943,9 +943,9 @@
     <dimen name="bottom_padding">48dp</dimen>
     <dimen name="edge_margin">8dp</dimen>
 
-    <dimen name="rounded_corner_radius">0dp</dimen>
-    <dimen name="rounded_corner_radius_top">0dp</dimen>
-    <dimen name="rounded_corner_radius_bottom">0dp</dimen>
+    <dimen name="rounded_corner_radius">@*android:dimen/rounded_corner_radius</dimen>
+    <dimen name="rounded_corner_radius_top">@*android:dimen/rounded_corner_radius_top</dimen>
+    <dimen name="rounded_corner_radius_bottom">@*android:dimen/rounded_corner_radius_bottom</dimen>
     <dimen name="rounded_corner_content_padding">0dp</dimen>
     <dimen name="nav_content_padding">0dp</dimen>
     <dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 35abb0a..03fb9bb 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -15,7 +15,6 @@
  */
 package com.android.keyguard;
 
-import android.R.style;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.admin.DevicePolicyManager;
@@ -26,7 +25,6 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.StatsLog;
-import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
@@ -142,6 +140,7 @@
             mSecurityViewFlipper.addView(v);
             updateSecurityView(v);
             view = (KeyguardSecurityView)v;
+            view.reset();
         }
 
         return view;
@@ -209,7 +208,7 @@
 
         if (messageId != 0) {
             final String message = mContext.getString(messageId,
-                    KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(userId),
+                    mLockPatternUtils.getCurrentFailedPasswordAttempts(userId),
                     timeoutInSeconds);
             showDialog(null, message);
         }
@@ -254,8 +253,8 @@
     }
 
     private void reportFailedUnlockAttempt(int userId, int timeoutMs) {
-        final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
-        final int failedAttempts = monitor.getFailedUnlockAttempts(userId) + 1; // +1 for this time
+        // +1 for this time
+        final int failedAttempts = mLockPatternUtils.getCurrentFailedPasswordAttempts(userId) + 1;
 
         if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
 
@@ -289,7 +288,6 @@
                 showWipeDialog(failedAttempts, userType);
             }
         }
-        monitor.reportFailedStrongAuthUnlockAttempt(userId);
         mLockPatternUtils.reportFailedPasswordAttempt(userId);
         if (timeoutMs > 0) {
             mLockPatternUtils.reportPasswordLockout(timeoutMs, userId);
@@ -432,7 +430,6 @@
             if (success) {
                 StatsLog.write(StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED,
                     StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__SUCCESS);
-                monitor.clearFailedUnlockAttempts();
                 mLockPatternUtils.reportSuccessfulPasswordAttempt(userId);
             } else {
                 StatsLog.write(StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED,
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index ef3aa42..0e21815 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -209,9 +209,6 @@
     // Battery status
     private BatteryStatus mBatteryStatus;
 
-    // Password attempts
-    private SparseIntArray mFailedAttempts = new SparseIntArray();
-
     private final StrongAuthTracker mStrongAuthTracker;
 
     private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
@@ -1800,22 +1797,10 @@
         return mDeviceProvisioned;
     }
 
-    public void clearFailedUnlockAttempts() {
-        mFailedAttempts.delete(sCurrentUser);
-    }
-
     public ServiceState getServiceState(int subId) {
         return mServiceStates.get(subId);
     }
 
-    public int getFailedUnlockAttempts(int userId) {
-        return mFailedAttempts.get(userId, 0);
-    }
-
-    public void reportFailedStrongAuthUnlockAttempt(int userId) {
-        mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1);
-    }
-
     public void clearFingerprintRecognized() {
         mUserFingerprintAuthenticated.clear();
         mTrustManager.clearAllFingerprints();
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 79302f2..16b54b4 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -39,10 +39,13 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.display.DisplayManager;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.SystemProperties;
 import android.provider.Settings.Secure;
 import androidx.annotation.VisibleForTesting;
 import android.util.DisplayMetrics;
+import android.util.Log;
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.Gravity;
@@ -57,6 +60,7 @@
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 
+import com.android.internal.util.Preconditions;
 import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView;
 import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
@@ -74,6 +78,9 @@
  * for antialiasing and emulation purposes.
  */
 public class ScreenDecorations extends SystemUI implements Tunable {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "ScreenDecorations";
+
     public static final String SIZE = "sysui_rounded_size";
     public static final String PADDING = "sysui_rounded_content_padding";
     private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS =
@@ -82,9 +89,9 @@
     private DisplayManager mDisplayManager;
     private DisplayManager.DisplayListener mDisplayListener;
 
-    private int mRoundedDefault;
-    private int mRoundedDefaultTop;
-    private int mRoundedDefaultBottom;
+    @VisibleForTesting protected int mRoundedDefault;
+    @VisibleForTesting protected int mRoundedDefaultTop;
+    @VisibleForTesting protected int mRoundedDefaultBottom;
     private View mOverlay;
     private View mBottomOverlay;
     private float mDensity;
@@ -93,26 +100,30 @@
     private DisplayCutoutView mCutoutTop;
     private DisplayCutoutView mCutoutBottom;
     private boolean mPendingRotationChange;
+    private Handler mHandler;
 
     @Override
     public void start() {
+        mHandler = startHandlerThread();
+        mHandler.post(this::startOnScreenDecorationsThread);
+        setupStatusBarPaddingIfNeeded();
+    }
+
+    @VisibleForTesting
+    Handler startHandlerThread() {
+        HandlerThread thread = new HandlerThread("ScreenDecorations");
+        thread.start();
+        return thread.getThreadHandler();
+    }
+
+    private void startOnScreenDecorationsThread() {
+        mRotation = RotationUtils.getExactRotation(mContext);
         mWindowManager = mContext.getSystemService(WindowManager.class);
-        mRoundedDefault = mContext.getResources().getDimensionPixelSize(
-                R.dimen.rounded_corner_radius);
-        mRoundedDefaultTop = mContext.getResources().getDimensionPixelSize(
-                R.dimen.rounded_corner_radius_top);
-        mRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize(
-                R.dimen.rounded_corner_radius_bottom);
+        updateRoundedCornerRadii();
         if (hasRoundedCorners() || shouldDrawCutout()) {
             setupDecorations();
         }
 
-        int padding = mContext.getResources().getDimensionPixelSize(
-                R.dimen.rounded_corner_content_padding);
-        if (padding != 0) {
-            setupPadding(padding);
-        }
-
         mDisplayListener = new DisplayManager.DisplayListener() {
             @Override
             public void onDisplayAdded(int displayId) {
@@ -126,8 +137,8 @@
 
             @Override
             public void onDisplayChanged(int displayId) {
-                if (mOverlay != null && mBottomOverlay != null
-                        && mRotation != RotationUtils.getExactRotation(mContext)) {
+                final int newRotation = RotationUtils.getExactRotation(mContext);
+                if (mOverlay != null && mBottomOverlay != null && mRotation != newRotation) {
                     // We cannot immediately update the orientation. Otherwise
                     // WindowManager is still deferring layout until it has finished dispatching
                     // the config changes, which may cause divergence between what we draw
@@ -136,20 +147,24 @@
                     // - we are trying to redraw. This because WM resized our window and told us to.
                     // - the config change has been dispatched, so WM is no longer deferring layout.
                     mPendingRotationChange = true;
-                    mOverlay.getViewTreeObserver().addOnPreDrawListener(
-                            new RestartingPreDrawListener(mOverlay));
-                    mBottomOverlay.getViewTreeObserver().addOnPreDrawListener(
-                            new RestartingPreDrawListener(mBottomOverlay));
+                    if (DEBUG) {
+                        Log.i(TAG, "Rotation changed, deferring " + newRotation + ", staying at "
+                                + mRotation);
+                    }
 
+                    mOverlay.getViewTreeObserver().addOnPreDrawListener(
+                            new RestartingPreDrawListener(mOverlay, newRotation));
+                    mBottomOverlay.getViewTreeObserver().addOnPreDrawListener(
+                            new RestartingPreDrawListener(mBottomOverlay, newRotation));
                 }
                 updateOrientation();
             }
         };
 
-        mRotation = -1;
         mDisplayManager = (DisplayManager) mContext.getSystemService(
                 Context.DISPLAY_SERVICE);
-        mDisplayManager.registerDisplayListener(mDisplayListener, null);
+        mDisplayManager.registerDisplayListener(mDisplayListener, mHandler);
+        updateOrientation();
     }
 
     private void setupDecorations() {
@@ -179,10 +194,11 @@
         mWindowManager.getDefaultDisplay().getMetrics(metrics);
         mDensity = metrics.density;
 
-        Dependency.get(TunerService.class).addTunable(this, SIZE);
+        Dependency.get(Dependency.MAIN_HANDLER).post(
+                () -> Dependency.get(TunerService.class).addTunable(this, SIZE));
 
         // Watch color inversion and invert the overlay as needed.
-        SecureSetting setting = new SecureSetting(mContext, Dependency.get(Dependency.MAIN_HANDLER),
+        SecureSetting setting = new SecureSetting(mContext, mHandler,
                 Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) {
             @Override
             protected void handleValueChanged(int value, boolean observedChange) {
@@ -215,18 +231,38 @@
                         .start();
             }
         });
+
+        mOverlay.getViewTreeObserver().addOnPreDrawListener(
+                new ValidatingPreDrawListener(mOverlay));
+        mBottomOverlay.getViewTreeObserver().addOnPreDrawListener(
+                new ValidatingPreDrawListener(mBottomOverlay));
     }
 
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
-        mPendingRotationChange = false;
-        updateOrientation();
-        if (shouldDrawCutout() && mOverlay == null) {
-            setupDecorations();
-        }
+        mHandler.post(() -> {
+            int oldRotation = mRotation;
+            mPendingRotationChange = false;
+            updateOrientation();
+            updateRoundedCornerRadii();
+            if (DEBUG) Log.i(TAG, "onConfigChanged from rot " + oldRotation + " to " + mRotation);
+            if (shouldDrawCutout() && mOverlay == null) {
+                setupDecorations();
+            }
+            if (mOverlay != null) {
+                // Updating the layout params ensures that ViewRootImpl will call relayoutWindow(),
+                // which ensures that the forced seamless rotation will end, even if we updated
+                // the rotation before window manager was ready (and was still waiting for sending
+                // the updated rotation).
+                updateLayoutParams();
+            }
+        });
     }
 
-    protected void updateOrientation() {
+    private void updateOrientation() {
+        Preconditions.checkState(mHandler.getLooper().getThread() == Thread.currentThread(),
+                "must call on " + mHandler.getLooper().getThread()
+                        + ", but was " + Thread.currentThread());
         if (mPendingRotationChange) {
             return;
         }
@@ -241,6 +277,26 @@
         }
     }
 
+    private void updateRoundedCornerRadii() {
+        final int newRoundedDefault = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius);
+        final int newRoundedDefaultTop = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius_top);
+        final int newRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius_bottom);
+
+        final boolean roundedCornersChanged = mRoundedDefault != newRoundedDefault
+                || mRoundedDefaultBottom != newRoundedDefaultBottom
+                || mRoundedDefaultTop != newRoundedDefaultTop;
+
+        if (roundedCornersChanged) {
+            mRoundedDefault = newRoundedDefault;
+            mRoundedDefaultTop = newRoundedDefaultTop;
+            mRoundedDefaultBottom = newRoundedDefaultBottom;
+            onTuningChanged(SIZE, null);
+        }
+    }
+
     private void updateViews() {
         View topLeft = mOverlay.findViewById(R.id.left);
         View topRight = mOverlay.findViewById(R.id.right);
@@ -306,7 +362,19 @@
                 com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout);
     }
 
-    private void setupPadding(int padding) {
+
+    private void setupStatusBarPaddingIfNeeded() {
+        // TODO: This should be moved to a more appropriate place, as it is not related to the
+        // screen decorations overlay.
+        int padding = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_content_padding);
+        if (padding != 0) {
+            setupStatusBarPadding(padding);
+        }
+
+    }
+
+    private void setupStatusBarPadding(int padding) {
         // Add some padding to all the content near the edge of the screen.
         StatusBar sb = getComponent(StatusBar.class);
         View statusBar = (sb != null ? sb.getStatusBarWindow() : null);
@@ -375,30 +443,32 @@
 
     @Override
     public void onTuningChanged(String key, String newValue) {
-        if (mOverlay == null) return;
-        if (SIZE.equals(key)) {
-            int size = mRoundedDefault;
-            int sizeTop = mRoundedDefaultTop;
-            int sizeBottom = mRoundedDefaultBottom;
-            if (newValue != null) {
-                try {
-                    size = (int) (Integer.parseInt(newValue) * mDensity);
-                } catch (Exception e) {
+        mHandler.post(() -> {
+            if (mOverlay == null) return;
+            if (SIZE.equals(key)) {
+                int size = mRoundedDefault;
+                int sizeTop = mRoundedDefaultTop;
+                int sizeBottom = mRoundedDefaultBottom;
+                if (newValue != null) {
+                    try {
+                        size = (int) (Integer.parseInt(newValue) * mDensity);
+                    } catch (Exception e) {
+                    }
                 }
-            }
 
-            if (sizeTop == 0) {
-                sizeTop = size;
-            }
-            if (sizeBottom == 0) {
-                sizeBottom = size;
-            }
+                if (sizeTop == 0) {
+                    sizeTop = size;
+                }
+                if (sizeBottom == 0) {
+                    sizeBottom = size;
+                }
 
-            setSize(mOverlay.findViewById(R.id.left), sizeTop);
-            setSize(mOverlay.findViewById(R.id.right), sizeTop);
-            setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom);
-            setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom);
-        }
+                setSize(mOverlay.findViewById(R.id.left), sizeTop);
+                setSize(mOverlay.findViewById(R.id.right), sizeTop);
+                setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom);
+                setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom);
+            }
+        });
     }
 
     private void setSize(View view, int pixelSize) {
@@ -457,6 +527,11 @@
             mVisibilityChangedListener = visibilityChangedListener;
             mDecorations = decorations;
             setId(R.id.display_cutout);
+            if (DEBUG) {
+                getViewTreeObserver().addOnDrawListener(() -> Log.i(TAG,
+                        (mInitialStart ? "OverlayTop" : "OverlayBottom")
+                                + " drawn in rot " + mRotation));
+            }
         }
 
         public void setColor(int color) {
@@ -692,20 +767,66 @@
     private class RestartingPreDrawListener implements ViewTreeObserver.OnPreDrawListener {
 
         private final View mView;
+        private final int mTargetRotation;
 
-        private RestartingPreDrawListener(View view) {
+        private RestartingPreDrawListener(View view, int targetRotation) {
+            mView = view;
+            mTargetRotation = targetRotation;
+        }
+
+        @Override
+        public boolean onPreDraw() {
+            mView.getViewTreeObserver().removeOnPreDrawListener(this);
+
+            if (mTargetRotation == mRotation) {
+                if (DEBUG) {
+                    Log.i(TAG, (mView == mOverlay ? "OverlayTop" : "OverlayBottom")
+                            + " already in target rot "
+                            + mTargetRotation + ", allow draw without restarting it");
+                }
+                return true;
+            }
+
+            mPendingRotationChange = false;
+            // This changes the window attributes - we need to restart the traversal for them to
+            // take effect.
+            updateOrientation();
+            if (DEBUG) {
+                Log.i(TAG, (mView == mOverlay ? "OverlayTop" : "OverlayBottom")
+                        + " restarting listener fired, restarting draw for rot " + mRotation);
+            }
+            mView.invalidate();
+            return false;
+        }
+    }
+
+    /**
+     * A pre-draw listener, that validates that the rotation we draw in matches the displays
+     * rotation before continuing the draw.
+     *
+     * This is to prevent a race condition, where we have not received the display changed event
+     * yet, and would thus draw in an old orientation.
+     */
+    private class ValidatingPreDrawListener implements ViewTreeObserver.OnPreDrawListener {
+
+        private final View mView;
+
+        public ValidatingPreDrawListener(View view) {
             mView = view;
         }
 
         @Override
         public boolean onPreDraw() {
-            mPendingRotationChange = false;
-            mView.getViewTreeObserver().removeOnPreDrawListener(this);
-            // This changes the window attributes - we need to restart the traversal for them to
-            // take effect.
-            updateOrientation();
-            mView.invalidate();
-            return false;
+            final int displayRotation = RotationUtils.getExactRotation(mContext);
+            if (displayRotation != mRotation && !mPendingRotationChange) {
+                if (DEBUG) {
+                    Log.i(TAG, "Drawing rot " + mRotation + ", but display is at rot "
+                            + displayRotation + ". Restarting draw");
+                }
+                mView.invalidate();
+                return false;
+            }
+            return true;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 89688fb..33db2c8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -1647,7 +1647,6 @@
             resetKeyguardDonePendingLocked();
         }
 
-        mUpdateMonitor.clearFailedUnlockAttempts();
         mUpdateMonitor.clearFingerprintRecognized();
 
         if (mGoingToSleep) {
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index da41136..2e5eb34 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -266,9 +266,12 @@
                 || mEstimate.estimateMillis < mSevereWarningThreshold) {
             nb.setColor(Utils.getColorAttr(mContext, android.R.attr.colorError));
         }
-        nb.addAction(0,
-                mContext.getString(R.string.battery_saver_start_action),
-                pendingBroadcast(ACTION_START_SAVER));
+
+        if (!mPowerMan.isPowerSaveMode()) {
+            nb.addAction(0,
+                    mContext.getString(R.string.battery_saver_start_action),
+                    pendingBroadcast(ACTION_START_SAVER));
+        }
         nb.setOnlyAlertOnce(!mPlaySound);
         mPlaySound = false;
         SystemUI.overrideNotificationAppName(mContext, nb, false);
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 9a648d1..0b9067e 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -333,10 +333,11 @@
     @VisibleForTesting
     boolean shouldDismissLowBatteryWarning(boolean plugged, int oldBucket, int bucket,
             long timeRemaining, boolean isPowerSaver) {
-        final boolean hybridWouldDismiss = mEnhancedEstimates.isHybridNotificationEnabled()
+        final boolean hybridEnabled = mEnhancedEstimates.isHybridNotificationEnabled();
+        final boolean hybridWouldDismiss = hybridEnabled
                 && timeRemaining > mEnhancedEstimates.getLowWarningThreshold();
         final boolean standardWouldDismiss = (bucket > oldBucket && bucket > 0);
-        return isPowerSaver
+        return (isPowerSaver && !hybridEnabled)
                 || plugged
                 || (standardWouldDismiss && (!mEnhancedEstimates.isHybridNotificationEnabled()
                         || hybridWouldDismiss));
@@ -344,14 +345,14 @@
 
     private boolean isEnhancedTrigger(boolean plugged, long timeRemaining, boolean isPowerSaver,
             int batteryStatus) {
-        if (plugged || isPowerSaver || batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
+        if (plugged || batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
             return false;
         }
         int warnLevel = mLowBatteryReminderLevels[0];
         int critLevel = mLowBatteryReminderLevels[1];
 
-        // Only show the low warning once per charge cycle
-        final boolean canShowWarning = !mLowWarningShownThisChargeCycle
+        // Only show the low warning once per charge cycle & no battery saver
+        final boolean canShowWarning = !mLowWarningShownThisChargeCycle && !isPowerSaver
                 && (timeRemaining < mEnhancedEstimates.getLowWarningThreshold()
                         || mBatteryLevel <= warnLevel);
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 0876a5d..3fc258b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -285,9 +285,6 @@
 
         updatePageIndicator();
 
-        for (TileRecord r : mRecords) {
-            r.tile.clearState();
-        }
         if (mListening) {
             refreshAllTiles();
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index 53a576d..591e9e0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -95,7 +95,6 @@
                 continue;
             }
             tile.setListening(this, true);
-            tile.clearState();
             tile.refreshState();
             tile.setListening(this, false);
             tile.setTileSpec(spec);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 834feb7..022a2b4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -211,10 +211,6 @@
         mHandler.obtainMessage(H.REFRESH_STATE, arg).sendToTarget();
     }
 
-    public void clearState() {
-        mHandler.sendEmptyMessage(H.CLEAR_STATE);
-    }
-
     public void userSwitch(int newUserId) {
         mHandler.obtainMessage(H.USER_SWITCH, newUserId, 0).sendToTarget();
     }
@@ -266,11 +262,6 @@
 
     public abstract Intent getLongClickIntent();
 
-    protected void handleClearState() {
-        mTmpState = newTileState();
-        mState = newTileState();
-    }
-
     protected void handleRefreshState(Object arg) {
         handleUpdateState(mTmpState, arg);
         final boolean changed = mTmpState.copyTo(mState);
@@ -409,11 +400,10 @@
         private static final int TOGGLE_STATE_CHANGED = 8;
         private static final int SCAN_STATE_CHANGED = 9;
         private static final int DESTROY = 10;
-        private static final int CLEAR_STATE = 11;
-        private static final int REMOVE_CALLBACKS = 12;
-        private static final int REMOVE_CALLBACK = 13;
-        private static final int SET_LISTENING = 14;
-        private static final int STALE = 15;
+        private static final int REMOVE_CALLBACKS = 11;
+        private static final int REMOVE_CALLBACK = 12;
+        private static final int SET_LISTENING = 13;
+        private static final int STALE = 14;
 
         @VisibleForTesting
         protected H(Looper looper) {
@@ -467,9 +457,6 @@
                 } else if (msg.what == DESTROY) {
                     name = "handleDestroy";
                     handleDestroy();
-                } else if (msg.what == CLEAR_STATE) {
-                    name = "handleClearState";
-                    handleClearState();
                 } else if (msg.what == SET_LISTENING) {
                     name = "handleSetListeningInternal";
                     handleSetListeningInternal(msg.obj, msg.arg1 != 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
index 06f26c9..469c3c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java
@@ -667,9 +667,15 @@
                     entry.row.getNotificationChildren();
             for (int i = 0; i < notificationChildren.size(); i++) {
                 ExpandableNotificationRow row = notificationChildren.get(i);
-                if ((row.getStatusBarNotification().getNotification().flags
-                        & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
-                    // the child is a foreground service notification which we can't remove!
+                NotificationData.Entry childEntry = row.getEntry();
+                boolean isForeground = (row.getStatusBarNotification().getNotification().flags
+                        & Notification.FLAG_FOREGROUND_SERVICE) != 0;
+                boolean keepForReply = FORCE_REMOTE_INPUT_HISTORY
+                        && (shouldKeepForRemoteInput(childEntry)
+                                || shouldKeepForSmartReply(childEntry));
+                if (isForeground || keepForReply) {
+                    // the child is a foreground service notification which we can't remove or it's
+                    // a child we're keeping around for reply!
                     continue;
                 }
                 row.setKeepInParent(true);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 3063199..a215ec6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -151,12 +151,11 @@
     }
 
     public void fadeInTranslating() {
-        float translation = mShelfIcons.getTranslationY();
-        mShelfIcons.setTranslationY(translation - mShelfAppearTranslation);
+        mShelfIcons.setTranslationY(-mShelfAppearTranslation);
         mShelfIcons.setAlpha(0);
         mShelfIcons.animate()
                 .setInterpolator(Interpolators.DECELERATE_QUINT)
-                .translationY(translation)
+                .translationY(0)
                 .setDuration(SHELF_IN_TRANSLATION_DURATION)
                 .start();
         mShelfIcons.animate()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 83021ca..be46d2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -19,7 +19,7 @@
 import android.app.ActivityManager;
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
-import android.os.SystemProperties;
+import android.sysprop.CarProperties;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
@@ -56,7 +56,7 @@
         CarBatteryController.BatteryViewHandler {
     private static final String TAG = "CarStatusBar";
     public static final boolean ENABLE_HVAC_CONNECTION
-            = !SystemProperties.getBoolean("android.car.hvac.demo", true);
+            = !CarProperties.hvac_demo().orElse(true);
 
     private TaskStackListenerImpl mTaskStackListener;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 7e6abe9..5c18782 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1358,9 +1358,7 @@
         mQsExpansionHeight = height;
         updateQsExpansion();
         requestScrollerTopPaddingUpdate(false /* animate */);
-        if (mKeyguardShowing) {
-            updateHeaderKeyguardAlpha();
-        }
+        updateHeaderKeyguardAlpha();
         if (mStatusBarState == StatusBarState.SHADE_LOCKED
                 || mStatusBarState == StatusBarState.KEYGUARD) {
             updateKeyguardBottomAreaAlpha();
@@ -1763,6 +1761,9 @@
     }
 
     private void updateHeaderKeyguardAlpha() {
+        if (!mKeyguardShowing) {
+            return;
+        }
         float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2);
         mKeyguardStatusBar.setAlpha(Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
                 * mKeyguardStatusBarAnimateAlpha);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index bd73a40..d68e2fa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -189,7 +189,7 @@
                 mNavigationBarView.getDownHitTarget() == HIT_TARGET_DEAD_ZONE;
         if (mOverviewEventSender.getProxy() == null || (!mNavigationBarView.isQuickScrubEnabled()
                 && !mNavigationBarView.isQuickStepSwipeUpEnabled())) {
-            return false;
+            return deadZoneConsumed;
         }
         mNavigationBarView.requestUnbufferedDispatch(event);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index fadc0ea..a38328a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -180,6 +180,15 @@
         mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
     }
 
+    private void applyExpandedFlag(State state) {
+        if (state.panelExpanded || state.isKeyguardShowingAndNotOccluded() || state.bouncerShowing
+                || ENABLE_REMOTE_INPUT && state.remoteInputActive) {
+            mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_BAR_EXPANDED;
+        } else {
+            mLpChanged.privateFlags &= ~LayoutParams.PRIVATE_FLAG_STATUS_BAR_EXPANDED;
+        }
+    }
+
     private void applyHeight(State state) {
         boolean expanded = isExpanded(state);
         if (state.forcePluginOpen) {
@@ -234,6 +243,7 @@
         applyKeyguardFlags(state);
         applyForceStatusBarVisibleFlag(state);
         applyFocusableFlag(state);
+        applyExpandedFlag(state);
         adjustScreenOrientation(state);
         applyHeight(state);
         applyUserActivityTimeout(state);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
index 639e50c..9c099f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
-import android.os.SystemProperties;
+import android.sysprop.VoldProperties;
 
 /**
  * Helper for determining whether the phone is decrypted yet.
@@ -26,7 +26,7 @@
     public static final boolean IS_DATA_ENCRYPTED = isDataEncrypted();
 
     private static boolean isDataEncrypted() {
-        String voldState = SystemProperties.get("vold.decrypt");
+        String voldState = VoldProperties.decrypt().orElse("");
         return "1".equals(voldState) || "trigger_restart_min_framework".equals(voldState);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index d6d0673..3c16329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -134,6 +134,10 @@
 
     @Override
     public void setHotspotEnabled(boolean enabled) {
+        if (mWaitingForCallback) {
+            if (DEBUG) Log.d(TAG, "Ignoring setHotspotEnabled; waiting for callback.");
+            return;
+        }
         if (enabled) {
             OnStartTetheringCallback callback = new OnStartTetheringCallback();
             mWaitingForCallback = true;
diff --git a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
index d7c4bbf..c97095e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java
@@ -21,11 +21,13 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.res.Resources.NotFoundException;
 import android.media.AudioManager;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.WindowManager;
 
+
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 
 abstract public class SafetyWarningDialog extends SystemUIDialog
@@ -40,12 +42,18 @@
 
     private long mShowTime;
     private boolean mNewVolumeUp;
+    private boolean mDisableOnVolumeUp;
 
     public SafetyWarningDialog(Context context, AudioManager audioManager) {
         super(context);
         mContext = context;
         mAudioManager = audioManager;
-
+        try {
+            mDisableOnVolumeUp = mContext.getResources().getBoolean(
+                  com.android.internal.R.bool.config_safe_media_disable_on_volume_up);
+        } catch (NotFoundException e) {
+            mDisableOnVolumeUp = true;
+        }
         getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
         setShowForAllUsers(true);
         setMessage(mContext.getString(com.android.internal.R.string.safe_media_volume_warning));
@@ -63,7 +71,8 @@
 
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && event.getRepeatCount() == 0) {
+        if (mDisableOnVolumeUp && keyCode == KeyEvent.KEYCODE_VOLUME_UP
+            && event.getRepeatCount() == 0) {
             mNewVolumeUp = true;
         }
         return super.onKeyDown(keyCode, event);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index f1bf31d..cc96917 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -21,6 +21,7 @@
 
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -34,8 +35,10 @@
 
 import android.app.Fragment;
 import android.content.res.Configuration;
+import android.os.Handler;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
 import android.view.Display;
 import android.view.View;
@@ -60,6 +63,7 @@
 @SmallTest
 public class ScreenDecorationsTest extends SysuiTestCase {
 
+    private TestableLooper mTestableLooper;
     private ScreenDecorations mScreenDecorations;
     private StatusBar mStatusBar;
     private WindowManager mWindowManager;
@@ -71,6 +75,10 @@
 
     @Before
     public void setup() {
+        mTestableLooper = TestableLooper.get(this);
+        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
+                new Handler(mTestableLooper.getLooper()));
+
         mStatusBar = mock(StatusBar.class);
         mWindowManager = mock(WindowManager.class);
         mView = spy(new StatusBarWindowView(mContext, null));
@@ -88,7 +96,31 @@
 
         mTunerService = mDependency.injectMockDependency(TunerService.class);
 
-        mScreenDecorations = new ScreenDecorations();
+
+        mScreenDecorations = new ScreenDecorations() {
+            @Override
+            public void start() {
+                super.start();
+                mTestableLooper.processAllMessages();
+            }
+
+            @Override
+            Handler startHandlerThread() {
+                return new Handler(mTestableLooper.getLooper());
+            }
+
+            @Override
+            protected void onConfigurationChanged(Configuration newConfig) {
+                super.onConfigurationChanged(newConfig);
+                mTestableLooper.processAllMessages();
+            }
+
+            @Override
+            public void onTuningChanged(String key, String newValue) {
+                super.onTuningChanged(key, newValue);
+                mTestableLooper.processAllMessages();
+            }
+        };
         mScreenDecorations.mContext = mContext;
         mScreenDecorations.mComponents = mContext.getComponents();
 
@@ -195,4 +227,17 @@
         verify(padding).destroy();
     }
 
+    @Test
+    public void testUpdateRoundedCorners() {
+        mContext.getOrCreateTestableResources().addOverride(
+                com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false);
+        mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20);
+
+        mScreenDecorations.start();
+        assertEquals(mScreenDecorations.mRoundedDefault, 20);
+
+        mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 5);
+        mScreenDecorations.onConfigurationChanged(null);
+        assertEquals(mScreenDecorations.mRoundedDefault, 5);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index 5ecf0c0..a9d49f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -323,9 +323,9 @@
     }
 
     @Test
-    public void testShouldDismissLowBatteryWarning_dismissWhenPowerSaverEnabled() {
+    public void testShouldDismissLowBatteryWarning_dismissWhenPowerSaverEnabledLegacy() {
         mPowerUI.start();
-        when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
+        when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(false);
         when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
         when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
 
@@ -337,6 +337,20 @@
     }
 
     @Test
+    public void testShouldNotDismissLowBatteryWarning_dismissWhenPowerSaverEnabledHybrid() {
+        mPowerUI.start();
+        when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
+        when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
+        when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
+
+        // device that gets power saver turned on should dismiss
+        boolean shouldDismiss =
+            mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
+                BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, !POWER_SAVER_OFF);
+        assertFalse(shouldDismiss);
+    }
+
+    @Test
     public void testShouldDismissLowBatteryWarning_dismissWhenPlugged() {
         mPowerUI.start();
         when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml
index 754ba72..b08924b 100644
--- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml
@@ -16,7 +16,7 @@
   -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <string name="display_cutout_emulation_overlay">Corner display cutout</string>
+    <string name="display_cutout_emulation_overlay">Corner cutout</string>
 
 </resources>
 
diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml
index 68c2dcb..0a106fa 100644
--- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml
@@ -16,7 +16,7 @@
   -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <string name="display_cutout_emulation_overlay">Double display cutout</string>
+    <string name="display_cutout_emulation_overlay">Double cutout</string>
 
 </resources>
 
diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml
index 4989677..0bf8330 100644
--- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml
@@ -18,7 +18,7 @@
 -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <string name="display_cutout_emulation_overlay">Narrow display cutout</string>
+    <string name="display_cutout_emulation_overlay">Narrow cutout</string>
 
 </resources>
 
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml
index 6dcbbd9..bcc7c97 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml
@@ -16,7 +16,7 @@
   -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <string name="display_cutout_emulation_overlay">Tall display cutout</string>
+    <string name="display_cutout_emulation_overlay">Tall cutout</string>
 
 </resources>
 
diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml
index f4b9f7e..0fcbdebb 100644
--- a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml
@@ -16,7 +16,7 @@
   -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-    <string name="display_cutout_emulation_overlay">Wide display cutout</string>
+    <string name="display_cutout_emulation_overlay">Wide cutout</string>
 
 </resources>
 
diff --git a/proto/src/gnss.proto b/proto/src/gnss.proto
index 0168392..1509fc0 100644
--- a/proto/src/gnss.proto
+++ b/proto/src/gnss.proto
@@ -45,6 +45,9 @@
 
   // Power metrics
   optional PowerMetrics power_metrics = 12;
+
+  // Hardware revision (EVT, DVT, PVT etc.)
+  optional string hardware_revision = 13;
 }
 
 // Power metrics
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 03ab60c..b990175 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -941,9 +941,10 @@
     // OS: 6.0
     NOTIFICATION_ZEN_MODE_EVENT_RULE = 146;
 
-    // ACTION: App notification settings > Block Notifications
+    // ACTION: App notification settings > Block Notifications or long press on
+    // notification blocks.
     // CATEGORY: SETTINGS
-    // OS: 6.0
+    // OS: 9.0
     ACTION_BAN_APP_NOTES = 147;
 
     // ACTION: Notification shade > Dismiss all button
@@ -6129,6 +6130,305 @@
     // CATEGORY: NOTIFICATION
     NOTIFICATION_INTERRUPTION = 1501;
 
+    // OPEN: Settings
+    // CATEGORY: SETTINGS
+    // OS: Q
+    SETTINGS_HOMEPAGE = 1502;
+
+    // OPEN: Settings > Create shortcut(widget)
+    // CATEGORY: SETTINGS
+    // OS: Q
+    SETTINGS_CREATE_SHORTCUT = 1503;
+
+    // ACTION: Authenticate using fingerprint
+    // CATEGORY: SETTINGS
+    // OS: Q
+    ACTION_FACE_AUTH = 1504;
+
+    // ACTION: Add fingerprint > Enroll fingerprint
+    // CATEGORY: SETTINGS
+    // OS: Q
+    ACTION_FACE_ENROLL = 1505;
+
+    // OPEN: Face Enroll introduction
+    // CATEGORY: SETTINGS
+    // OS: Q
+    FACE_ENROLL_INTRO = 1506;
+
+    // OPEN: Face Enroll introduction
+    // CATEGORY: SETTINGS
+    // OS: Q
+    FACE_ENROLL_ENROLLING = 1507;
+
+    // OPEN: Face Enroll introduction
+    // CATEGORY: SETTINGS
+    // OS: Q
+    FACE_ENROLL_FINISHED = 1508;
+
+    // OPEN: Face Enroll sidecar
+    // CATEGORY: SETTINGS
+    // OS: Q
+    FACE_ENROLL_SIDECAR = 1509;
+
+    // OPEN: Settings > Add face > Error dialog
+    // OS: Q
+    DIALOG_FACE_ERROR = 1510;
+
+    // OPEN: Settings > Security > Face
+    // CATEGORY: SETTINGS
+    // OS: Q
+    FACE = 1511;
+
+    // OPEN: Settings > Acessibility > HearingAid pairing instructions dialog
+    // CATEGORY: SETTINGS
+    // OS: Q
+    DIALOG_ACCESSIBILITY_HEARINGAID = 1512;
+
+    // ACTION: Activity start
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    ACTION_ACTIVITY_START = 1513;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Calling UID
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_CALLING_UID = 1514;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Calling package name
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_CALLING_PACKAGE_NAME = 1515;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Calling UID proc state
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_CALLING_UID_PROC_STATE = 1516;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Calling UID has any visible window
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW = 1517;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Real calling UID
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_REAL_CALLING_UID = 1518;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Real calling UID proc state
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_REAL_CALLING_UID_PROC_STATE = 1519;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Real calling UID has any visible window
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW = 1520;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Target UID
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_TARGET_UID = 1521;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Target UID package name
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_TARGET_PACKAGE_NAME = 1522;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Target UID proc state
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_TARGET_UID_PROC_STATE = 1523;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Target UID has any visible window
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW = 1524;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Target doze whitelist tag
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_TARGET_WHITELIST_TAG = 1525;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Target short component name
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_TARGET_SHORT_COMPONENT_NAME = 1526;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Coming from pending intent
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_COMING_FROM_PENDING_INTENT = 1527;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Intent action
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_INTENT_ACTION = 1528;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Caller app process record process name
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_PROCESS_NAME = 1529;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Caller app process record current proc state
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_CUR_PROC_STATE = 1530;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Caller app process record has client activities
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES = 1531;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Caller app process record has foreground services
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES = 1532;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Caller app process record has foreground activities
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES = 1533;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Caller app process record has top UI
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_HAS_TOP_UI = 1534;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Caller app process record has overlay UI
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_HAS_OVERLAY_UI = 1535;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Caller app process record pending UI clean
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_PENDING_UI_CLEAN = 1536;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Millis since caller app's process record last interaction event
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT = 1537;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Millis since caller app's process record fg interaction
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION = 1538;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Millis since caller app's process record last became unimportant
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT = 1539;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record launch mode
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_LAUNCH_MODE = 1540;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record target activity
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY = 1541;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record flags
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_FLAGS = 1542;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record real activity
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_REAL_ACTIVITY = 1543;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record short component name
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME = 1544;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record process name
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_PROCESS_NAME = 1545;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record is fullscreen
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_IS_FULLSCREEN = 1546;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record is no display
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY = 1547;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Millis since activity was last visible
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE = 1548;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record's resultTo packageName
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME = 1549;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record's resultTo shortComponentName
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME = 1550;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record is visible
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_IS_VISIBLE = 1551;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Activity record is visible ignoring keyguard
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD = 1552;
+
+    // Tagged data for ACTION_ACTIVITY_START.
+    // FIELD: Millis since activity's last launch
+    // CATEGORY: OTHER
+    // OS: Q (will also ship in PQ1A)
+    FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH = 1553;
+
     // OPEN: Emergency dialer opened
     // CLOSE: Emergency dialer closed
     //  SUBTYPE: The entry type that user opened emergency dialer
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 72f11e0..b29c992 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -457,6 +457,11 @@
   // Identifier for experimental scoring parameter settings.
   optional string score_experiment_id = 117;
 
+  // Histogram of the EAP method type of all installed Passpoint profiles
+  repeated PasspointProfileTypeCount installed_passpoint_profile_type = 123;
+
+  // Hardware revision (EVT, DVT, PVT etc.)
+  optional string hardware_revision = 124;
 }
 
 // Information that gets logged for every WiFi connection.
@@ -1503,3 +1508,31 @@
     optional int32 count = 2;
   }
 }
+
+message PasspointProfileTypeCount {
+  enum EapMethod {
+    // Unknown Type
+    TYPE_UNKNOWN = 0;
+
+    // EAP_TLS (13)
+    TYPE_EAP_TLS = 1;
+
+    // EAP_TTLS (21)
+    TYPE_EAP_TTLS = 2;
+
+    // EAP_SIM (18)
+    TYPE_EAP_SIM = 3;
+
+    // EAP_AKA (23)
+    TYPE_EAP_AKA = 4;
+
+    // EAP_AKA_PRIME (50)
+    TYPE_EAP_AKA_PRIME = 5;
+  }
+
+  // Eap method type set in Passpoint profile
+  optional EapMethod eap_method_type = 1;
+
+  // Num of installed Passpoint profile with same eap method
+  optional int32 count = 2;
+}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
index c9c7adc..f69b638 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java
@@ -48,11 +48,6 @@
     }
 
     @Override
-    public void onUnlockUser(int userHandle) {
-        FgThread.getHandler().post(() -> mImpl.onUserUnlocked(userHandle));
-    }
-
-    @Override
     public void onStopUser(int userHandle) {
         mImpl.onUserStopped(userHandle);
     }
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index db8ad12..b71d7a7 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -19,7 +19,6 @@
 import static android.content.Context.KEYGUARD_SERVICE;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
 
 import android.annotation.UserIdInt;
@@ -2697,7 +2696,12 @@
         }
     }
 
-    void onUserUnlocked(int userId) {
+    /**
+     * This does not use the usual onUserUnlocked() listener mechanism because it is
+     * invoked at a choreographed point in the middle of the user unlock sequence,
+     * before the boot-completed broadcast is issued and the listeners notified.
+     */
+    void handleUserUnlocked(int userId) {
         if (isProfileWithLockedParent(userId)) {
             return;
         }
@@ -2734,7 +2738,7 @@
                 }
             }
         }
-        Slog.i(TAG, "Async processing of onUserUnlocked u" + userId + " took "
+        Slog.i(TAG, "Processing of handleUserUnlocked u" + userId + " took "
                 + (SystemClock.elapsedRealtime() - time) + " ms");
     }
 
@@ -4801,5 +4805,11 @@
                 return widgetPackages;
             }
         }
+
+        @Override
+        public void unlockUser(int userId) {
+            handleUserUnlocked(userId);
+        }
+
     }
 }
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index dc84498..5882303 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -81,6 +81,13 @@
         void onDestroy();
     }
 
+    /**
+     * Wrapper that guarantees that only one callback is triggered by ignoring further calls after
+     * it's destroyed.
+     *
+     * <p>It's needed becase {@link #onCancel(IntentSender)} is always called when the Save UI
+     * dialog is dismissed.
+     */
     private class OneTimeListener implements OnSaveListener {
 
         private final OnSaveListener mRealListener;
@@ -96,7 +103,6 @@
             if (mDone) {
                 return;
             }
-            mDone = true;
             mRealListener.onSave();
         }
 
@@ -106,7 +112,6 @@
             if (mDone) {
                 return;
             }
-            mDone = true;
             mRealListener.onCancel(listener);
         }
 
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 43469ff..9b8f51e 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -6,7 +6,6 @@
             "frameworks/native/aidl/binder",
             "frameworks/native/cmds/dumpstate/binder",
             "system/core/storaged/binder",
-            "system/netd/server/binder",
             "system/vold/binder",
         ],
     },
@@ -19,7 +18,6 @@
         ":mediaupdateservice_aidl",
         "java/com/android/server/EventLogTags.logtags",
         "java/com/android/server/am/EventLogTags.logtags",
-        ":netd_metrics_aidl",
     ],
 
     libs: [
@@ -49,6 +47,7 @@
         "android.hardware.contexthub-V1.0-java",
         "android.hidl.manager-V1.0-java",
         "netd_aidl_interface-java",
+        "netd_event_listener_interface-java",
     ],
 }
 
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 5c14459..50f15ca0 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -624,7 +624,7 @@
             // them will get the new sequence number at that point.  (See for example how testing
             // of JobScheduler's BatteryController works.)
             sendBatteryChangedIntentLocked();
-            if (mLastBatteryLevel != mHealthInfo.batteryLevel) {
+            if (mLastBatteryLevel != mHealthInfo.batteryLevel || mLastPlugType != mPlugType) {
                 sendBatteryLevelChangedIntentLocked();
             }
 
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 49de4b1..555e899 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -76,6 +76,7 @@
 import java.util.LinkedList;
 import java.util.Locale;
 import java.util.Map;
+import java.util.NoSuchElementException;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -1279,7 +1280,11 @@
             if (mService == null) {
                 return;
             }
-            mService.unlinkToDeath(this, 0);
+            try {
+                mService.unlinkToDeath(this, 0);
+            } catch (NoSuchElementException e) {
+                Log.e(TAG, "error unlinking to death", e);
+            }
             mService = null;
             mClassName = null;
 
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 14503f9..66ceae4 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -902,6 +902,7 @@
         // Listen to package add and removal events for all users.
         intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
+        intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
         intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         intentFilter.addDataScheme("package");
         mContext.registerReceiverAsUser(
@@ -1967,6 +1968,7 @@
     void systemReady() {
         mProxyTracker.loadGlobalProxy();
         registerNetdEventCallback();
+        mTethering.systemReady();
 
         synchronized (this) {
             mSystemReady = true;
@@ -4203,12 +4205,46 @@
         mPermissionMonitor.onPackageAdded(packageName, uid);
     }
 
-    private void onPackageRemoved(String packageName, int uid) {
+    private void onPackageReplaced(String packageName, int uid) {
+        if (TextUtils.isEmpty(packageName) || uid < 0) {
+            Slog.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid);
+            return;
+        }
+        final int userId = UserHandle.getUserId(uid);
+        synchronized (mVpns) {
+            final Vpn vpn = mVpns.get(userId);
+            if (vpn == null) {
+                return;
+            }
+            // Legacy always-on VPN won't be affected since the package name is not set.
+            if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName)) {
+                Slog.d(TAG, "Restarting always-on VPN package " + packageName + " for user "
+                        + userId);
+                vpn.startAlwaysOnVpn();
+            }
+        }
+    }
+
+    private void onPackageRemoved(String packageName, int uid, boolean isReplacing) {
         if (TextUtils.isEmpty(packageName) || uid < 0) {
             Slog.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid);
             return;
         }
         mPermissionMonitor.onPackageRemoved(uid);
+
+        final int userId = UserHandle.getUserId(uid);
+        synchronized (mVpns) {
+            final Vpn vpn = mVpns.get(userId);
+            if (vpn == null) {
+                return;
+            }
+            // Legacy always-on VPN won't be affected since the package name is not set.
+            if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName) && !isReplacing) {
+                Slog.d(TAG, "Removing always-on VPN package " + packageName + " for user "
+                        + userId);
+                vpn.setAlwaysOnPackage(null, false);
+            }
+        }
     }
 
     private void onUserUnlocked(int userId) {
@@ -4245,8 +4281,12 @@
                 onUserUnlocked(userId);
             } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
                 onPackageAdded(packageName, uid);
+            } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
+                onPackageReplaced(packageName, uid);
             } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) {
-                onPackageRemoved(packageName, uid);
+                final boolean isReplacing = intent.getBooleanExtra(
+                        Intent.EXTRA_REPLACING, false);
+                onPackageRemoved(packageName, uid, isReplacing);
             }
         }
     };
@@ -5674,7 +5714,6 @@
                 // This should never fail.  Specifying an already in use NetID will cause failure.
                 if (networkAgent.isVPN()) {
                     mNMS.createVirtualNetwork(networkAgent.network.netId,
-                            !networkAgent.linkProperties.getDnsServers().isEmpty(),
                             (networkAgent.networkMisc == null ||
                                 !networkAgent.networkMisc.allowBypass));
                 } else {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index fc1e1f0..00b1320 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -163,8 +163,6 @@
 
     private static final int MAX_UID_RANGES_PER_COMMAND = 10;
 
-    private static final  String[] EMPTY_STRING_ARRAY = new String[0];
-
     /**
      * Name representing {@link #setGlobalAlert(long)} limit when delivered to
      * {@link INetworkManagementEventObserver#limitReached(String, String)}.
@@ -951,23 +949,10 @@
     // INetworkManagementService members
     //
     @Override
-    public INetd getNetdService() throws RemoteException {
-        final CountDownLatch connectedSignal = mConnectedSignal;
-        if (connectedSignal != null) {
-            try {
-                connectedSignal.await();
-            } catch (InterruptedException ignored) {}
-        }
-
-        return mNetdService;
-    }
-
-    @Override
     public String[] listInterfaces() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            final List<String> result = mNetdService.interfaceGetList();
-            return result.toArray(EMPTY_STRING_ARRAY);
+            return mNetdService.interfaceGetList();
         } catch (RemoteException | ServiceSpecificException e) {
             throw new IllegalStateException(e);
         }
@@ -1259,8 +1244,7 @@
     public String[] listTetheredInterfaces() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            final List<String> result = mNetdService.tetherInterfaceList();
-            return result.toArray(EMPTY_STRING_ARRAY);
+            return mNetdService.tetherInterfaceList();
         } catch (RemoteException | ServiceSpecificException e) {
             throw new IllegalStateException(e);
         }
@@ -1283,8 +1267,7 @@
     public String[] getDnsForwarders() {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            final List<String> result = mNetdService.tetherDnsList();
-            return result.toArray(EMPTY_STRING_ARRAY);
+            return mNetdService.tetherDnsList();
         } catch (RemoteException | ServiceSpecificException e) {
             throw new IllegalStateException(e);
         }
@@ -2325,11 +2308,11 @@
     }
 
     @Override
-    public void createVirtualNetwork(int netId, boolean hasDNS, boolean secure) {
+    public void createVirtualNetwork(int netId, boolean secure) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mNetdService.networkCreateVpn(netId, hasDNS, secure);
+            mNetdService.networkCreateVpn(netId, secure);
         } catch (RemoteException | ServiceSpecificException e) {
             throw new IllegalStateException(e);
         }
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index f5b29e9..0deaee7 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -43,6 +43,7 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.MediaStore;
 import android.provider.Settings;
 import android.system.ErrnoException;
@@ -69,6 +70,7 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.List;
 import java.util.ArrayList;
 
 import java.util.zip.ZipFile;
@@ -103,6 +105,7 @@
     private final Context mContext;
     private final ActivityManagerInternal mAmInternal;
     private final IActivityManager mAm;
+    private final UserManager mUserManager;
 
     /** The list of the statically pinned files. */
     @GuardedBy("this")
@@ -164,6 +167,8 @@
         mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
         mAm = ActivityManager.getService();
 
+        mUserManager = mContext.getSystemService(UserManager.class);
+
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
         filter.addDataScheme("package");
@@ -194,12 +199,16 @@
      */
     @Override
     public void onSwitchUser(int userHandle) {
-        sendPinAppsMessage(userHandle);
+        if (!mUserManager.isManagedProfile(userHandle)) {
+            sendPinAppsMessage(userHandle);
+        }
     }
 
     @Override
     public void onUnlockUser(int userHandle) {
-        sendPinAppsMessage(userHandle);
+        if (!mUserManager.isManagedProfile(userHandle)) {
+            sendPinAppsMessage(userHandle);
+        }
     }
 
     /**
@@ -345,31 +354,76 @@
     }
 
     private ApplicationInfo getCameraInfo(int userHandle) {
-        //  find the camera via an intent
-        //  use INTENT_ACTION_STILL_IMAGE_CAMERA instead of _SECURE.  On a
-        //  device without a fbe enabled, the _SECURE intent will never get set.
         Intent cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
-        return getApplicationInfoForIntent(cameraIntent, userHandle);
+        ApplicationInfo info = getApplicationInfoForIntent(cameraIntent, userHandle,
+            false /* defaultToSystemApp */);
+
+        // If the STILL_IMAGE_CAMERA intent doesn't resolve, try the _SECURE intent.
+        // We don't use _SECURE first because it will never get set on a device
+        // without File-based Encryption. But if the user has only set the intent
+        // before unlocking their device, we may still be able to identify their
+        // preference using this intent.
+        if (info == null) {
+            cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE);
+            info = getApplicationInfoForIntent(cameraIntent, userHandle,
+                false /* defaultToSystemApp */);
+        }
+
+        // If the _SECURE intent doesn't resolve, try the original intent but request
+        // the system app for camera if there was more than one result.
+        if (info == null) {
+            cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+            info = getApplicationInfoForIntent(cameraIntent, userHandle,
+                true /* defaultToSystemApp */);
+        }
+        return info;
     }
 
     private ApplicationInfo getHomeInfo(int userHandle) {
         Intent intent = mAmInternal.getHomeIntent();
-        return getApplicationInfoForIntent(intent, userHandle);
+        return getApplicationInfoForIntent(intent, userHandle, false);
     }
 
-    private ApplicationInfo getApplicationInfoForIntent(Intent intent, int userHandle) {
+    private ApplicationInfo getApplicationInfoForIntent(Intent intent, int userHandle,
+            boolean defaultToSystemApp) {
         if (intent == null) {
             return null;
         }
-        ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser(intent,
+
+        ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivityAsUser(intent,
                 MATCH_FLAGS, userHandle);
-        if (info == null) {
+
+        // If this intent can resolve to only one app, choose that one.
+        // Otherwise, if we've requested to default to the system app, return it;
+        // if we have not requested that default, return null if there's more than one option.
+        // If there's more than one system app, return null since we don't know which to pick.
+        if (resolveInfo == null) {
             return null;
         }
-        if (isResolverActivity(info.activityInfo)) {
-            return null;
+
+        if (!isResolverActivity(resolveInfo.activityInfo)) {
+            return resolveInfo.activityInfo.applicationInfo;
         }
-        return info.activityInfo.applicationInfo;
+
+        if (defaultToSystemApp) {
+            List<ResolveInfo> infoList = mContext.getPackageManager()
+                .queryIntentActivitiesAsUser(intent, MATCH_FLAGS, userHandle);
+            ApplicationInfo systemAppInfo = null;
+            for (ResolveInfo info : infoList) {
+                if ((info.activityInfo.applicationInfo.flags
+                      & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                    if (systemAppInfo == null) {
+                        systemAppInfo = info.activityInfo.applicationInfo;
+                    } else {
+                        // If there's more than one system app, return null due to ambiguity.
+                        return null;
+                    }
+                }
+            }
+            return systemAppInfo;
+        }
+
+        return null;
     }
 
     private void sendPinAppsMessage(int userHandle) {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index a3e6ea2..371e517 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -99,6 +99,7 @@
 import android.os.storage.VolumeRecord;
 import android.provider.MediaStore;
 import android.provider.Settings;
+import android.sysprop.VoldProperties;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
@@ -973,7 +974,7 @@
 
         // On an encrypted device we can't see system properties yet, so pull
         // the system locale out of the mount service.
-        if ("".equals(SystemProperties.get("vold.encrypt_progress"))) {
+        if ("".equals(VoldProperties.encrypt_progress().orElse(""))) {
             copyLocaleFromMountService();
         }
     }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 66ae47c..7b29fe5 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -210,6 +210,10 @@
 
     private PreciseCallState mPreciseCallState = new PreciseCallState();
 
+    private int mCallDisconnectCause = DisconnectCause.NOT_VALID;
+
+    private int mCallPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
+
     private boolean mCarrierNetworkChangeState = false;
 
     private PhoneCapability mPhoneCapability = null;
@@ -708,6 +712,14 @@
                             remove(r.binder);
                         }
                     }
+                    if ((events & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
+                        try {
+                            r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause,
+                                    mCallPreciseDisconnectCause);
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
                     if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
                         try {
                             r.callback.onPreciseDataConnectionStateChanged(
@@ -1478,9 +1490,8 @@
             }
             handleRemoveListLocked();
         }
-        broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState,
-                DisconnectCause.NOT_VALID,
-                PreciseDisconnectCause.NOT_VALID);
+        broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState,
+                backgroundCallState);
     }
 
     public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) {
@@ -1488,12 +1499,14 @@
             return;
         }
         synchronized (mRecords) {
-            mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState,
-                    mBackgroundCallState, disconnectCause, preciseDisconnectCause);
+            mCallDisconnectCause = disconnectCause;
+            mCallPreciseDisconnectCause = preciseDisconnectCause;
             for (Record r : mRecords) {
-                if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) {
+                if (r.matchPhoneStateListenerEvent(PhoneStateListener
+                        .LISTEN_CALL_DISCONNECT_CAUSES)) {
                     try {
-                        r.callback.onPreciseCallStateChanged(mPreciseCallState);
+                        r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause,
+                                mCallPreciseDisconnectCause);
                     } catch (RemoteException ex) {
                         mRemoveList.add(r.binder);
                     }
@@ -1501,8 +1514,6 @@
             }
             handleRemoveListLocked();
         }
-        broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState,
-                mBackgroundCallState, disconnectCause, preciseDisconnectCause);
     }
 
     public void notifyPreciseDataConnectionFailed(String reason, String apnType,
@@ -1703,6 +1714,8 @@
             }
             pw.println("mPreciseDataConnectionState=" + mPreciseDataConnectionState);
             pw.println("mPreciseCallState=" + mPreciseCallState);
+            pw.println("mCallDisconnectCause=" + mCallDisconnectCause);
+            pw.println("mCallPreciseDisconnectCause=" + mCallPreciseDisconnectCause);
             pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState);
             pw.println("mRingingCallState=" + mRingingCallState);
             pw.println("mForegroundCallState=" + mForegroundCallState);
@@ -1877,13 +1890,11 @@
     }
 
     private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState,
-            int backgroundCallState, int disconnectCause, int preciseDisconnectCause) {
+            int backgroundCallState) {
         Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED);
         intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState);
         intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState);
         intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState);
-        intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause);
-        intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause);
         mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
                 android.Manifest.permission.READ_PRECISE_PHONE_STATE);
     }
@@ -1964,6 +1975,11 @@
         }
 
 
+        if ((events & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
+        }
+
         return true;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 6550d06..d14c1a1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -67,6 +67,7 @@
     static final String KEY_BOUND_SERVICE_CRASH_RESTART_DURATION = "service_crash_restart_duration";
     static final String KEY_BOUND_SERVICE_CRASH_MAX_RETRY = "service_crash_max_retry";
     static final String KEY_PROCESS_START_ASYNC = "process_start_async";
+    static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration";
 
     private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
     private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000;
@@ -95,7 +96,7 @@
     private static final long DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION = 30*60_000;
     private static final int DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY = 16;
     private static final boolean DEFAULT_PROCESS_START_ASYNC = true;
-
+    private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000;
 
     // Maximum number of cached processes we will allow.
     public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
@@ -207,6 +208,14 @@
     // Indicates if the processes need to be started asynchronously.
     public boolean FLAG_PROCESS_START_ASYNC = DEFAULT_PROCESS_START_ASYNC;
 
+    // Allow app just moving from TOP to FOREGROUND_SERVICE to stay in a higher adj value for
+    // this long.
+    public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION;
+
+    // Indicates whether the activity starts logging is enabled.
+    // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
+    boolean mFlagActivityStartsLoggingEnabled;
+
     private final ActivityManagerService mService;
     private ContentResolver mResolver;
     private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -235,6 +244,12 @@
     // memory trimming.
     public int CUR_TRIM_CACHED_PROCESSES;
 
+    private static final Uri ACTIVITY_MANAGER_CONSTANTS_URI = Settings.Global.getUriFor(
+                Settings.Global.ACTIVITY_MANAGER_CONSTANTS);
+
+    private static final Uri ACTIVITY_STARTS_LOGGING_ENABLED_URI = Settings.Global.getUriFor(
+                Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED);
+
     public ActivityManagerConstants(ActivityManagerService service, Handler handler) {
         super(handler);
         mService = service;
@@ -243,9 +258,10 @@
 
     public void start(ContentResolver resolver) {
         mResolver = resolver;
-        mResolver.registerContentObserver(Settings.Global.getUriFor(
-                Settings.Global.ACTIVITY_MANAGER_CONSTANTS), false, this);
+        mResolver.registerContentObserver(ACTIVITY_MANAGER_CONSTANTS_URI, false, this);
+        mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this);
         updateConstants();
+        updateActivityStartsLoggingEnabled();
     }
 
     public void setOverrideMaxCachedProcesses(int value) {
@@ -263,7 +279,12 @@
 
     @Override
     public void onChange(boolean selfChange, Uri uri) {
-        updateConstants();
+        if (uri == null) return;
+        if (ACTIVITY_MANAGER_CONSTANTS_URI.equals(uri)) {
+            updateConstants();
+        } else if (ACTIVITY_STARTS_LOGGING_ENABLED_URI.equals(uri)) {
+            updateActivityStartsLoggingEnabled();
+        }
     }
 
     private void updateConstants() {
@@ -332,11 +353,18 @@
                 DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY);
             FLAG_PROCESS_START_ASYNC = mParser.getBoolean(KEY_PROCESS_START_ASYNC,
                     DEFAULT_PROCESS_START_ASYNC);
+            TOP_TO_FGS_GRACE_DURATION = mParser.getDurationMillis(KEY_TOP_TO_FGS_GRACE_DURATION,
+                    DEFAULT_TOP_TO_FGS_GRACE_DURATION);
 
             updateMaxCachedProcesses();
         }
     }
 
+    private void updateActivityStartsLoggingEnabled() {
+        mFlagActivityStartsLoggingEnabled = Settings.Global.getInt(mResolver,
+                Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 0) == 1;
+    }
+
     private void updateMaxCachedProcesses() {
         CUR_MAX_CACHED_PROCESSES = mOverrideMaxCachedProcesses < 0
                 ? MAX_CACHED_PROCESSES : mOverrideMaxCachedProcesses;
@@ -402,6 +430,8 @@
         pw.println(MAX_SERVICE_INACTIVITY);
         pw.print("  "); pw.print(KEY_BG_START_TIMEOUT); pw.print("=");
         pw.println(BG_START_TIMEOUT);
+        pw.print("  "); pw.print(KEY_TOP_TO_FGS_GRACE_DURATION); pw.print("=");
+        pw.println(TOP_TO_FGS_GRACE_DURATION);
 
         pw.println();
         if (mOverrideMaxCachedProcesses >= 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index a411af2..514c9f6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -364,6 +364,7 @@
 import android.provider.Settings;
 import android.service.voice.IVoiceInteractionSession;
 import android.service.voice.VoiceInteractionManagerInternal;
+import android.sysprop.VoldProperties;
 import android.telecom.TelecomManager;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
@@ -5578,7 +5579,7 @@
         // TODO: Switch to user app stacks here.
         int ret = mActivityStartController.startActivities(caller, -1, callingPackage,
                 intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId,
-                reason);
+                reason, null /* originatingPendingIntent */);
         return ret;
     }
 
@@ -7958,8 +7959,8 @@
             SystemProperties.set("sys.boot_completed", "1");
 
             // And trigger dev.bootcomplete if we are not showing encryption progress
-            if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
-                    || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
+            if (!"trigger_restart_min_framework".equals(VoldProperties.decrypt().orElse(""))
+                    || "".equals(VoldProperties.encrypt_progress().orElse(""))){
                 SystemProperties.set("dev.bootcomplete", "1");
             }
             mUserController.sendBootCompleted(
@@ -10935,6 +10936,20 @@
         }
     }
 
+    /**
+     * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
+     * the whitelist
+     */
+    String getPendingTempWhitelistTagForUidLocked(int uid) {
+        final PendingTempWhitelist ptw = mPendingTempWhitelist.get(uid);
+        return ptw != null ? ptw.tag : null;
+    }
+
+    @VisibleForTesting
+    boolean isActivityStartsLoggingEnabled() {
+        return mConstants.mFlagActivityStartsLoggingEnabled;
+    }
+
     @Override
     public void moveStackToDisplay(int stackId, int displayId) {
         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
@@ -13646,7 +13661,7 @@
         String extraOptions = null;
         switch (bugreportType) {
             case ActivityManager.BUGREPORT_OPTION_FULL:
-                // Default options.
+                extraOptions = "bugreportfull";
                 break;
             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
                 extraOptions = "bugreportplus";
@@ -23244,6 +23259,19 @@
             }
         }
 
+        // If the app was recently in the foreground and moved to a foreground service status,
+        // allow it to get a higher rank in memory for some time, compared to other foreground
+        // services so that it can finish performing any persistence/processing of in-memory state.
+        if (app.foregroundServices && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ
+                && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now
+                    || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) {
+            adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ;
+            app.adjType = "fg-service-act";
+            if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
+                reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app);
+            }
+        }
+
         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
             if (app.forcingToImportant != null) {
@@ -23508,6 +23536,10 @@
                                         schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
                                         procState = ActivityManager.PROCESS_STATE_PERSISTENT;
                                     }
+                                } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0
+                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
+                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ + 1) {
+                                    newAdj = ProcessList.PERCEPTIBLE_APP_ADJ + 1;
                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
@@ -24478,6 +24510,8 @@
             // Must be called before updating setProcState
             maybeUpdateUsageStatsLocked(app, nowElapsed);
 
+            maybeUpdateLastTopTime(app, now);
+
             app.setProcState = app.curProcState;
             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
                 app.notCachedSinceIdle = false;
@@ -24702,6 +24736,13 @@
         }
     }
 
+    private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) {
+        if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP
+                && app.curProcState > ActivityManager.PROCESS_STATE_TOP) {
+            app.lastTopTime = nowUptime;
+        }
+    }
+
     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
         if (proc.thread != null) {
             if (proc.baseProcessTracker != null) {
@@ -26399,7 +26440,7 @@
                         packageUid, packageName,
                         intents, resolvedTypes, null /* resultTo */,
                         SafeActivityOptions.fromBundle(bOptions), userId,
-                        false /* validateIncomingUser */);
+                        false /* validateIncomingUser */, null /* originatingPendingIntent */);
             }
         }
 
@@ -26738,6 +26779,18 @@
                 return ActivityManagerService.this.getHomeIntent();
             }
         }
+
+        @Override
+        public void notifyDefaultDisplaySizeChanged() {
+            synchronized (ActivityManagerService.this) {
+                if (mSystemServiceManager.isBootCompleted() && mHomeProcess != null) {
+
+                    // TODO: Ugly hack to unblock the release
+                    Slog.i(TAG, "Killing home process because of display size change");
+                    removeProcessLocked(mHomeProcess, false, true, "kill home screen size");
+                }
+            }
+        }
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 7fb161c..843699c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2849,6 +2849,7 @@
             pw.println("  --checkin: output checkin format, resetting data.");
             pw.println("  --C: output checkin format, not resetting data.");
             pw.println("  --proto: output dump in protocol buffer format.");
+            pw.println("  --autofill: dump just the autofill-related state of an activity");
         } else {
             pw.println("Activity manager (activity) commands:");
             pw.println("  help");
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 47d0423..9ffa662 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -2,6 +2,7 @@
 
 import static android.app.ActivityManager.START_SUCCESS;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.ActivityManager.processStateAmToProto;
 import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -9,6 +10,7 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_ACTIVITY_START;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_BIND_APPLICATION_DELAY_MS;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME;
@@ -21,8 +23,48 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_REPORTED_DRAWN_MS;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_FLAGS;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_FULLSCREEN;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_LAUNCH_MODE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_PROCESS_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_REAL_ACTIVITY;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_PACKAGE_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_PROC_STATE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CLASS_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_COMING_FROM_PENDING_INTENT;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_LAUNCH_TOKEN;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INTENT_ACTION;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_CUR_PROC_STATE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_OVERLAY_UI;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_TOP_UI;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PENDING_UI_CLEAN;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PROCESS_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_PROC_STATE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_PACKAGE_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_SHORT_COMPONENT_NAME;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_PROC_STATE;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_WHITELIST_TAG;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_REASON;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_FILTER;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH;
@@ -37,6 +79,7 @@
 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
 
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.dex.ArtManagerInternal;
 import android.content.pm.dex.PackageOptimizationInfo;
@@ -622,6 +665,95 @@
                 startupTimeMs);
     }
 
+    void logActivityStart(Intent intent, ProcessRecord callerApp, ActivityRecord r,
+            int callingUid, String callingPackage, int callingUidProcState,
+            boolean callingUidHasAnyVisibleWindow,
+            int realCallingUid, int realCallingUidProcState,
+            boolean realCallingUidHasAnyVisibleWindow,
+            int targetUid, String targetPackage, int targetUidProcState,
+            boolean targetUidHasAnyVisibleWindow, String targetWhitelistTag,
+            boolean comingFromPendingIntent) {
+
+        final long nowElapsed = SystemClock.elapsedRealtime();
+        final long nowUptime = SystemClock.uptimeMillis();
+        final LogMaker builder = new LogMaker(ACTION_ACTIVITY_START);
+        builder.setTimestamp(System.currentTimeMillis());
+        builder.addTaggedData(FIELD_CALLING_UID, callingUid);
+        builder.addTaggedData(FIELD_CALLING_PACKAGE_NAME, callingPackage);
+        builder.addTaggedData(FIELD_CALLING_UID_PROC_STATE,
+                processStateAmToProto(callingUidProcState));
+        builder.addTaggedData(FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
+                callingUidHasAnyVisibleWindow ? 1 : 0);
+        builder.addTaggedData(FIELD_REAL_CALLING_UID, realCallingUid);
+        builder.addTaggedData(FIELD_REAL_CALLING_UID_PROC_STATE,
+                processStateAmToProto(realCallingUidProcState));
+        builder.addTaggedData(FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW,
+                realCallingUidHasAnyVisibleWindow ? 1 : 0);
+        builder.addTaggedData(FIELD_TARGET_UID, targetUid);
+        builder.addTaggedData(FIELD_TARGET_PACKAGE_NAME, targetPackage);
+        builder.addTaggedData(FIELD_TARGET_UID_PROC_STATE,
+                processStateAmToProto(targetUidProcState));
+        builder.addTaggedData(FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW,
+                targetUidHasAnyVisibleWindow ? 1 : 0);
+        builder.addTaggedData(FIELD_TARGET_WHITELIST_TAG, targetWhitelistTag);
+        builder.addTaggedData(FIELD_TARGET_SHORT_COMPONENT_NAME, r.shortComponentName);
+        builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0);
+        builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction());
+        if (callerApp != null) {
+            builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.processName);
+            builder.addTaggedData(FIELD_PROCESS_RECORD_CUR_PROC_STATE,
+                    processStateAmToProto(callerApp.curProcState));
+            builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES,
+                    callerApp.hasClientActivities ? 1 : 0);
+            builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES,
+                    callerApp.hasForegroundServices() ? 1 : 0);
+            builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES,
+                    callerApp.foregroundActivities ? 1 : 0);
+            builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi ? 1 : 0);
+            builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_OVERLAY_UI,
+                    callerApp.hasOverlayUi ? 1 : 0);
+            builder.addTaggedData(FIELD_PROCESS_RECORD_PENDING_UI_CLEAN,
+                    callerApp.pendingUiClean ? 1 : 0);
+            if (callerApp.interactionEventTime != 0) {
+                builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT,
+                        (nowElapsed - callerApp.interactionEventTime));
+            }
+            if (callerApp.fgInteractionTime != 0) {
+                builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION,
+                        (nowElapsed - callerApp.fgInteractionTime));
+            }
+            if (callerApp.whenUnimportant != 0) {
+                builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT,
+                        (nowUptime - callerApp.whenUnimportant));
+            }
+        }
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_LAUNCH_MODE, r.info.launchMode);
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY, r.info.targetActivity);
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_FLAGS, r.info.flags);
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_REAL_ACTIVITY, r.realActivity.toShortString());
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME, r.shortComponentName);
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_PROCESS_NAME, r.processName);
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_FULLSCREEN, r.fullscreen ? 1 : 0);
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY, r.noDisplay ? 1 : 0);
+        if (r.lastVisibleTime != 0) {
+            builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE,
+                    (nowUptime - r.lastVisibleTime));
+        }
+        if (r.resultTo != null) {
+            builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME, r.resultTo.packageName);
+            builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME,
+                    r.resultTo.shortComponentName);
+        }
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE, r.visible ? 1 : 0);
+        builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD,
+                r.visibleIgnoringKeyguard ? 1 : 0);
+        if (r.lastLaunchTime != 0) {
+            builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH,
+                    (nowUptime - r.lastLaunchTime));
+        }
+        mMetricsLogger.write(builder);
+    }
+
     private int getTransitionType(WindowingModeTransitionInfo info) {
         if (info.currentTransitionProcessRunning) {
             if (info.startResult == START_SUCCESS) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 75f2723..60f79f72 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -694,9 +694,13 @@
         final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null;
         if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) {
             // Picture-in-picture mode changes also trigger a multi-window mode change as well, so
-            // update that here in order
+            // update that here in order. Set the last reported MW state to the same as the PiP
+            // state since we haven't yet actually resized the task (these callbacks need to
+            // preceed the configuration change from the resiez.
+            // TODO(110009072): Once we move these callbacks to the client, remove all logic related
+            // to forcing the update of the picture-in-picture mode as a part of the PiP animation.
             mLastReportedPictureInPictureMode = inPictureInPictureMode;
-            mLastReportedMultiWindowMode = inMultiWindowMode();
+            mLastReportedMultiWindowMode = inPictureInPictureMode;
             final Configuration newConfig = task.computeNewOverrideConfigurationForBounds(
                     targetStackBounds, null);
             schedulePictureInPictureModeChanged(newConfig);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index c520101..2ae056f 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -4853,7 +4853,7 @@
             return mService.getActivityStartController().startActivityInPackage(
                     task.mCallingUid, callingPid, callingUid, callingPackage, intent, null, null,
                     null, 0, 0, options, userId, task, "startActivityFromRecents",
-                    false /* validateIncomingUser */);
+                    false /* validateIncomingUser */, null /* originatingPendingIntent */);
         } finally {
             if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && task != null) {
                 // If we are launching the task in the docked stack, put it into resizing mode so
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index a7c3200..edcf6e7 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -248,7 +248,8 @@
     final int startActivityInPackage(int uid, int realCallingPid, int realCallingUid,
             String callingPackage, Intent intent, String resolvedType, IBinder resultTo,
             String resultWho, int requestCode, int startFlags, SafeActivityOptions options,
-            int userId, TaskRecord inTask, String reason, boolean validateIncomingUser) {
+            int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
+            PendingIntentRecord originatingPendingIntent) {
 
         userId = checkTargetUser(userId, validateIncomingUser, realCallingPid, realCallingUid,
                 reason);
@@ -267,6 +268,7 @@
                 .setActivityOptions(options)
                 .setMayWait(userId)
                 .setInTask(inTask)
+                .setOriginatingPendingIntent(originatingPendingIntent)
                 .execute();
     }
 
@@ -278,10 +280,12 @@
      * @param intents Intents to start.
      * @param userId Start the intents on this user.
      * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID.
+     * @param originatingPendingIntent PendingIntentRecord that originated this activity start or
+     *        null if not originated by PendingIntent
      */
     final int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents,
             String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId,
-            boolean validateIncomingUser) {
+            boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) {
 
         final String reason = "startActivityInPackage";
 
@@ -290,12 +294,12 @@
 
         // TODO: Switch to user app stacks here.
         return startActivities(null, uid, callingPackage, intents, resolvedTypes, resultTo, options,
-                userId, reason);
+                userId, reason, originatingPendingIntent);
     }
 
     int startActivities(IApplicationThread caller, int callingUid, String callingPackage,
             Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options,
-            int userId, String reason) {
+            int userId, String reason, PendingIntentRecord originatingPendingIntent) {
         if (intents == null) {
             throw new NullPointerException("intents is null");
         }
@@ -374,6 +378,7 @@
                             // Top activity decides on animation being run, so we allow only for the
                             // top one as otherwise an activity below might consume it.
                             .setAllowPendingRemoteAnimationRegistryLookup(top /* allowLookup*/)
+                            .setOriginatingPendingIntent(originatingPendingIntent)
                             .execute();
 
                     if (res < 0) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 73e3d33..00ba3a6 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -99,6 +99,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.service.voice.IVoiceInteractionSession;
@@ -313,6 +314,7 @@
         int userId;
         WaitResult waitResult;
         int filterCallingUid;
+        PendingIntentRecord originatingPendingIntent;
 
         /**
          * If set to {@code true}, allows this activity start to look into
@@ -369,6 +371,7 @@
             avoidMoveToFront = false;
             allowPendingRemoteAnimationRegistryLookup = true;
             filterCallingUid = UserHandle.USER_NULL;
+            originatingPendingIntent = null;
         }
 
         /**
@@ -407,6 +410,7 @@
             allowPendingRemoteAnimationRegistryLookup
                     = request.allowPendingRemoteAnimationRegistryLookup;
             filterCallingUid = request.filterCallingUid;
+            originatingPendingIntent = request.originatingPendingIntent;
         }
     }
 
@@ -490,7 +494,8 @@
                         mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                         mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                         mRequest.inTask, mRequest.reason,
-                        mRequest.allowPendingRemoteAnimationRegistryLookup);
+                        mRequest.allowPendingRemoteAnimationRegistryLookup,
+                        mRequest.originatingPendingIntent);
             } else {
                 return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
                         mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
@@ -500,7 +505,8 @@
                         mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
                         mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
                         mRequest.outActivity, mRequest.inTask, mRequest.reason,
-                        mRequest.allowPendingRemoteAnimationRegistryLookup);
+                        mRequest.allowPendingRemoteAnimationRegistryLookup,
+                        mRequest.originatingPendingIntent);
             }
         } finally {
             onExecutionComplete();
@@ -532,7 +538,8 @@
             String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
             SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
             ActivityRecord[] outActivity, TaskRecord inTask, String reason,
-            boolean allowPendingRemoteAnimationRegistryLookup) {
+            boolean allowPendingRemoteAnimationRegistryLookup,
+            PendingIntentRecord originatingPendingIntent) {
 
         if (TextUtils.isEmpty(reason)) {
             throw new IllegalArgumentException("Need to specify a reason.");
@@ -545,7 +552,7 @@
                 aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                 callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                 options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
-                inTask, allowPendingRemoteAnimationRegistryLookup);
+                inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
 
         if (outActivity != null) {
             // mLastStartActivityRecord[0] is set in the call to startActivity above.
@@ -575,7 +582,8 @@
             String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
             SafeActivityOptions options,
             boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
-            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
+            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
+            PendingIntentRecord originatingPendingIntent) {
         int err = ActivityManager.START_SUCCESS;
         // Pull the optional Ephemeral Installer-only bundle out of the options early.
         final Bundle verificationBundle
@@ -865,10 +873,58 @@
 
         mController.doPendingActivityLaunches(false);
 
+        maybeLogActivityStart(callingUid, callingPackage, realCallingUid, intent, callerApp, r,
+                originatingPendingIntent);
+
         return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                 true /* doResume */, checkedOptions, inTask, outActivity);
     }
 
+    private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid,
+            Intent intent, ProcessRecord callerApp, ActivityRecord r,
+            PendingIntentRecord originatingPendingIntent) {
+        boolean callerAppHasForegroundActivity = (callerApp != null)
+                ? callerApp.foregroundActivities
+                : false;
+        if (!mService.isActivityStartsLoggingEnabled() || callerAppHasForegroundActivity
+                || r == null) {
+            // skip logging in this case
+            return;
+        }
+
+        try {
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart");
+            final int callingUidProcState = mService.getUidStateLocked(callingUid);
+            final boolean callingUidHasAnyVisibleWindow =
+                    mService.mWindowManager.isAnyWindowVisibleForUid(callingUid);
+            final int realCallingUidProcState = (callingUid == realCallingUid)
+                    ? callingUidProcState
+                    : mService.getUidStateLocked(realCallingUid);
+            final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
+                    ? callingUidHasAnyVisibleWindow
+                    : mService.mWindowManager.isAnyWindowVisibleForUid(realCallingUid);
+            final String targetPackage = r.packageName;
+            final int targetUid = (r.appInfo != null) ? r.appInfo.uid : -1;
+            final int targetUidProcState = mService.getUidStateLocked(targetUid);
+            final boolean targetUidHasAnyVisibleWindow = (targetUid != -1)
+                    ? mService.mWindowManager.isAnyWindowVisibleForUid(targetUid)
+                    : false;
+            final String targetWhitelistTag = (targetUid != -1)
+                    ? mService.getPendingTempWhitelistTagForUidLocked(targetUid)
+                    : null;
+
+            mSupervisor.getActivityMetricsLogger().logActivityStart(intent, callerApp, r,
+                    callingUid, callingPackage, callingUidProcState,
+                    callingUidHasAnyVisibleWindow,
+                    realCallingUid, realCallingUidProcState,
+                    realCallingUidHasAnyVisibleWindow,
+                    targetUid, targetPackage, targetUidProcState,
+                    targetUidHasAnyVisibleWindow, targetWhitelistTag,
+                    (originatingPendingIntent != null));
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        }
+    }
 
     /**
      * Creates a launch intent for the given auxiliary resolution data.
@@ -949,7 +1005,8 @@
             ProfilerInfo profilerInfo, WaitResult outResult,
             Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
             int userId, TaskRecord inTask, String reason,
-            boolean allowPendingRemoteAnimationRegistryLookup) {
+            boolean allowPendingRemoteAnimationRegistryLookup,
+            PendingIntentRecord originatingPendingIntent) {
         // Refuse possible leaked file descriptors
         if (intent != null && intent.hasFileDescriptors()) {
             throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -1100,7 +1157,7 @@
                     voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                     callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                     ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
-                    allowPendingRemoteAnimationRegistryLookup);
+                    allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent);
 
             Binder.restoreCallingIdentity(origId);
 
@@ -2625,6 +2682,11 @@
         return this;
     }
 
+    ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) {
+        mRequest.originatingPendingIntent = originatingPendingIntent;
+        return this;
+    }
+
     void dump(PrintWriter pw, String prefix) {
         prefix = prefix + "  ";
         pw.print(prefix);
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index a6dafbb..f0e2876 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -484,7 +484,8 @@
                                     task.intent, null, null, null, 0, 0,
                                     new SafeActivityOptions(ActivityOptions.makeBasic()),
                                     task.userId, null,
-                                    "AppErrors", false /*validateIncomingUser*/);
+                                    "AppErrors", false /*validateIncomingUser*/,
+                                    null /* originatingPendingIntent */);
                         }
                     }
                 }
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index 79c98e5..2649807 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -15,7 +15,7 @@
 jjaggi@google.com
 racarr@google.com
 chaviw@google.com
-brycelee@google.com
+vishnun@google.com
 akulian@google.com
 roosa@google.com
 
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index e0aa2a2..4e00304 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -307,7 +307,7 @@
                             } else if (finalIntent.getComponent() != null) {
                                 finalIntent.getComponent().appendShortString(tag);
                             } else if (finalIntent.getData() != null) {
-                                tag.append(finalIntent.getData());
+                                tag.append(finalIntent.getData().toSafeString());
                             }
                             owner.tempWhitelistForPendingIntentLocked(callingPid,
                                     callingUid, uid, duration, tag.toString());
@@ -346,13 +346,15 @@
                                 res = owner.getActivityStartController().startActivitiesInPackage(
                                         uid, key.packageName, allIntents, allResolvedTypes,
                                         resultTo, mergedOptions, userId,
-                                        false /* validateIncomingUser */);
+                                        false /* validateIncomingUser */,
+                                        this /* originatingPendingIntent */);
                             } else {
                                 res = owner.getActivityStartController().startActivityInPackage(uid,
                                         callingPid, callingUid, key.packageName, finalIntent,
                                         resolvedType, resultTo, resultWho, requestCode, 0,
                                         mergedOptions, userId, null, "PendingIntentRecord",
-                                        false /* validateIncomingUser */);
+                                        false /* validateIncomingUser */,
+                                        this /* originatingPendingIntent */);
                             }
                         } catch (RuntimeException e) {
                             Slog.w(TAG, "Unable to send startActivity intent", e);
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 302e195..9e7ce32 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -104,6 +104,11 @@
     static final int VISIBLE_APP_ADJ = 100;
     static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1;
 
+    // This is a process that was recently TOP and moved to FGS. Continue to treat it almost
+    // like a foreground app for a while.
+    // @see TOP_TO_FGS_GRACE_PERIOD
+    static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50;
+
     // This is the process running the current foreground app.  We'd really
     // rather not kill it!
     static final int FOREGROUND_APP_ADJ = 0;
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index caf52e3..e3e839f 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -163,6 +163,7 @@
     long lastRequestedGc;       // When we last asked the app to do a gc
     long lastLowMemory;         // When we last told the app that memory is low
     long lastProviderTime;      // The last time someone else was using a provider in this process.
+    long lastTopTime;           // The last time the process was in the TOP state or greater.
     boolean reportLowMemory;    // Set to true when waiting to report low mem
     boolean empty;              // Is this an empty background process?
     boolean cached;             // Is this a cached process?
@@ -380,6 +381,11 @@
             TimeUtils.formatDuration(lastProviderTime, nowUptime, pw);
             pw.println();
         }
+        if (lastTopTime > 0) {
+            pw.print(prefix); pw.print("lastTopTime=");
+            TimeUtils.formatDuration(lastTopTime, nowUptime, pw);
+            pw.println();
+        }
         if (hasStartedServices) {
             pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices);
         }
@@ -856,4 +862,8 @@
         }
         return list;
     }
+
+    boolean hasForegroundServices() {
+        return foregroundServices;
+    }
 }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 18c0957..415a822 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -24,7 +24,6 @@
 import static android.app.ActivityManager.USER_OP_SUCCESS;
 import static android.os.Process.SHELL_UID;
 import static android.os.Process.SYSTEM_UID;
-
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -48,6 +47,7 @@
 import android.app.IUserSwitchObserver;
 import android.app.KeyguardManager;
 import android.app.usage.UsageEvents;
+import android.appwidget.AppWidgetManagerInternal;
 import android.content.Context;
 import android.content.IIntentReceiver;
 import android.content.Intent;
@@ -87,8 +87,8 @@
 import android.util.SparseIntArray;
 import android.util.TimingsTraceLog;
 import android.util.proto.ProtoOutputStream;
-
 import android.view.Window;
+
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
@@ -533,6 +533,9 @@
             }
         }
 
+        // Spin up app widgets prior to boot-complete, so they can be ready promptly
+        mInjector.startUserWidgets(userId);
+
         Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId);
         // Do not report secondary users, runtime restarts or first boot/upgrade
         if (userId == UserHandle.USER_SYSTEM
@@ -2173,6 +2176,13 @@
             }
         }
 
+        void startUserWidgets(int userId) {
+            AppWidgetManagerInternal awm = LocalServices.getService(AppWidgetManagerInternal.class);
+            if (awm != null) {
+                awm.unlockUser(userId);
+            }
+        }
+
         void updateUserConfiguration() {
             synchronized (mService) {
                 mService.updateUserConfigurationLocked();
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 422f556..e40949b 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -217,6 +217,19 @@
     @Override
     // Called concurrently by multiple binder threads.
     // This method must not block or perform long-running operations.
+    public synchronized void onNat64PrefixEvent(int netId,
+            boolean added, String prefixString, int prefixLength)
+            throws RemoteException {
+        for (INetdEventCallback callback : mNetdEventCallbackList) {
+            if (callback != null) {
+                callback.onNat64PrefixEvent(netId, added, prefixString, prefixLength);
+            }
+        }
+    }
+
+    @Override
+    // Called concurrently by multiple binder threads.
+    // This method must not block or perform long-running operations.
     public synchronized void onPrivateDnsValidationEvent(int netId,
             String ipAddress, String hostname, boolean validated)
             throws RemoteException {
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index bf95210..9684f4c 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -944,6 +944,10 @@
     private class WaitingForNextProbeState extends State {
         @Override
         public void enter() {
+            scheduleNextProbe();
+        }
+
+        private void scheduleNextProbe() {
             final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
             sendMessageDelayed(msg, mReevaluateDelayMs);
             mReevaluateDelayMs *= 2;
diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java
index c370959..3ea9810 100644
--- a/services/core/java/com/android/server/connectivity/PacManager.java
+++ b/services/core/java/com/android/server/connectivity/PacManager.java
@@ -43,8 +43,6 @@
 import com.android.net.IProxyPortListener;
 import com.android.net.IProxyService;
 
-import libcore.io.Streams;
-
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.net.URL;
@@ -71,6 +69,11 @@
     private static final int DELAY_LONG = 4;
     private static final long MAX_PAC_SIZE = 20 * 1000 * 1000;
 
+    // Return values for #setCurrentProxyScriptUrl
+    enum ToSendOrNotToSendBroadcast {
+        DONT_SEND_BROADCAST, DO_SEND_BROADCAST
+    }
+
     private String mCurrentPac;
     @GuardedBy("mProxyLock")
     private volatile Uri mPacUrl = Uri.EMPTY;
@@ -171,13 +174,13 @@
      * PacManager will trigger a new broadcast when it is ready.
      *
      * @param proxy Proxy information that is about to be broadcast.
-     * @return Returns true when the broadcast should not be sent
+     * @return Returns whether the broadcast should be sent : either DO_ or DONT_SEND_BROADCAST
      */
-    synchronized boolean setCurrentProxyScriptUrl(ProxyInfo proxy) {
+    synchronized ToSendOrNotToSendBroadcast setCurrentProxyScriptUrl(ProxyInfo proxy) {
         if (!Uri.EMPTY.equals(proxy.getPacFileUrl())) {
             if (proxy.getPacFileUrl().equals(mPacUrl) && (proxy.getPort() > 0)) {
                 // Allow to send broadcast, nothing to do.
-                return false;
+                return ToSendOrNotToSendBroadcast.DO_SEND_BROADCAST;
             }
             mPacUrl = proxy.getPacFileUrl();
             mCurrentDelay = DELAY_1;
@@ -185,7 +188,7 @@
             mHasDownloaded = false;
             getAlarmManager().cancel(mPacRefreshIntent);
             bind();
-            return true;
+            return ToSendOrNotToSendBroadcast.DONT_SEND_BROADCAST;
         } else {
             getAlarmManager().cancel(mPacRefreshIntent);
             synchronized (mProxyLock) {
@@ -201,7 +204,7 @@
                     }
                 }
             }
-            return false;
+            return ToSendOrNotToSendBroadcast.DO_SEND_BROADCAST;
         }
     }
 
@@ -296,7 +299,7 @@
         Intent intent = new Intent();
         intent.setClassName(PAC_PACKAGE, PAC_SERVICE);
         if ((mProxyConnection != null) && (mConnection != null)) {
-            // Already bound no need to bind again, just download the new file.
+            // Already bound: no need to bind again, just download the new file.
             mNetThreadHandler.post(mPacDownloader);
             return;
         }
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index 15468ff..fdddccd 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -208,7 +208,10 @@
     public void sendProxyBroadcast() {
         final ProxyInfo defaultProxy = getDefaultProxy();
         final ProxyInfo proxyInfo = null != defaultProxy ? defaultProxy : new ProxyInfo("", 0, "");
-        if (mPacManager.setCurrentProxyScriptUrl(proxyInfo)) return;
+        if (mPacManager.setCurrentProxyScriptUrl(proxyInfo)
+                == PacManager.ToSendOrNotToSendBroadcast.DONT_SEND_BROADCAST) {
+            return;
+        }
         if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 3c14393..9dfdddb 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -944,10 +944,11 @@
     public boolean hasTetherableConfiguration() {
         final TetheringConfiguration cfg = mConfig;
         final boolean hasDownstreamConfiguration =
-                (cfg.tetherableUsbRegexs.length != 0) ||
-                (cfg.tetherableWifiRegexs.length != 0) ||
-                (cfg.tetherableBluetoothRegexs.length != 0);
-        final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty();
+                (cfg.tetherableUsbRegexs.length != 0)
+                || (cfg.tetherableWifiRegexs.length != 0)
+                || (cfg.tetherableBluetoothRegexs.length != 0);
+        final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty()
+                || cfg.chooseUpstreamAutomatically;
 
         return hasDownstreamConfiguration && hasUpstreamConfiguration;
     }
@@ -1381,7 +1382,7 @@
                     return;
                 }
 
-                mUpstreamNetworkMonitor.start(mDeps.getDefaultNetworkRequest());
+                mUpstreamNetworkMonitor.startObserveAllNetworks();
 
                 // TODO: De-duplicate with updateUpstreamWanted() below.
                 if (upstreamWanted()) {
@@ -1657,6 +1658,10 @@
         }
     }
 
+    public void systemReady() {
+        mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest());
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         // Binder.java closes the resource for us.
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index b7ed2f9..602aedb 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -206,45 +206,6 @@
     // Handle of the user initiating VPN.
     private final int mUserHandle;
 
-    // Listen to package removal and change events (update/uninstall) for this user
-    private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final Uri data = intent.getData();
-            final String packageName = data == null ? null : data.getSchemeSpecificPart();
-            if (packageName == null) {
-                return;
-            }
-
-            synchronized (Vpn.this) {
-                // Avoid race where always-on package has been unset
-                if (!packageName.equals(getAlwaysOnPackage())) {
-                    return;
-                }
-
-                final String action = intent.getAction();
-                Log.i(TAG, "Received broadcast " + action + " for always-on VPN package "
-                        + packageName + " in user " + mUserHandle);
-
-                switch(action) {
-                    case Intent.ACTION_PACKAGE_REPLACED:
-                        // Start vpn after app upgrade
-                        startAlwaysOnVpn();
-                        break;
-                    case Intent.ACTION_PACKAGE_REMOVED:
-                        final boolean isPackageRemoved = !intent.getBooleanExtra(
-                                Intent.EXTRA_REPLACING, false);
-                        if (isPackageRemoved) {
-                            setAlwaysOnPackage(null, false);
-                        }
-                        break;
-                }
-            }
-        }
-    };
-
-    private boolean mIsPackageIntentReceiverRegistered = false;
-
     public Vpn(Looper looper, Context context, INetworkManagementService netService,
             @UserIdInt int userHandle) {
         this(looper, context, netService, userHandle, new SystemServices(context));
@@ -500,7 +461,6 @@
             // Prepare this app. The notification will update as a side-effect of updateState().
             prepareInternal(packageName);
         }
-        maybeRegisterPackageChangeReceiverLocked(packageName);
         setVpnForcedLocked(mLockdown);
         return true;
     }
@@ -509,31 +469,6 @@
         return packageName == null || VpnConfig.LEGACY_VPN.equals(packageName);
     }
 
-    private void unregisterPackageChangeReceiverLocked() {
-        if (mIsPackageIntentReceiverRegistered) {
-            mContext.unregisterReceiver(mPackageIntentReceiver);
-            mIsPackageIntentReceiverRegistered = false;
-        }
-    }
-
-    private void maybeRegisterPackageChangeReceiverLocked(String packageName) {
-        // Unregister IntentFilter listening for previous always-on package change
-        unregisterPackageChangeReceiverLocked();
-
-        if (!isNullOrLegacyVpn(packageName)) {
-            mIsPackageIntentReceiverRegistered = true;
-
-            IntentFilter intentFilter = new IntentFilter();
-            // Protected intent can only be sent by system. No permission required in register.
-            intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
-            intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-            intentFilter.addDataScheme("package");
-            intentFilter.addDataSchemeSpecificPart(packageName, PatternMatcher.PATTERN_LITERAL);
-            mContext.registerReceiverAsUser(
-                    mPackageIntentReceiver, UserHandle.of(mUserHandle), intentFilter, null, null);
-        }
-    }
-
     /**
      * @return the package name of the VPN controller responsible for always-on VPN,
      *         or {@code null} if none is set or always-on VPN is controlled through
@@ -1302,7 +1237,6 @@
         setLockdown(false);
         mAlwaysOn = false;
 
-        unregisterPackageChangeReceiverLocked();
         // Quit any active connections
         agentDisconnect();
     }
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 3e5d5aa..3ac311b 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -55,10 +55,13 @@
  * A class to centralize all the network and link properties information
  * pertaining to the current and any potential upstream network.
  *
- * Calling #start() registers two callbacks: one to track the system default
- * network and a second to observe all networks.  The latter is necessary
- * while the expression of preferred upstreams remains a list of legacy
- * connectivity types.  In future, this can be revisited.
+ * The owner of UNM gets it to register network callbacks by calling the
+ * following methods :
+ * Calling #startTrackDefaultNetwork() to track the system default network.
+ * Calling #startObserveAllNetworks() to observe all networks. Listening all
+ * networks is necessary while the expression of preferred upstreams remains
+ * a list of legacy connectivity types.  In future, this can be revisited.
+ * Calling #registerMobileNetworkRequest() to bring up mobile DUN/HIPRI network.
  *
  * The methods and data members of this class are only to be accessed and
  * modified from the tethering master state machine thread. Any other
@@ -119,33 +122,31 @@
         mCM = cm;
     }
 
-    public void start(NetworkRequest defaultNetworkRequest) {
-        stop();
-
-        final NetworkRequest listenAllRequest = new NetworkRequest.Builder()
-                .clearCapabilities().build();
-        mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL);
-        cm().registerNetworkCallback(listenAllRequest, mListenAllCallback, mHandler);
-
-        if (defaultNetworkRequest != null) {
-            // This is not really a "request", just a way of tracking the system default network.
-            // It's guaranteed not to actually bring up any networks because it's the same request
-            // as the ConnectivityService default request, and thus shares fate with it. We can't
-            // use registerDefaultNetworkCallback because it will not track the system default
-            // network if there is a VPN that applies to our UID.
+    public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest) {
+        // This is not really a "request", just a way of tracking the system default network.
+        // It's guaranteed not to actually bring up any networks because it's the same request
+        // as the ConnectivityService default request, and thus shares fate with it. We can't
+        // use registerDefaultNetworkCallback because it will not track the system default
+        // network if there is a VPN that applies to our UID.
+        if (mDefaultNetworkCallback == null) {
             final NetworkRequest trackDefaultRequest = new NetworkRequest(defaultNetworkRequest);
             mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_DEFAULT_INTERNET);
             cm().requestNetwork(trackDefaultRequest, mDefaultNetworkCallback, mHandler);
         }
     }
 
+    public void startObserveAllNetworks() {
+        stop();
+
+        final NetworkRequest listenAllRequest = new NetworkRequest.Builder()
+                .clearCapabilities().build();
+        mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL);
+        cm().registerNetworkCallback(listenAllRequest, mListenAllCallback, mHandler);
+    }
+
     public void stop() {
         releaseMobileNetworkRequest();
 
-        releaseCallback(mDefaultNetworkCallback);
-        mDefaultNetworkCallback = null;
-        mDefaultInternetNetwork = null;
-
         releaseCallback(mListenAllCallback);
         mListenAllCallback = null;
 
@@ -264,9 +265,7 @@
         mNetworkMap.put(network, new NetworkState(null, null, null, network, null, null));
     }
 
-    private void handleNetCap(int callbackType, Network network, NetworkCapabilities newNc) {
-        if (callbackType == CALLBACK_DEFAULT_INTERNET) mDefaultInternetNetwork = network;
-
+    private void handleNetCap(Network network, NetworkCapabilities newNc) {
         final NetworkState prev = mNetworkMap.get(network);
         if (prev == null || newNc.equals(prev.networkCapabilities)) {
             // Ignore notifications about networks for which we have not yet
@@ -315,31 +314,25 @@
         notifyTarget(EVENT_ON_LINKPROPERTIES, network);
     }
 
-    private void handleSuspended(int callbackType, Network network) {
-        if (callbackType != CALLBACK_LISTEN_ALL) return;
+    private void handleSuspended(Network network) {
         if (!network.equals(mTetheringUpstreamNetwork)) return;
         mLog.log("SUSPENDED current upstream: " + network);
     }
 
-    private void handleResumed(int callbackType, Network network) {
-        if (callbackType != CALLBACK_LISTEN_ALL) return;
+    private void handleResumed(Network network) {
         if (!network.equals(mTetheringUpstreamNetwork)) return;
         mLog.log("RESUMED current upstream: " + network);
     }
 
-    private void handleLost(int callbackType, Network network) {
-        if (network.equals(mDefaultInternetNetwork)) {
-            mDefaultInternetNetwork = null;
-            // There are few TODOs within ConnectivityService's rematching code
-            // pertaining to spurious onLost() notifications.
-            //
-            // TODO: simplify this, probably if favor of code that:
-            //     - selects a new upstream if mTetheringUpstreamNetwork has
-            //       been lost (by any callback)
-            //     - deletes the entry from the map only when the LISTEN_ALL
-            //       callback gets  notified.
-            if (callbackType == CALLBACK_DEFAULT_INTERNET) return;
-        }
+    private void handleLost(Network network) {
+        // There are few TODOs within ConnectivityService's rematching code
+        // pertaining to spurious onLost() notifications.
+        //
+        // TODO: simplify this, probably if favor of code that:
+        //     - selects a new upstream if mTetheringUpstreamNetwork has
+        //       been lost (by any callback)
+        //     - deletes the entry from the map only when the LISTEN_ALL
+        //       callback gets notified.
 
         if (!mNetworkMap.containsKey(network)) {
             // Ignore loss of networks about which we had not previously
@@ -393,11 +386,17 @@
 
         @Override
         public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) {
-            handleNetCap(mCallbackType, network, newNc);
+            if (mCallbackType == CALLBACK_DEFAULT_INTERNET) {
+                mDefaultInternetNetwork = network;
+                return;
+            }
+            handleNetCap(network, newNc);
         }
 
         @Override
         public void onLinkPropertiesChanged(Network network, LinkProperties newLp) {
+            if (mCallbackType == CALLBACK_DEFAULT_INTERNET) return;
+
             handleLinkProp(network, newLp);
             // Any non-LISTEN_ALL callback will necessarily concern a network that will
             // also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback.
@@ -409,17 +408,25 @@
 
         @Override
         public void onNetworkSuspended(Network network) {
-            handleSuspended(mCallbackType, network);
+            if (mCallbackType == CALLBACK_LISTEN_ALL) {
+                handleSuspended(network);
+            }
         }
 
         @Override
         public void onNetworkResumed(Network network) {
-            handleResumed(mCallbackType, network);
+            if (mCallbackType == CALLBACK_LISTEN_ALL) {
+                handleResumed(network);
+            }
         }
 
         @Override
         public void onLost(Network network) {
-            handleLost(mCallbackType, network);
+            if (mCallbackType == CALLBACK_DEFAULT_INTERNET) {
+                mDefaultInternetNetwork = null;
+                return;
+            }
+            handleLost(network);
             // Any non-LISTEN_ALL callback will necessarily concern a network that will
             // also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback.
             // So it's not useful to do this work for non-LISTEN_ALL callbacks.
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 349e1c8..512e851 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -104,6 +104,12 @@
     public static final int FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 10;
 
     /**
+     * Flag: The display cutout of this display is masked.
+     * @hide
+     */
+    public static final int FLAG_MASK_DISPLAY_CUTOUT = 1 << 11;
+
+    /**
      * Touch attachment: Display does not receive touch.
      */
     public static final int TOUCH_NONE = 0;
@@ -453,6 +459,9 @@
         if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
             msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD");
         }
+        if ((flags & FLAG_MASK_DISPLAY_CUTOUT) != 0) {
+            msg.append(", FLAG_MASK_DISPLAY_CUTOUT");
+        }
         return msg.toString();
     }
 }
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index ddd8855..cc5a827 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -151,6 +151,8 @@
     // Otherwise WFD is enabled according to the value of config_enableWifiDisplay.
     private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable";
 
+    private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top";
+
     private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000;
 
     private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
@@ -243,6 +245,15 @@
     // device).
     private Point mStableDisplaySize = new Point();
 
+    // Whether the system has finished booting or not.
+    private boolean mSystemReady;
+
+    // The top inset of the default display.
+    // This gets persisted so that the boot animation knows how to transition from the display's
+    // full size to the size configured by the user. Right now we only persist and animate the top
+    // inset, but theoretically we could do it for all of them.
+    private int mDefaultDisplayTopInset;
+
     // Viewports of the default display and the display that should receive touch
     // input from an external source.  Used by the input system.
     private final DisplayViewport mDefaultViewport = new DisplayViewport();
@@ -301,6 +312,7 @@
         Resources resources = mContext.getResources();
         mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
+        mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1);
         float[] lux = getFloatArray(resources.obtainTypedArray(
                 com.android.internal.R.array.config_minimumBrightnessCurveLux));
         float[] nits = getFloatArray(resources.obtainTypedArray(
@@ -311,6 +323,8 @@
         PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
         mCurrentUserId = UserHandle.USER_SYSTEM;
+
+        mSystemReady = false;
     }
 
     public void setupSchedulerPolicies() {
@@ -400,6 +414,10 @@
         synchronized (mSyncRoot) {
             mSafeMode = safeMode;
             mOnlyCore = onlyCore;
+            mSystemReady = true;
+            // Just in case the top inset changed before the system was ready. At this point, any
+            // relevant configuration should be in place.
+            recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY));
         }
 
         mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
@@ -457,7 +475,7 @@
             LogicalDisplay display = mLogicalDisplays.get(displayId);
             if (display != null) {
                 if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) {
-                    sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
+                    handleLogicalDisplayChanged(displayId, display);
                     scheduleTraversalLocked(false);
                 }
             }
@@ -938,6 +956,13 @@
         scheduleTraversalLocked(false);
     }
 
+    private void handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display) {
+        if (displayId == Display.DEFAULT_DISPLAY) {
+            recordTopInsetLocked(display);
+        }
+        sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
+    }
+
     private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) {
         final int count = mDisplayDevices.size();
         for (int i = 0; i < count; i++) {
@@ -991,6 +1016,7 @@
         configureColorModeLocked(display, device);
         if (isDefault) {
             recordStableDisplayStatsIfNeededLocked(display);
+            recordTopInsetLocked(display);
         }
 
         mLogicalDisplays.put(displayId, display);
@@ -1039,6 +1065,21 @@
         }
     }
 
+    private void recordTopInsetLocked(@Nullable LogicalDisplay d) {
+        // We must only persist the inset after boot has completed, otherwise we will end up
+        // overwriting the persisted value before the masking flag has been loaded from the
+        // resource overlay.
+        if (!mSystemReady || d == null) {
+            return;
+        }
+        int topInset = d.getInsets().top;
+        if (topInset == mDefaultDisplayTopInset) {
+            return;
+        }
+        mDefaultDisplayTopInset = topInset;
+        SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset));
+    }
+
     private void setStableDisplaySizeLocked(int width, int height) {
         mStableDisplaySize = new Point(width, height);
         try {
@@ -1118,7 +1159,7 @@
                 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
                 changed = true;
             } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) {
-                sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED);
+                handleLogicalDisplayChanged(displayId, display);
                 changed = true;
             }
         }
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 21ae048..16d82df 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -402,6 +402,10 @@
                             && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
                         mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
                     }
+                    if (res.getBoolean(
+                            com.android.internal.R.bool.config_maskMainBuiltInDisplayCutout)) {
+                        mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT;
+                    }
                     mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
                             mInfo.width, mInfo.height);
                     mInfo.type = Display.TYPE_BUILT_IN;
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 23ee56b..5b7c520 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -18,11 +18,14 @@
 
 import android.graphics.Rect;
 import android.hardware.display.DisplayManagerInternal;
+import android.os.SystemProperties;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Surface;
 import android.view.SurfaceControl;
 
+import com.android.server.wm.utils.InsetUtils;
+
 import java.io.PrintWriter;
 import java.util.Arrays;
 import java.util.List;
@@ -55,6 +58,8 @@
  * </p>
  */
 final class LogicalDisplay {
+    private static final String PROP_MASKING_INSET_TOP = "persist.sys.displayinset.top";
+
     private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();
 
     // The layer stack we use when the display has been blanked to prevent any
@@ -251,14 +256,18 @@
             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
                 mBaseDisplayInfo.flags |= Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
             }
+            Rect maskingInsets = getMaskingInsets(deviceInfo);
+            int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
+            int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;
+
             mBaseDisplayInfo.type = deviceInfo.type;
             mBaseDisplayInfo.address = deviceInfo.address;
             mBaseDisplayInfo.name = deviceInfo.name;
             mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId;
-            mBaseDisplayInfo.appWidth = deviceInfo.width;
-            mBaseDisplayInfo.appHeight = deviceInfo.height;
-            mBaseDisplayInfo.logicalWidth = deviceInfo.width;
-            mBaseDisplayInfo.logicalHeight = deviceInfo.height;
+            mBaseDisplayInfo.appWidth = maskedWidth;
+            mBaseDisplayInfo.appHeight = maskedHeight;
+            mBaseDisplayInfo.logicalWidth = maskedWidth;
+            mBaseDisplayInfo.logicalHeight = maskedHeight;
             mBaseDisplayInfo.rotation = Surface.ROTATION_0;
             mBaseDisplayInfo.modeId = deviceInfo.modeId;
             mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
@@ -275,13 +284,15 @@
             mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
             mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
             mBaseDisplayInfo.state = deviceInfo.state;
-            mBaseDisplayInfo.smallestNominalAppWidth = deviceInfo.width;
-            mBaseDisplayInfo.smallestNominalAppHeight = deviceInfo.height;
-            mBaseDisplayInfo.largestNominalAppWidth = deviceInfo.width;
-            mBaseDisplayInfo.largestNominalAppHeight = deviceInfo.height;
+            mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth;
+            mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight;
+            mBaseDisplayInfo.largestNominalAppWidth = maskedWidth;
+            mBaseDisplayInfo.largestNominalAppHeight = maskedHeight;
             mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid;
             mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName;
-            mBaseDisplayInfo.displayCutout = deviceInfo.displayCutout;
+            boolean maskCutout =
+                    (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
+            mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout;
 
             mPrimaryDisplayDeviceInfo = deviceInfo;
             mInfo = null;
@@ -289,6 +300,29 @@
     }
 
     /**
+     * Return the insets currently applied to the display.
+     *
+     * Note that the base DisplayInfo already takes these insets into account, so if you want to
+     * find out the <b>true</b> size of the display, you need to add them back to the logical
+     * dimensions.
+     */
+    public Rect getInsets() {
+        return getMaskingInsets(mPrimaryDisplayDeviceInfo);
+    }
+
+    /**
+     * Returns insets in ROTATION_0 for areas that are masked.
+     */
+    private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) {
+        boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
+        if (maskCutout && deviceInfo.displayCutout != null) {
+            return deviceInfo.displayCutout.getSafeInsets();
+        } else {
+            return new Rect();
+        }
+    }
+
+    /**
      * Applies the layer stack and transformation to the given display device
      * so that it shows the contents of this logical display.
      *
@@ -349,6 +383,12 @@
         int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width;
         int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height;
 
+        Rect maskingInsets = getMaskingInsets(displayDeviceInfo);
+        InsetUtils.rotateInsets(maskingInsets, orientation);
+        // Don't consider the masked area as available when calculating the scaling below.
+        physWidth -= maskingInsets.left + maskingInsets.right;
+        physHeight -= maskingInsets.top + maskingInsets.bottom;
+
         // Determine whether the width or height is more constrained to be scaled.
         //    physWidth / displayInfo.logicalWidth    => letter box
         // or physHeight / displayInfo.logicalHeight  => pillar box
@@ -375,6 +415,9 @@
         mTempDisplayRect.set(displayRectLeft, displayRectTop,
                 displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);
 
+        // Now add back the offset for the masked area.
+        mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top);
+
         mTempDisplayRect.left += mDisplayOffsetX;
         mTempDisplayRect.right += mDisplayOffsetX;
         mTempDisplayRect.top += mDisplayOffsetY;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index de0f298..25ca278 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1082,13 +1082,14 @@
         assertRunOnServiceThread();
 
         if (!canStartArcUpdateAction(message.getSource(), true)) {
-            if (getAvrDeviceInfo() == null) {
+            HdmiDeviceInfo avrDeviceInfo = getAvrDeviceInfo();
+            if (avrDeviceInfo == null) {
                 // AVR may not have been discovered yet. Delay the message processing.
                 mDelayedMessageBuffer.add(message);
                 return true;
             }
             mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
-            if (!isConnectedToArcPort(message.getSource())) {
+            if (!isConnectedToArcPort(avrDeviceInfo.getPhysicalAddress())) {
                 displayOsd(OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT);
             }
             return true;
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 268e844..0120dc3 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -80,8 +80,10 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import libcore.util.EmptyArray;
 
 /**
@@ -93,6 +95,31 @@
     private final Locale HONG_KONG = new Locale("zh", "HK");
     private final Locale MACAU = new Locale("zh", "MO");
 
+    private static final Map<String, String> mTerminologyToBibliographicMap;
+    static {
+        mTerminologyToBibliographicMap = new HashMap<>();
+        // NOTE: (TERMINOLOGY_CODE, BIBLIOGRAPHIC_CODE)
+        mTerminologyToBibliographicMap.put("sqi", "alb"); // Albanian
+        mTerminologyToBibliographicMap.put("hye", "arm"); // Armenian
+        mTerminologyToBibliographicMap.put("eus", "baq"); // Basque
+        mTerminologyToBibliographicMap.put("mya", "bur"); // Burmese
+        mTerminologyToBibliographicMap.put("ces", "cze"); // Czech
+        mTerminologyToBibliographicMap.put("nld", "dut"); // Dutch
+        mTerminologyToBibliographicMap.put("kat", "geo"); // Georgian
+        mTerminologyToBibliographicMap.put("deu", "ger"); // German
+        mTerminologyToBibliographicMap.put("ell", "gre"); // Greek
+        mTerminologyToBibliographicMap.put("fra", "fre"); // French
+        mTerminologyToBibliographicMap.put("isl", "ice"); // Icelandic
+        mTerminologyToBibliographicMap.put("mkd", "mac"); // Macedonian
+        mTerminologyToBibliographicMap.put("mri", "mao"); // Maori
+        mTerminologyToBibliographicMap.put("msa", "may"); // Malay
+        mTerminologyToBibliographicMap.put("fas", "per"); // Persian
+        mTerminologyToBibliographicMap.put("ron", "rum"); // Romanian
+        mTerminologyToBibliographicMap.put("slk", "slo"); // Slovak
+        mTerminologyToBibliographicMap.put("bod", "tib"); // Tibetan
+        mTerminologyToBibliographicMap.put("cym", "wel"); // Welsh
+    }
+
     static final String PERMISSION = "android.permission.HDMI_CEC";
 
     // The reason code to initiate intializeCec().
@@ -176,7 +203,18 @@
                 // Chinese used in Taiwan/Hong Kong/Macau.
                 return "chi";
             } else {
-                return locale.getISO3Language();
+                String language = locale.getISO3Language();
+
+                // locale.getISO3Language() returns terminology code and need to
+                // send it as bibliographic code instead since the Bibliographic
+                // codes of ISO/FDIS 639-2 shall be used.
+                // NOTE: Chinese also has terminology/bibliographic code "zho" and "chi"
+                // But, as it depends on the locale, is not handled here.
+                if (mTerminologyToBibliographicMap.containsKey(language)) {
+                    language = mTerminologyToBibliographicMap.get(language);
+                }
+
+                return language;
             }
         }
     }
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 383e1e0..8237185 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -955,7 +955,13 @@
 
     @Override
     public long getIfaceStats(String iface, int type) {
-        return nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
+        // eBPF code doesn't provide per-interface TCP counters. Use xt_qtaguid for now.
+        // TODO: delete getMobileTcp(Rx|Tx)Packets entirely. See b/110443385 .
+        if (type == TYPE_TCP_TX_PACKETS || type == TYPE_TCP_RX_PACKETS) {
+            return nativeGetIfaceStat(iface, type, false);
+        } else {
+            return nativeGetIfaceStat(iface, type, checkBpfStatsEnable());
+        }
     }
 
     @Override
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index c0fbfbb..18f4bc7 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -150,6 +150,7 @@
         try {
             provider.onConnected();
         } catch (RemoteException e) {
+            Slog.e(TAG, "can't connect to service " + info, e);
             // we tried
         }
         if (mCallback != null) {
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index f7becd5..30fa7fe 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -175,6 +175,10 @@
         }
     }
 
+    protected int getBindFlags() {
+        return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT;
+    }
+
     protected void onServiceRemovedLocked(ManagedServiceInfo removed) { }
 
     private ManagedServiceInfo newServiceInfo(IInterface service,
@@ -1022,9 +1026,9 @@
                 }
             };
             if (!mContext.bindServiceAsUser(intent,
-                serviceConnection,
-                BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT,
-                new UserHandle(userid))) {
+                    serviceConnection,
+                    getBindFlags(),
+                    new UserHandle(userid))) {
                 mServicesBinding.remove(servicesBindingTag);
                 Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent);
                 return;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 1284468..f70ecd5 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -33,6 +33,10 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
+import static android.content.Context.BIND_ADJUST_BELOW_PERCEPTIBLE;
+import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
+import static android.content.Context.BIND_AUTO_CREATE;
+import static android.content.Context.BIND_FOREGROUND_SERVICE;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK;
 import static android.content.pm.PackageManager.FEATURE_TELEVISION;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -2122,6 +2126,10 @@
             enforceSystemOrSystemUI("setNotificationsEnabledForPackage");
 
             mRankingHelper.setEnabled(pkg, uid, enabled);
+            mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES)
+                    .setType(MetricsEvent.TYPE_ACTION)
+                    .setPackageName(pkg)
+                    .setSubtype(enabled ? 1 : 0));
             // Now, cancel any outstanding notifications that are part of a just-disabled app
             if (!enabled) {
                 cancelAllNotificationsInt(MY_UID, MY_PID, pkg, null, 0, 0, true,
@@ -6510,6 +6518,16 @@
         }
 
         @Override
+        protected int getBindFlags() {
+            // Most of the same flags as the base, but also add BIND_ADJUST_BELOW_PERCEPTIBLE
+            // because too many 3P apps could be kept in memory as notification listeners and
+            // cause extreme memory pressure.
+            // TODO: Change the binding lifecycle of NotificationListeners to avoid this situation.
+            return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE
+                    | BIND_ADJUST_BELOW_PERCEPTIBLE | BIND_ALLOW_WHITELIST_MANAGEMENT;
+        }
+
+        @Override
         protected Config getConfig() {
             Config c = new Config();
             c.caption = "notification listener";
diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java
index 6760875..b016faf 100644
--- a/services/core/java/com/android/server/notification/ZenLog.java
+++ b/services/core/java/com/android/server/notification/ZenLog.java
@@ -36,7 +36,8 @@
 
 public class ZenLog {
     private static final String TAG = "ZenLog";
-    private static final boolean DEBUG = Build.IS_DEBUGGABLE;
+    // the ZenLog is *very* verbose, so be careful about setting this to true
+    private static final boolean DEBUG = false;
 
     private static final int SIZE = Build.IS_DEBUGGABLE ? 100 : 20;
 
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index 63c0baf..b080a73 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -19,7 +19,6 @@
 import android.content.ComponentName;
 import android.net.Uri;
 import android.service.notification.Condition;
-import android.service.notification.IConditionListener;
 import android.service.notification.IConditionProvider;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.ZenRule;
@@ -27,6 +26,8 @@
 import android.util.ArraySet;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.io.PrintWriter;
 import java.util.Objects;
 
@@ -36,7 +37,9 @@
 
     private final ZenModeHelper mHelper;
     private final ConditionProviders mConditionProviders;
-    private final ArrayMap<Uri, ComponentName> mSubscriptions = new ArrayMap<>();
+
+    @VisibleForTesting
+    protected final ArrayMap<Uri, ComponentName> mSubscriptions = new ArrayMap<>();
 
     private boolean mFirstEvaluation = true;
 
@@ -59,7 +62,8 @@
         pw.print(prefix); pw.print("mSubscriptions="); pw.println(mSubscriptions);
     }
 
-    public void evaluateConfig(ZenModeConfig config, boolean processSubscriptions) {
+    public void evaluateConfig(ZenModeConfig config, ComponentName trigger,
+            boolean processSubscriptions) {
         if (config == null) return;
         if (config.manualRule != null && config.manualRule.condition != null
                 && !config.manualRule.isTrueOrUnknown()) {
@@ -67,9 +71,9 @@
             config.manualRule = null;
         }
         final ArraySet<Uri> current = new ArraySet<>();
-        evaluateRule(config.manualRule, current, processSubscriptions);
+        evaluateRule(config.manualRule, current, null, processSubscriptions);
         for (ZenRule automaticRule : config.automaticRules.values()) {
-            evaluateRule(automaticRule, current, processSubscriptions);
+            evaluateRule(automaticRule, current, trigger, processSubscriptions);
             updateSnoozing(automaticRule);
         }
 
@@ -102,7 +106,7 @@
     @Override
     public void onServiceAdded(ComponentName component) {
         if (DEBUG) Log.d(TAG, "onServiceAdded " + component);
-        mHelper.setConfig(mHelper.getConfig(), "zmc.onServiceAdded");
+        mHelper.setConfig(mHelper.getConfig(), component, "zmc.onServiceAdded");
     }
 
     @Override
@@ -110,17 +114,22 @@
         if (DEBUG) Log.d(TAG, "onConditionChanged " + id + " " + condition);
         ZenModeConfig config = mHelper.getConfig();
         if (config == null) return;
+        ComponentName trigger = null;
         boolean updated = updateCondition(id, condition, config.manualRule);
         for (ZenRule automaticRule : config.automaticRules.values()) {
             updated |= updateCondition(id, condition, automaticRule);
             updated |= updateSnoozing(automaticRule);
+            if (updated) {
+                trigger = automaticRule.component;
+            }
         }
         if (updated) {
-            mHelper.setConfig(config, "conditionChanged");
+            mHelper.setConfig(config, trigger, "conditionChanged");
         }
     }
 
-    private void evaluateRule(ZenRule rule, ArraySet<Uri> current, boolean processSubscriptions) {
+    private void evaluateRule(ZenRule rule, ArraySet<Uri> current, ComponentName trigger,
+            boolean processSubscriptions) {
         if (rule == null || rule.conditionId == null) return;
         final Uri id = rule.conditionId;
         boolean isSystemCondition = false;
@@ -146,7 +155,9 @@
         if (current != null) {
             current.add(id);
         }
-        if (processSubscriptions) {
+        if (processSubscriptions && ((trigger != null && trigger.equals(rule.component))
+                || isSystemCondition)) {
+            if (DEBUG) Log.d(TAG, "Subscribing to " + rule.component);
             if (mConditionProviders.subscribeIfNecessary(rule.component, rule.conditionId)) {
                 synchronized (mSubscriptions) {
                     mSubscriptions.put(rule.conditionId, rule.component);
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 669d556..0c42f8a 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -102,7 +102,7 @@
     private final ZenModeFiltering mFiltering;
     protected final RingerModeDelegate mRingerModeDelegate = new
             RingerModeDelegate();
-    private final ZenModeConditions mConditions;
+    @VisibleForTesting protected final ZenModeConditions mConditions;
     private final SparseArray<ZenModeConfig> mConfigs = new SparseArray<>();
     private final Metrics mMetrics = new Metrics();
     private final ConditionProviders.Config mServiceConfig;
@@ -225,7 +225,7 @@
             config.user = user;
         }
         synchronized (mConfig) {
-            setConfigLocked(config, reason);
+            setConfigLocked(config, null, reason);
         }
         cleanUpZenRules();
     }
@@ -312,7 +312,7 @@
             ZenRule rule = new ZenRule();
             populateZenRule(automaticZenRule, rule, true);
             newConfig.automaticRules.put(rule.id, rule);
-            if (setConfigLocked(newConfig, reason, true)) {
+            if (setConfigLocked(newConfig, reason, rule.component, true)) {
                 return rule.id;
             } else {
                 throw new AndroidRuntimeException("Could not create rule");
@@ -342,7 +342,7 @@
             }
             populateZenRule(automaticZenRule, rule, false);
             newConfig.automaticRules.put(ruleId, rule);
-            return setConfigLocked(newConfig, reason, true);
+            return setConfigLocked(newConfig, reason, rule.component, true);
         }
     }
 
@@ -360,7 +360,7 @@
                 throw new SecurityException(
                         "Cannot delete rules not owned by your condition provider");
             }
-            return setConfigLocked(newConfig, reason, true);
+            return setConfigLocked(newConfig, reason, null, true);
         }
     }
 
@@ -376,7 +376,7 @@
                     newConfig.automaticRules.removeAt(i);
                 }
             }
-            return setConfigLocked(newConfig, reason, true);
+            return setConfigLocked(newConfig, reason, null, true);
         }
     }
 
@@ -537,7 +537,7 @@
                 newRule.enabler = caller;
                 newConfig.manualRule = newRule;
             }
-            setConfigLocked(newConfig, reason, setRingerMode);
+            setConfigLocked(newConfig, reason, null, setRingerMode);
         }
     }
 
@@ -644,7 +644,7 @@
             }
             if (DEBUG) Log.d(TAG, reason);
             synchronized (mConfig) {
-                setConfigLocked(config, reason);
+                setConfigLocked(config, null, reason);
             }
         }
     }
@@ -673,7 +673,7 @@
         synchronized (mConfig) {
             final ZenModeConfig newConfig = mConfig.copy();
             newConfig.applyNotificationPolicy(policy);
-            setConfigLocked(newConfig, "setNotificationPolicy");
+            setConfigLocked(newConfig, null, "setNotificationPolicy");
         }
     }
 
@@ -697,7 +697,7 @@
                     }
                 }
             }
-            setConfigLocked(newConfig, "cleanUpZenRules");
+            setConfigLocked(newConfig, null, "cleanUpZenRules");
         }
     }
 
@@ -710,17 +710,19 @@
         }
     }
 
-    public boolean setConfigLocked(ZenModeConfig config, String reason) {
-        return setConfigLocked(config, reason, true /*setRingerMode*/);
+    public boolean setConfigLocked(ZenModeConfig config, ComponentName triggeringComponent,
+            String reason) {
+        return setConfigLocked(config, reason, triggeringComponent, true /*setRingerMode*/);
     }
 
-    public void setConfig(ZenModeConfig config, String reason) {
+    public void setConfig(ZenModeConfig config, ComponentName triggeringComponent, String reason) {
         synchronized (mConfig) {
-            setConfigLocked(config, reason);
+            setConfigLocked(config, triggeringComponent, reason);
         }
     }
 
-    private boolean setConfigLocked(ZenModeConfig config, String reason, boolean setRingerMode) {
+    private boolean setConfigLocked(ZenModeConfig config, String reason,
+            ComponentName triggeringComponent, boolean setRingerMode) {
         final long identity = Binder.clearCallingIdentity();
         try {
             if (config == null || !config.isValid()) {
@@ -733,7 +735,8 @@
                 if (DEBUG) Log.d(TAG, "setConfigLocked: store config for user " + config.user);
                 return true;
             }
-            mConditions.evaluateConfig(config, false /*processSubscriptions*/);  // may modify config
+            // may modify config
+            mConditions.evaluateConfig(config, null, false /*processSubscriptions*/);
             mConfigs.put(config.user, config);
             if (DEBUG) Log.d(TAG, "setConfigLocked reason=" + reason, new Throwable());
             ZenLog.traceConfig(reason, mConfig, config);
@@ -746,7 +749,7 @@
                 dispatchOnPolicyChanged();
             }
             mConfig = config;
-            mHandler.postApplyConfig(config, reason, setRingerMode);
+            mHandler.postApplyConfig(config, reason, triggeringComponent, setRingerMode);
             return true;
         } catch (SecurityException e) {
             Log.wtf(TAG, "Invalid rule in config", e);
@@ -756,13 +759,14 @@
         }
     }
 
-    private void applyConfig(ZenModeConfig config, String reason, boolean setRingerMode) {
+    private void applyConfig(ZenModeConfig config, String reason,
+            ComponentName triggeringComponent, boolean setRingerMode) {
         final String val = Integer.toString(config.hashCode());
         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_CONFIG_ETAG, val);
         if (!evaluateZenMode(reason, setRingerMode)) {
             applyRestrictions();  // evaluateZenMode will also apply restrictions if changed
         }
-        mConditions.evaluateConfig(config, true /*processSubscriptions*/);
+        mConditions.evaluateConfig(config, triggeringComponent, true /*processSubscriptions*/);
     }
 
     private int getZenModeSetting() {
@@ -1260,13 +1264,16 @@
 
         private final class ConfigMessageData {
             public final ZenModeConfig config;
+            public ComponentName triggeringComponent;
             public final String reason;
             public final boolean setRingerMode;
 
-            ConfigMessageData(ZenModeConfig config, String reason, boolean setRingerMode) {
+            ConfigMessageData(ZenModeConfig config, String reason,
+                    ComponentName triggeringComponent, boolean setRingerMode) {
                 this.config = config;
                 this.reason = reason;
                 this.setRingerMode = setRingerMode;
+                this.triggeringComponent = triggeringComponent;
             }
         }
 
@@ -1286,9 +1293,10 @@
             sendEmptyMessageDelayed(MSG_METRICS, METRICS_PERIOD_MS);
         }
 
-        private void postApplyConfig(ZenModeConfig config, String reason, boolean setRingerMode) {
+        private void postApplyConfig(ZenModeConfig config, String reason,
+                ComponentName triggeringComponent, boolean setRingerMode) {
             sendMessage(obtainMessage(MSG_APPLY_CONFIG,
-                    new ConfigMessageData(config, reason, setRingerMode)));
+                    new ConfigMessageData(config, reason, triggeringComponent, setRingerMode)));
         }
 
         @Override
@@ -1303,7 +1311,7 @@
                 case MSG_APPLY_CONFIG:
                     ConfigMessageData applyConfigData = (ConfigMessageData) msg.obj;
                     applyConfig(applyConfigData.config, applyConfigData.reason,
-                            applyConfigData.setRingerMode);
+                            applyConfigData.triggeringComponent, applyConfigData.setRingerMode);
             }
         }
     }
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 350fb2f..f1b03d1 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -22,11 +22,14 @@
 import static android.content.Intent.ACTION_PACKAGE_REMOVED;
 import static android.content.Intent.ACTION_USER_ADDED;
 import static android.content.Intent.ACTION_USER_REMOVED;
+import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES;
+import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 import static android.content.pm.PackageManager.SIGNATURE_MATCH;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
+import android.app.ActivityThread;
 import android.app.IActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -34,6 +37,7 @@
 import android.content.IntentFilter;
 import android.content.om.IOverlayManager;
 import android.content.om.OverlayInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManagerInternal;
@@ -269,13 +273,30 @@
 
     @Override
     public void onBootPhase(int phase) {
-        if (phase == PHASE_SYSTEM_SERVICES_READY) {
+        if (phase == PHASE_SYSTEM_SERVICES_READY && mInitCompleteSignal != null) {
             ConcurrentUtils.waitForFutureNoInterrupt(mInitCompleteSignal,
                     "Wait for OverlayManagerService init");
             mInitCompleteSignal = null;
         }
     }
 
+    public void updateSystemUiContext() {
+        if (mInitCompleteSignal != null) {
+            ConcurrentUtils.waitForFutureNoInterrupt(mInitCompleteSignal,
+                    "Wait for OverlayManagerService init");
+            mInitCompleteSignal = null;
+        }
+
+        final ApplicationInfo ai;
+        try {
+            ai = mPackageManager.mPackageManager.getApplicationInfo("android",
+                    GET_SHARED_LIBRARY_FILES, UserHandle.USER_SYSTEM);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+        ActivityThread.currentActivityThread().handleSystemApplicationInfoChanged(ai);
+    }
+
     private void initIfNeeded() {
         final UserManager um = getContext().getSystemService(UserManager.class);
         final List<UserInfo> users = um.getUsers(true /*excludeDying*/);
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index c197d23..5e1ed03 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -35,6 +35,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.pm.Installer.InstallerException;
+import com.android.server.pm.dex.ArtManagerService;
 import com.android.server.pm.dex.DexManager;
 import com.android.server.pm.dex.DexoptOptions;
 import com.android.server.pm.dex.DexoptUtils;
@@ -291,7 +292,8 @@
             mInstaller.dexopt(path, uid, pkg.packageName, isa, dexoptNeeded, oatDir, dexoptFlags,
                     compilerFilter, pkg.volumeUuid, classLoaderContext, pkg.applicationInfo.seInfo,
                     false /* downgrade*/, pkg.applicationInfo.targetSdkVersion,
-                    profileName, dexMetadataPath, getReasonName(compilationReason));
+                    profileName, dexMetadataPath,
+                    getAugmentedReasonName(compilationReason, dexMetadataPath != null));
 
             if (packageStats != null) {
                 long endTime = System.currentTimeMillis();
@@ -304,6 +306,12 @@
         }
     }
 
+    private String getAugmentedReasonName(int compilationReason, boolean useDexMetadata) {
+        String annotation = useDexMetadata
+                ? ArtManagerService.DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : "";
+        return getReasonName(compilationReason) + annotation;
+    }
+
     /**
      * Performs dexopt on the secondary dex {@code path} belonging to the app {@code info}.
      *
@@ -396,12 +404,17 @@
                 + " dexoptFlags=" + printDexoptFlags(dexoptFlags)
                 + " target-filter=" + compilerFilter);
 
-        // TODO(calin): b/64530081 b/66984396. Use SKIP_SHARED_LIBRARY_CHECK for the context
-        // (instead of dexUseInfo.getClassLoaderContext()) in order to compile secondary dex files
-        // in isolation (and avoid to extract/verify the main apk if it's in the class path).
-        // Note this trades correctness for performance since the resulting slow down is
-        // unacceptable in some cases until b/64530081 is fixed.
-        String classLoaderContext = SKIP_SHARED_LIBRARY_CHECK;
+        String classLoaderContext;
+        if (dexUseInfo.isUnknownClassLoaderContext() || dexUseInfo.isVariableClassLoaderContext()) {
+            // If we have an unknown (not yet set), or a variable class loader chain, compile
+            // without a context and mark the oat file with SKIP_SHARED_LIBRARY_CHECK. Note that
+            // this might lead to a incorrect compilation.
+            // TODO(calin): We should just extract in this case.
+            classLoaderContext = SKIP_SHARED_LIBRARY_CHECK;
+        } else {
+            classLoaderContext = dexUseInfo.getClassLoaderContext();
+        }
+
         int reason = options.getCompilationReason();
         try {
             for (String isa : dexUseInfo.getLoaderIsas()) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 52b6ffc..f4673a8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -456,6 +456,7 @@
     private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
     private static final int SHELL_UID = Process.SHELL_UID;
     private static final int SE_UID = Process.SE_UID;
+    private static final int NETWORKSTACK_UID = Process.NETWORK_STACK_UID;
 
     // Suffix used during package installation when copying/moving
     // package apks to install directory.
@@ -2469,6 +2470,8 @@
                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
         mSettings.addSharedUserLPw("android.uid.se", SE_UID,
                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
+        mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
+                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
 
         String separateProcesses = SystemProperties.get("debug.separate_processes");
         if (separateProcesses != null && separateProcesses.length() > 0) {
@@ -22060,9 +22063,6 @@
 
     //TODO: b/111402650
     private void disableSkuSpecificApps() {
-        if (!mIsUpgrade && !mFirstBoot) {
-            return;
-        }
         String apkList[] = mContext.getResources().getStringArray(
                 R.array.config_disableApksUnlessMatchedSku_apk_list);
         String skuArray[] = mContext.getResources().getStringArray(
@@ -22076,7 +22076,9 @@
         }
         for (String packageName : apkList) {
             setSystemAppHiddenUntilInstalled(packageName, true);
-            setSystemAppInstallState(packageName, false, ActivityManager.getCurrentUser());
+            for (UserInfo user : sUserManager.getUsers(false)) {
+                setSystemAppInstallState(packageName, false, user.id);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 580126f..e5b9030 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -534,6 +534,7 @@
         boolean listInstaller = false;
         boolean showUid = false;
         boolean showVersionCode = false;
+        boolean listApexOnly = false;
         int uid = -1;
         int userId = UserHandle.USER_SYSTEM;
         try {
@@ -573,6 +574,10 @@
                     case "--show-versioncode":
                         showVersionCode = true;
                         break;
+                    case "--apex-only":
+                        getFlags |= PackageManager.MATCH_APEX;
+                        listApexOnly = true;
+                        break;
                     case "--user":
                         userId = UserHandle.parseUserArg(getNextArgRequired());
                         break;
@@ -603,30 +608,38 @@
             if (filter != null && !info.packageName.contains(filter)) {
                 continue;
             }
-            if (uid != -1 && info.applicationInfo.uid != uid) {
+            final boolean isApex = info.isApex;
+            if (uid != -1 && !isApex && info.applicationInfo.uid != uid) {
                 continue;
             }
-            final boolean isSystem =
+
+            final boolean isSystem = !isApex &&
                     (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0;
-            if ((!listDisabled || !info.applicationInfo.enabled) &&
-                    (!listEnabled || info.applicationInfo.enabled) &&
+            final boolean isEnabled = !isApex && info.applicationInfo.enabled;
+            if ((!listDisabled || !isEnabled) &&
+                    (!listEnabled || isEnabled) &&
                     (!listSystem || isSystem) &&
-                    (!listThirdParty || !isSystem)) {
+                    (!listThirdParty || !isSystem) &&
+                    (!listApexOnly || isApex)) {
                 pw.print("package:");
-                if (showSourceDir) {
+                if (showSourceDir && !isApex) {
                     pw.print(info.applicationInfo.sourceDir);
                     pw.print("=");
                 }
                 pw.print(info.packageName);
                 if (showVersionCode) {
                     pw.print(" versionCode:");
-                    pw.print(info.applicationInfo.versionCode);
+                    if (info.applicationInfo != null) {
+                        pw.print(info.applicationInfo.versionCode);
+                    } else {
+                        pw.print(info.versionCode);
+                    }
                 }
-                if (listInstaller) {
+                if (listInstaller && !isApex) {
                     pw.print("  installer=");
                     pw.print(mInterface.getInstallerPackageName(info.packageName));
                 }
-                if (showUid) {
+                if (showUid && !isApex) {
                     pw.print(" uid:");
                     pw.print(info.applicationInfo.uid);
                 }
@@ -2692,11 +2705,11 @@
         pw.println("    Prints all system libraries.");
         pw.println("");
         pw.println("  list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
-        pw.println("      [--uid UID] [--user USER_ID] [FILTER]");
+        pw.println("      [--show-versioncode] [--apex-only] [--uid UID] [--user USER_ID] [FILTER]");
         pw.println("    Prints all packages; optionally only those whose name contains");
         pw.println("    the text in FILTER.  Options are:");
         pw.println("      -f: see their associated file");
-        pw.println("      -a: all known packages");
+        pw.println("      -a: all known packages (but excluding APEXes)");
         pw.println("      -d: filter to only show disabled packages");
         pw.println("      -e: filter to only show enabled packages");
         pw.println("      -s: filter to only show system packages");
@@ -2705,6 +2718,8 @@
         pw.println("      -l: ignored (used for compatibility with older releases)");
         pw.println("      -U: also show the package UID");
         pw.println("      -u: also include uninstalled packages");
+        pw.println("      --show-versioncode: also show the version code");
+        pw.println("      --apex-only: only show APEX packages");
         pw.println("      --uid UID: filter to only show packages with the given UID");
         pw.println("      --user USER_ID: only list packages belonging to the given user");
         pw.println("");
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index 1fb51b7..1f05dc9 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -527,6 +527,11 @@
     private static final int TRON_COMPILATION_REASON_AB_OTA = 6;
     private static final int TRON_COMPILATION_REASON_INACTIVE = 7;
     private static final int TRON_COMPILATION_REASON_SHARED = 8;
+    private static final int TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA = 9;
+
+    // The annotation to add as a suffix to the compilation reason when dexopt was
+    // performed with dex metadata.
+    public static final String DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION = "-dm";
 
     /**
      * Convert the compilation reason to an int suitable to be logged to TRON.
@@ -542,6 +547,10 @@
             case "ab-ota" : return TRON_COMPILATION_REASON_AB_OTA;
             case "inactive" : return TRON_COMPILATION_REASON_INACTIVE;
             case "shared" : return TRON_COMPILATION_REASON_SHARED;
+            // This is a special marker for dex metadata installation that does not
+            // have an equivalent as a system property.
+            case "install" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION :
+                return TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA;
             default: return TRON_COMPILATION_REASON_UNKNOWN;
         }
     }
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index 519a20d..a194f57 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -863,15 +863,13 @@
 
         public String getClassLoaderContext() { return mClassLoaderContext; }
 
-        @VisibleForTesting
-        /* package */ boolean isUnknownClassLoaderContext() {
+        public boolean isUnknownClassLoaderContext() {
             // The class loader context may be unknown if we loaded the data from a previous version
             // which didn't save the context.
             return UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
         }
 
-        @VisibleForTesting
-        /* package */ boolean isVariableClassLoaderContext() {
+        public boolean isVariableClassLoaderContext() {
             return VARIABLE_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
         }
     }
diff --git a/services/core/java/com/android/server/policy/BarController.java b/services/core/java/com/android/server/policy/BarController.java
index eca6f9f..14c985c 100644
--- a/services/core/java/com/android/server/policy/BarController.java
+++ b/services/core/java/com/android/server/policy/BarController.java
@@ -196,7 +196,7 @@
     }
 
     protected boolean skipAnimation() {
-        return false;
+        return !mWin.isDrawnLw();
     }
 
     private int computeStateLw(boolean wasVis, boolean wasAnim, WindowState win, boolean change) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index dfb6179..9a741bc 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -76,6 +76,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_BAR_EXPANDED;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE;
 import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT;
@@ -4397,17 +4398,9 @@
             if (isKeyguardShowingAndNotOccluded()) {
                 // don't launch home if keyguard showing
                 return;
-            } else if (mKeyguardOccluded && mKeyguardDelegate.isShowing()) {
-                mKeyguardDelegate.dismiss(new KeyguardDismissCallback() {
-                    @Override
-                    public void onDismissSucceeded() throws RemoteException {
-                        mHandler.post(() -> {
-                            startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
-                        });
-                    }
-                }, null /* message */);
-                return;
-            } else if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) {
+            }
+
+            if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) {
                 // when in keyguard restricted mode, must first verify unlock
                 // before launching home
                 mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
@@ -4692,8 +4685,7 @@
                 navTranslucent &= areTranslucentBarsAllowed();
             }
             boolean statusBarExpandedNotKeyguard = !isKeyguardShowing && mStatusBar != null
-                    && mStatusBar.getAttrs().height == MATCH_PARENT
-                    && mStatusBar.getAttrs().width == MATCH_PARENT;
+                    && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_STATUS_BAR_EXPANDED) != 0;
 
             // When the navigation bar isn't visible, we put up a fake input window to catch all
             // touch events. This way we can detect when the user presses anywhere to bring back the
@@ -5696,7 +5688,7 @@
         }
 
         // Take note if a window wants to acquire a sleep token.
-        if (win.isVisibleLw() && (attrs.privateFlags & PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN) != 0
+        if ((attrs.privateFlags & PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN) != 0
                 && win.canAcquireSleepToken()) {
             mWindowSleepTokenNeeded = true;
         }
@@ -5752,9 +5744,8 @@
                 mStatusBarController.setShowTransparent(true /* transparent */);
             }
 
-            WindowManager.LayoutParams statusBarAttrs = mStatusBar.getAttrs();
-            boolean statusBarExpanded = statusBarAttrs.height == MATCH_PARENT
-                    && statusBarAttrs.width == MATCH_PARENT;
+            boolean statusBarExpanded =
+                    (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_STATUS_BAR_EXPANDED) != 0;
             boolean topAppHidesStatusBar = topAppHidesStatusBar();
             if (mForceStatusBar || mForceStatusBarFromKeyguard || mForceStatusBarTransparent
                     || statusBarExpanded) {
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 4413666..f9f4bbf 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -46,7 +46,6 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.service.trust.TrustAgentService;
 import android.text.TextUtils;
@@ -60,7 +59,6 @@
 import android.view.WindowManagerGlobal;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageMonitor;
-import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.SystemService;
@@ -431,13 +429,20 @@
         for (int i = 0; i < userInfos.size(); i++) {
             UserInfo info = userInfos.get(i);
 
-            if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
-                    || !info.supportsSwitchToByUser()) {
+            if (info == null || info.partial || !info.isEnabled() || info.guestToRemove) {
                 continue;
             }
 
             int id = info.id;
             boolean secure = mLockPatternUtils.isSecure(id);
+
+            if (!info.supportsSwitchToByUser()) {
+                if (info.isManagedProfile() && !secure) {
+                    setDeviceLockedForUser(id, false);
+                }
+                continue;
+            }
+
             boolean trusted = aggregateIsTrusted(id);
             boolean showingKeyguard = true;
             boolean fingerprintAuthenticated = false;
@@ -992,7 +997,8 @@
             enforceReportPermission();
             final long identity = Binder.clearCallingIdentity();
             try {
-                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
+                        && mLockPatternUtils.isSecure(userId)) {
                     synchronized (mDeviceLockedForUser) {
                         mDeviceLockedForUser.put(userId, locked);
                     }
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
index ad92f81..bef974a 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
@@ -69,6 +69,7 @@
                 .setFormat(PixelFormat.TRANSLUCENT)
                 .setMetadata(appToken.windowType,
                         window != null ? window.mOwnerUid : Binder.getCallingUid())
+                .setBufferLayer()
                 .build();
 
         if (SHOW_TRANSACTIONS) {
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index b2a12be..86f328d 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -31,11 +31,13 @@
 import android.os.Debug;
 import android.util.ArrayMap;
 import android.util.Slog;
+import android.view.Choreographer;
 import android.view.animation.AnimationUtils;
 import android.view.animation.Interpolator;
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
@@ -112,6 +114,7 @@
     private final Interpolator mFastOutSlowInInterpolator;
     private boolean mFinishAnimationAfterTransition = false;
     private final AnimationHandler mAnimationHandler;
+    private Choreographer mChoreographer;
 
     private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000;
 
@@ -123,6 +126,12 @@
         mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.fast_out_slow_in);
         mAnimationHandler = animationHandler;
+        if (animationHandler != null) {
+            // If an animation handler is provided, then ensure that it runs on the sf vsync tick
+            handler.runWithScissors(() -> mChoreographer = Choreographer.getSfInstance(),
+                    0 /* timeout */);
+            animationHandler.setProvider(new SfVsyncFrameCallbackProvider(mChoreographer));
+        }
     }
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2887e5ef..6700a12 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -773,7 +773,8 @@
 
         final SurfaceControl.Builder b = mService.makeSurfaceBuilder(mSession)
                 .setSize(mSurfaceSize, mSurfaceSize)
-                .setOpaque(true);
+                .setOpaque(true)
+                .setContainerLayer(true);
         mWindowingLayer = b.setName("Display Root").build();
         mOverlayLayer = b.setName("Display Overlays").build();
 
@@ -1775,8 +1776,9 @@
         final int newDensity = mDisplayInfo.logicalDensityDpi;
         final DisplayCutout newCutout = mDisplayInfo.displayCutout;
 
-        final boolean displayMetricsChanged = mInitialDisplayWidth != newWidth
-                || mInitialDisplayHeight != newHeight
+        final boolean sizeChanged = mInitialDisplayWidth != newWidth
+                || mInitialDisplayHeight != newHeight;
+        final boolean displayMetricsChanged = sizeChanged
                 || mInitialDisplayDensity != mDisplayInfo.logicalDensityDpi
                 || !Objects.equals(mInitialDisplayCutout, newCutout);
 
@@ -1798,6 +1800,10 @@
             mInitialDisplayCutout = newCutout;
             mService.reconfigureDisplayLocked(this);
         }
+
+        if (isDefaultDisplay && sizeChanged) {
+            mService.mH.post(mService.mAmInternal::notifyDefaultDisplaySizeChanged);
+        }
     }
 
     /** Sets the maximum width the screen resolution can be */
@@ -3885,7 +3891,7 @@
         SurfaceSession s = child != null ? child.getSession() : getSession();
         final SurfaceControl.Builder b = mService.makeSurfaceBuilder(s);
         b.setSize(mSurfaceSize, mSurfaceSize);
-
+        b.setContainerLayer(true);
         if (child == null) {
             return b;
         }
diff --git a/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java b/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java
index bebc565..efb43a6 100644
--- a/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java
+++ b/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java
@@ -21,6 +21,7 @@
 
 import android.graphics.Matrix;
 import android.view.DisplayInfo;
+import android.view.Surface.Rotation;
 
 import com.android.server.wm.utils.CoordinateTransforms;
 
@@ -65,6 +66,16 @@
     }
 
     /**
+     * Returns the rotation of the display before it started rotating.
+     *
+     * @return the old rotation of the display
+     */
+    @Rotation
+    public int getOldRotation() {
+        return mOldRotation;
+    }
+
+    /**
      * Removes the transform to the window token's surface that undoes the effect of the global
      * display rotation.
      *
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index fff42c5..8dda485 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -2,6 +2,6 @@
 jjaggi@google.com
 racarr@google.com
 chaviw@google.com
-brycelee@google.com
+vishnun@google.com
 akulian@google.com
 roosa@google.com
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index fa8a5c6..755a571 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -37,6 +37,7 @@
 import android.view.Surface;
 import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
 import android.view.SurfaceSession;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -268,6 +269,12 @@
                     .setSecure(isSecure)
                     .build();
 
+            // In case display bounds change, screenshot buffer and surface may mismatch so set a
+            // scaling mode.
+            Transaction t2 = new Transaction();
+            t2.setOverrideScalingMode(mSurfaceControl, Surface.SCALING_MODE_SCALE_TO_WINDOW);
+            t2.apply(true /* sync */);
+
             // capture a screenshot into the surface we just created
             // TODO(multidisplay): we should use the proper display
             final int displayId = SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index a642e6a..d1c0443 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -360,6 +360,7 @@
 
             // For snapshots with reduced resolution, do not create or save full sized bitmaps
             if (mSnapshot.isReducedResolution()) {
+                swBitmap.recycle();
                 return true;
             }
 
@@ -372,6 +373,8 @@
                 Slog.e(TAG, "Unable to open " + file + " for persisting.", e);
                 return false;
             }
+            reduced.recycle();
+            swBitmap.recycle();
             return true;
         }
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8bc2246..8b4a2dd 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1005,7 +1005,6 @@
         mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier);
 
         final AnimationHandler animationHandler = new AnimationHandler();
-        animationHandler.setProvider(new SfVsyncFrameCallbackProvider());
         mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition,
                 AnimationThread.getHandler(), animationHandler);
 
@@ -6221,6 +6220,17 @@
     }
 
     /**
+     * Returns true if the callingUid has any window currently visible to the user.
+     */
+    public boolean isAnyWindowVisibleForUid(int callingUid) {
+        synchronized (mWindowMap) {
+            return mRoot.forAllWindows(w -> {
+                return w.getOwningUid() == callingUid && w.isVisible();
+            }, true /* traverseTopToBottom */);
+        }
+    }
+
+    /**
      * Called when a task has been removed from the recent tasks list.
      * <p>
      * Note: This doesn't go through {@link TaskWindowContainerController} yet as the window
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 009f393..1ae680f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -681,6 +681,10 @@
 
     void forceSeamlesslyRotateIfAllowed(int oldRotation, int rotation) {
         if (mForceSeamlesslyRotate) {
+            if (mPendingForcedSeamlessRotate != null) {
+                oldRotation = mPendingForcedSeamlessRotate.getOldRotation();
+            }
+
             mPendingForcedSeamlessRotate = new ForcedSeamlessRotator(
                     oldRotation, rotation, getDisplayInfo());
             mPendingForcedSeamlessRotate.unrotate(this.mToken);
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 66c8cca..4548cec 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -104,6 +104,7 @@
 
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
         final SurfaceControl.Builder b = win.makeSurface()
+                .setBufferLayer()
                 .setParent(win.getSurfaceControl())
                 .setName(name)
                 .setSize(w, h)
diff --git a/services/core/java/com/android/server/wm/utils/InsetUtils.java b/services/core/java/com/android/server/wm/utils/InsetUtils.java
index b4a998a..c8600dd 100644
--- a/services/core/java/com/android/server/wm/utils/InsetUtils.java
+++ b/services/core/java/com/android/server/wm/utils/InsetUtils.java
@@ -17,6 +17,7 @@
 package com.android.server.wm.utils;
 
 import android.graphics.Rect;
+import android.view.Surface;
 
 /**
  * Utility methods to handle insets represented as rects.
@@ -27,6 +28,32 @@
     }
 
     /**
+     * Transforms insets given in one rotation into insets in a different rotation.
+     *
+     * @param inOutInsets the insets to transform, is set to the transformed insets
+     * @param rotationDelta the delta between the new and old rotation.
+     *                      Must be one of Surface.ROTATION_0/90/180/270.
+     */
+    public static void rotateInsets(Rect inOutInsets, int rotationDelta) {
+        final Rect r = inOutInsets;
+        switch (rotationDelta) {
+            case Surface.ROTATION_0:
+                return;
+            case Surface.ROTATION_90:
+                r.set(r.top, r.right, r.bottom, r.left);
+                break;
+            case Surface.ROTATION_180:
+                r.set(r.right, r.bottom, r.left, r.top);
+                break;
+            case Surface.ROTATION_270:
+                r.set(r.bottom, r.left, r.top, r.right);
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown rotation: " + rotationDelta);
+        }
+    }
+
+    /**
      * Adds {@code insetsToAdd} to {@code inOutInsets}.
      */
     public static void addInsets(Rect inOutInsets, Rect insetsToAdd) {
diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
index 649f1a5..4d4a7b4 100644
--- a/services/core/jni/com_android_server_net_NetworkStatsService.cpp
+++ b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
@@ -34,7 +34,6 @@
 #include "netdbpf/BpfNetworkStats.h"
 
 using android::bpf::Stats;
-using android::bpf::hasBpfSupport;
 using android::bpf::bpfGetUidStats;
 using android::bpf::bpfGetIfaceStats;
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 123d615..8f5d36a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4572,10 +4572,12 @@
         enforceFullCrossUsersPermission(userHandle);
         synchronized (getLockObject()) {
             if (!isCallerWithSystemUid()) {
-                // This API can only be called by an active device admin,
-                // so try to retrieve it to check that the caller is one.
-                getActiveAdminForCallerLocked(
-                        null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+                // This API can be called by an active device admin or by keyguard code.
+                if (mContext.checkCallingPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE)
+                        != PackageManager.PERMISSION_GRANTED) {
+                    getActiveAdminForCallerLocked(
+                            null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent);
+                }
             }
 
             DevicePolicyData policy = getUserDataUnchecked(getCredentialOwner(userHandle, parent));
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 80b0e6f..2d07fd6 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -29,6 +29,7 @@
 import android.content.res.Resources.Theme;
 import android.database.sqlite.SQLiteCompatibilityWalFlags;
 import android.database.sqlite.SQLiteGlobal;
+import android.hardware.display.DisplayManagerInternal;
 import android.os.BaseBundle;
 import android.os.Binder;
 import android.os.Build;
@@ -48,6 +49,7 @@
 import android.os.Trace;
 import android.os.UserHandle;
 import android.os.storage.IStorageManager;
+import android.sysprop.VoldProperties;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Slog;
@@ -625,7 +627,7 @@
         traceEnd();
 
         // Only run "core" apps if we're encrypting the device.
-        String cryptState = SystemProperties.get("vold.decrypt");
+        String cryptState = VoldProperties.decrypt().orElse("");
         if (ENCRYPTING_STATE.equals(cryptState)) {
             Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
             mOnlyCore = true;
@@ -687,9 +689,17 @@
 
         // Manages Overlay packages
         traceBeginAndSlog("StartOverlayManagerService");
-        mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
+        OverlayManagerService overlayManagerService = new OverlayManagerService(
+                mSystemContext, installer);
+        mSystemServiceManager.startService(overlayManagerService);
         traceEnd();
 
+        if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) {
+            // DisplayManager needs the overlay immediately.
+            overlayManagerService.updateSystemUiContext();
+            LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged();
+        }
+
         // The sensor service needs access to package manager service, app ops
         // service, and permissions service, therefore we start it after them.
         // Start sensor service in a separate thread. Completion should be checked
@@ -1194,6 +1204,16 @@
             }
             traceEnd();
 
+            traceBeginAndSlog("StartNetworkStack");
+            try {
+                final android.net.NetworkStack networkStack =
+                        context.getSystemService(android.net.NetworkStack.class);
+                networkStack.start(context);
+            } catch (Throwable e) {
+                reportWtf("starting Network Stack", e);
+            }
+            traceEnd();
+
             traceBeginAndSlog("StartNsdService");
             try {
                 serviceDiscovery = NsdService.create(context);
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index a7209a0..f037905 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -111,7 +111,7 @@
      * the last writable 32bit word.
      */
     @VisibleForTesting
-    private static enum Counter {
+    public static enum Counter {
         RESERVED_OOB,  // Points to offset 0 from the end of the buffer (out-of-bounds)
         TOTAL_PACKETS,
         PASSED_ARP,
@@ -139,7 +139,8 @@
         DROPPED_IPV6_MULTICAST_PING,
         DROPPED_IPV6_NON_ICMP_MULTICAST,
         DROPPED_802_3_FRAME,
-        DROPPED_ETHERTYPE_BLACKLISTED;
+        DROPPED_ETHERTYPE_BLACKLISTED,
+        DROPPED_ARP_REPLY_SPA_NO_HOST;
 
         // Returns the negative byte offset from the end of the APF data segment for
         // a given counter.
@@ -156,7 +157,7 @@
     /**
      * When APFv4 is supported, loads R1 with the offset of the specified counter.
      */
-    private void maybeSetCounter(ApfGenerator gen, Counter c) {
+    private void maybeSetupCounter(ApfGenerator gen, Counter c) {
         if (mApfCapabilities.hasDataAccess()) {
             gen.addLoadImmediate(Register.R1, c.offset());
         }
@@ -288,16 +289,18 @@
     private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
 
     private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN;
-    private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
-    private static final short ARP_OPCODE_REQUEST = 1;
-    private static final short ARP_OPCODE_REPLY = 2;
     private static final byte[] ARP_IPV4_HEADER = {
             0, 1, // Hardware type: Ethernet (1)
             8, 0, // Protocol type: IP (0x0800)
             6,    // Hardware size: 6
             4,    // Protocol size: 4
     };
-    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24;
+    private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
+    // Opcode: ARP request (0x0001), ARP reply (0x0002)
+    private static final short ARP_OPCODE_REQUEST = 1;
+    private static final short ARP_OPCODE_REPLY = 2;
+    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
+    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
     // Do not log ApfProgramEvents whose actual lifetimes was less than this.
     private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2;
     // Limit on the Black List size to cap on program usage for this
@@ -816,7 +819,7 @@
                     gen.addJumpIfR0LessThan(filterLifetime, nextFilterLabel);
                 }
             }
-            maybeSetCounter(gen, Counter.DROPPED_RA);
+            maybeSetupCounter(gen, Counter.DROPPED_RA);
             gen.addJump(mCountAndDropLabel);
             gen.defineLabel(nextFilterLabel);
             return filterLifetime;
@@ -883,6 +886,8 @@
         //   pass
         // if not ARP IPv4 reply or request
         //   pass
+        // if ARP reply source ip is 0.0.0.0
+        //   drop
         // if unicast ARP reply
         //   pass
         // if interface has no IPv4 address
@@ -897,18 +902,23 @@
 
         // Pass if not ARP IPv4.
         gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
-        maybeSetCounter(gen, Counter.PASSED_ARP_NON_IPV4);
+        maybeSetupCounter(gen, Counter.PASSED_ARP_NON_IPV4);
         gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, mCountAndPassLabel);
 
         // Pass if unknown ARP opcode.
         gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET);
         gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check
-        maybeSetCounter(gen, Counter.PASSED_ARP_UNKNOWN);
+        maybeSetupCounter(gen, Counter.PASSED_ARP_UNKNOWN);
         gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndPassLabel);
 
+        // Drop if ARP reply source IP is 0.0.0.0
+        gen.addLoad32(Register.R0, ARP_SOURCE_IP_ADDRESS_OFFSET);
+        maybeSetupCounter(gen, Counter.DROPPED_ARP_REPLY_SPA_NO_HOST);
+        gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
+
         // Pass if unicast reply.
         gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        maybeSetCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
+        maybeSetupCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
         gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
 
         // Either a unicast request, a unicast reply, or a broadcast reply.
@@ -916,17 +926,17 @@
         if (mIPv4Address == null) {
             // When there is no IPv4 address, drop GARP replies (b/29404209).
             gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            maybeSetCounter(gen, Counter.DROPPED_GARP_REPLY);
+            maybeSetupCounter(gen, Counter.DROPPED_GARP_REPLY);
             gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
         } else {
             // When there is an IPv4 address, drop unicast/broadcast requests
             // and broadcast replies with a different target IPv4 address.
             gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
-            maybeSetCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
+            maybeSetupCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
             gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, mCountAndDropLabel);
         }
 
-        maybeSetCounter(gen, Counter.PASSED_ARP);
+        maybeSetupCounter(gen, Counter.PASSED_ARP);
         gen.addJump(mCountAndPassLabel);
     }
 
@@ -970,7 +980,7 @@
             // NOTE: Relies on R1 containing IPv4 header offset.
             gen.addAddR1();
             gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, skipDhcpv4Filter);
-            maybeSetCounter(gen, Counter.PASSED_DHCP);
+            maybeSetupCounter(gen, Counter.PASSED_DHCP);
             gen.addJump(mCountAndPassLabel);
 
             // Drop all multicasts/broadcasts.
@@ -979,30 +989,30 @@
             // If IPv4 destination address is in multicast range, drop.
             gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
             gen.addAnd(0xf0);
-            maybeSetCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
+            maybeSetupCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
             gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel);
 
             // If IPv4 broadcast packet, drop regardless of L2 (b/30231088).
-            maybeSetCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
+            maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
             gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET);
             gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel);
             if (mIPv4Address != null && mIPv4PrefixLength < 31) {
-                maybeSetCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
+                maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
                 int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength);
                 gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
             }
 
             // If L2 broadcast packet, drop.
             // TODO: can we invert this condition to fall through to the common pass case below?
-            maybeSetCounter(gen, Counter.PASSED_IPV4_UNICAST);
+            maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST);
             gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
             gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-            maybeSetCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
+            maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
             gen.addJump(mCountAndDropLabel);
         }
 
         // Otherwise, pass
-        maybeSetCounter(gen, Counter.PASSED_IPV4);
+        maybeSetupCounter(gen, Counter.PASSED_IPV4);
         gen.addJump(mCountAndPassLabel);
     }
 
@@ -1050,16 +1060,16 @@
 
             // Drop all other packets sent to ff00::/8 (multicast prefix).
             gen.defineLabel(dropAllIPv6MulticastsLabel);
-            maybeSetCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
+            maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
             gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET);
             gen.addJumpIfR0Equals(0xff, mCountAndDropLabel);
             // Not multicast. Pass.
-            maybeSetCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
+            maybeSetupCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
             gen.addJump(mCountAndPassLabel);
             gen.defineLabel(skipIPv6MulticastFilterLabel);
         } else {
             // If not ICMPv6, pass.
-            maybeSetCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
+            maybeSetupCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
             gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel);
         }
 
@@ -1069,7 +1079,7 @@
         String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
         gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
         // Drop all router solicitations (b/32833400)
-        maybeSetCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
+        maybeSetupCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
         gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel);
         // If not neighbor announcements, skip filter.
         gen.addJumpIfR0NotEquals(ICMPV6_NEIGHBOR_ADVERTISEMENT, skipUnsolicitedMulticastNALabel);
@@ -1078,7 +1088,7 @@
         gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
         gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
                 skipUnsolicitedMulticastNALabel);
-        maybeSetCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
+        maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
         gen.addJump(mCountAndDropLabel);
         gen.defineLabel(skipUnsolicitedMulticastNALabel);
     }
@@ -1108,7 +1118,7 @@
 
         if (mApfCapabilities.hasDataAccess()) {
             // Increment TOTAL_PACKETS
-            maybeSetCounter(gen, Counter.TOTAL_PACKETS);
+            maybeSetupCounter(gen, Counter.TOTAL_PACKETS);
             gen.addLoadData(Register.R0, 0);  // load counter
             gen.addAdd(1);
             gen.addStoreData(Register.R0, 0);  // write-back counter
@@ -1134,12 +1144,12 @@
 
         if (mDrop802_3Frames) {
             // drop 802.3 frames (ethtype < 0x0600)
-            maybeSetCounter(gen, Counter.DROPPED_802_3_FRAME);
+            maybeSetupCounter(gen, Counter.DROPPED_802_3_FRAME);
             gen.addJumpIfR0LessThan(ETH_TYPE_MIN, mCountAndDropLabel);
         }
 
         // Handle ether-type black list
-        maybeSetCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
+        maybeSetupCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
         for (int p : mEthTypeBlackList) {
             gen.addJumpIfR0Equals(p, mCountAndDropLabel);
         }
@@ -1168,9 +1178,9 @@
 
         // Drop non-IP non-ARP broadcasts, pass the rest
         gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
-        maybeSetCounter(gen, Counter.PASSED_NON_IP_UNICAST);
+        maybeSetupCounter(gen, Counter.PASSED_NON_IP_UNICAST);
         gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
-        maybeSetCounter(gen, Counter.DROPPED_ETH_BROADCAST);
+        maybeSetupCounter(gen, Counter.DROPPED_ETH_BROADCAST);
         gen.addJump(mCountAndDropLabel);
 
         // Add IPv6 filters:
@@ -1193,7 +1203,7 @@
 
         // Execution will reach the bottom of the program if none of the filters match,
         // which will pass the packet to the application processor.
-        maybeSetCounter(gen, Counter.PASSED_IPV6_ICMP);
+        maybeSetupCounter(gen, Counter.PASSED_IPV6_ICMP);
 
         // Append the count & pass trampoline, which increments the counter at the data address
         // pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting
diff --git a/services/net/java/android/net/dhcp/DhcpServer.java b/services/net/java/android/net/dhcp/DhcpServer.java
index cee6fa9..35d29e7 100644
--- a/services/net/java/android/net/dhcp/DhcpServer.java
+++ b/services/net/java/android/net/dhcp/DhcpServer.java
@@ -39,7 +39,6 @@
 import android.net.MacAddress;
 import android.net.NetworkUtils;
 import android.net.TrafficStats;
-import android.net.util.InterfaceParams;
 import android.net.util.SharedLog;
 import android.os.Handler;
 import android.os.Looper;
@@ -85,7 +84,7 @@
     @NonNull
     private final ServerHandler mHandler;
     @NonNull
-    private final InterfaceParams mIface;
+    private final String mIfName;
     @NonNull
     private final DhcpLeaseRepository mLeaseRepo;
     @NonNull
@@ -161,20 +160,20 @@
         }
     }
 
-    public DhcpServer(@NonNull Looper looper, @NonNull InterfaceParams iface,
+    public DhcpServer(@NonNull Looper looper, @NonNull String ifName,
             @NonNull DhcpServingParams params, @NonNull SharedLog log) {
-        this(looper, iface, params, log, null);
+        this(looper, ifName, params, log, null);
     }
 
     @VisibleForTesting
-    DhcpServer(@NonNull Looper looper, @NonNull InterfaceParams iface,
+    DhcpServer(@NonNull Looper looper, @NonNull String ifName,
             @NonNull DhcpServingParams params, @NonNull SharedLog log,
             @Nullable Dependencies deps) {
         if (deps == null) {
             deps = new DependenciesImpl();
         }
         mHandler = new ServerHandler(looper);
-        mIface = iface;
+        mIfName = ifName;
         mServingParams = params;
         mLog = log;
         mDeps = deps;
@@ -444,7 +443,7 @@
 
     private boolean addArpEntry(@NonNull MacAddress macAddr, @NonNull Inet4Address inetAddr) {
         try {
-            mDeps.addArpEntry(inetAddr, macAddr, mIface.name, mSocket);
+            mDeps.addArpEntry(inetAddr, macAddr, mIfName, mSocket);
             return true;
         } catch (IOException e) {
             mLog.e("Error adding client to ARP table", e);
@@ -526,7 +525,7 @@
                 // SO_BINDTODEVICE actually takes a string. This works because the first member
                 // of struct ifreq is a NULL-terminated interface name.
                 // TODO: add a setsockoptString()
-                Os.setsockoptIfreq(mSocket, SOL_SOCKET, SO_BINDTODEVICE, mIface.name);
+                Os.setsockoptIfreq(mSocket, SOL_SOCKET, SO_BINDTODEVICE, mIfName);
                 Os.setsockoptInt(mSocket, SOL_SOCKET, SO_BROADCAST, 1);
                 Os.bind(mSocket, Inet4Address.ANY, DHCP_SERVER);
                 NetworkUtils.protectFromVpn(mSocket);
diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java
index 823c0a1..493350d 100644
--- a/services/net/java/android/net/ip/IpServer.java
+++ b/services/net/java/android/net/ip/IpServer.java
@@ -138,9 +138,9 @@
             return NetdService.getInstance();
         }
 
-        public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface,
+        public DhcpServer makeDhcpServer(Looper looper, String ifName,
                 DhcpServingParams params, SharedLog log) {
-            return new DhcpServer(looper, iface, params, log);
+            return new DhcpServer(looper, ifName, params, log);
         }
     }
 
@@ -256,12 +256,6 @@
         if (mUsingLegacyDhcp) {
             return true;
         }
-
-        final InterfaceParams ifaceParams = mDeps.getInterfaceParams(mIfaceName);
-        if (ifaceParams == null) {
-            Log.e(TAG, "Failed to find interface params for DHCPv4");
-            return false;
-        }
         final DhcpServingParams params;
         try {
             params = new DhcpServingParams.Builder()
@@ -277,7 +271,7 @@
             return false;
         }
 
-        mDhcpServer = mDeps.makeDhcpServer(getHandler().getLooper(), ifaceParams, params,
+        mDhcpServer = mDeps.makeDhcpServer(getHandler().getLooper(), mIfaceName, params,
                 mLog.forSubComponent("DHCP"));
         mDhcpServer.start();
         return true;
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index af8596d..d2d6e32 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -67,7 +67,7 @@
         "liblzma",
         "libnativehelper",
         "libui",
-        "libunwind",
+        "libunwindstack",
         "libutils",
         "netd_aidl_interface-cpp",
     ],
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index 1520859..8d056fc 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -53,6 +53,7 @@
 import org.junit.runner.RunWith;
 import org.junit.Test;
 
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
 import static com.android.server.am.ActivityManagerService.ANIMATE;
 
@@ -62,11 +63,13 @@
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyObject;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.times;
@@ -91,6 +94,7 @@
     private ActivityManagerService mService;
     private ActivityStarter mStarter;
     private ActivityStartController mController;
+    private ActivityMetricsLogger mActivityMetricsLogger;
 
     private static final int PRECONDITION_NO_CALLER_APP = 1;
     private static final int PRECONDITION_NO_INTENT_COMPONENT = 1 << 1;
@@ -104,11 +108,17 @@
     private static final int PRECONDITION_CANNOT_START_ANY_ACTIVITY = 1 << 9;
     private static final int PRECONDITION_DISALLOW_APP_SWITCHING = 1 << 10;
 
+    private static final int FAKE_CALLING_UID = 666;
+    private static final int FAKE_REAL_CALLING_UID = 667;
+    private static final String FAKE_CALLING_PACKAGE = "com.whatever.dude";
+
     @Override
     public void setUp() throws Exception {
         super.setUp();
         mService = createActivityManagerService();
         mController = mock(ActivityStartController.class);
+        mActivityMetricsLogger = mock(ActivityMetricsLogger.class);
+        clearInvocations(mActivityMetricsLogger);
         mStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor,
                 mock(ActivityStartInterceptor.class));
     }
@@ -471,4 +481,46 @@
             assertTrue(stack.getAllTasks().isEmpty());
         }
     }
+
+    /**
+     * This test ensures that activity starts are not being logged when the logging is disabled.
+     */
+    @Test
+    public void testActivityStartsLogging_noLoggingWhenDisabled() {
+        doReturn(false).when(mService).isActivityStartsLoggingEnabled();
+        doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger();
+
+        ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK);
+        starter.setReason("testActivityStartsLogging_noLoggingWhenDisabled").execute();
+
+        // verify logging wasn't done
+        verify(mActivityMetricsLogger, never()).logActivityStart(any(), any(), any(), anyInt(),
+                any(), anyInt(), anyBoolean(), anyInt(), anyInt(), anyBoolean(), anyInt(), any(),
+                anyInt(), anyBoolean(), any(), anyBoolean());
+    }
+
+    /**
+     * This test ensures that activity starts are being logged when the logging is enabled.
+     */
+    @Test
+    public void testActivityStartsLogging_logsWhenEnabled() {
+        // note: conveniently this package doesn't have any activity visible
+        doReturn(true).when(mService).isActivityStartsLoggingEnabled();
+        doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger();
+
+        ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK)
+                .setCallingUid(FAKE_CALLING_UID)
+                .setRealCallingUid(FAKE_REAL_CALLING_UID)
+                .setCallingPackage(FAKE_CALLING_PACKAGE)
+                .setOriginatingPendingIntent(null);
+
+        starter.setReason("testActivityStartsLogging_logsWhenEnabled").execute();
+
+        // verify the above activity start was logged
+        verify(mActivityMetricsLogger, times(1)).logActivityStart(any(), any(), any(),
+                eq(FAKE_CALLING_UID), eq(FAKE_CALLING_PACKAGE), anyInt(), anyBoolean(),
+                eq(FAKE_REAL_CALLING_UID), anyInt(), anyBoolean(), anyInt(),
+                eq(ActivityBuilder.getDefaultComponent().getPackageName()), anyInt(), anyBoolean(),
+                any(), eq(false));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java
index d0f0fe3..08bcc3d 100644
--- a/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java
@@ -16,6 +16,11 @@
 
 package com.android.server.wm.utils;
 
+import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+
 import static junit.framework.Assert.assertEquals;
 
 import android.graphics.Rect;
@@ -39,5 +44,29 @@
         InsetUtils.addInsets(rect1, rect2);
         assertEquals(new Rect(60, 80, 100, 120), rect1);
     }
+
+    @Test
+    public void rotate() {
+        final Rect original = new Rect(1, 2, 3, 4);
+
+        assertEquals("rot0", original, rotateCopy(original, ROTATION_0));
+
+        final Rect rot90 = rotateCopy(original, ROTATION_90);
+        assertEquals("rot90", new Rect(2, 3, 4, 1), rot90);
+
+        final Rect rot180 = rotateCopy(original, ROTATION_180);
+        assertEquals("rot180", new Rect(3, 4, 1, 2), rot180);
+        assertEquals("rot90(rot90)=rot180", rotateCopy(rot90, ROTATION_90), rot180);
+
+        final Rect rot270 = rotateCopy(original, ROTATION_270);
+        assertEquals("rot270", new Rect(4, 1, 2, 3), rot270);
+        assertEquals("rot90(rot180)=rot270", rotateCopy(rot180, ROTATION_90), rot270);
+    }
+
+    private static Rect rotateCopy(Rect insets, int rotationDelta) {
+        final Rect copy = new Rect(insets);
+        InsetUtils.rotateInsets(copy, rotationDelta);
+        return copy;
+    }
 }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index afc1263..8222c38 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -38,6 +38,7 @@
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.NotificationManager;
 import android.content.ComponentName;
@@ -49,8 +50,10 @@
 import android.media.AudioManagerInternal;
 import android.media.VolumePolicy;
 import android.media.AudioSystem;
+import android.net.Uri;
 import android.provider.Settings;
 import android.provider.Settings.Global;
+import android.service.notification.Condition;
 import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenModeConfig.ScheduleInfo;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -61,6 +64,7 @@
 
 import com.android.internal.R;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.server.notification.ManagedServices.UserProfiles;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.server.UiServiceTestCase;
 import android.util.Slog;
@@ -83,7 +87,7 @@
 @TestableLooper.RunWithLooper
 public class ZenModeHelperTest extends UiServiceTestCase {
 
-    @Mock ConditionProviders mConditionProviders;
+    ConditionProviders mConditionProviders;
     @Mock NotificationManager mNotificationManager;
     @Mock private Resources mResources;
     private TestableLooper mTestableLooper;
@@ -103,6 +107,9 @@
         when(mResources.getString(R.string.zen_mode_default_events_name)).thenReturn("events");
         when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager);
 
+        mConditionProviders = new ConditionProviders(mContext, new UserProfiles(),
+                AppGlobals.getPackageManager());
+        mConditionProviders.addSystemProvider(new CountdownConditionProvider());
         mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(),
                 mConditionProviders));
     }
@@ -116,7 +123,7 @@
         mZenModeHelperSpy.writeXml(serializer, forBackup, version);
         serializer.endDocument();
         serializer.flush();
-        mZenModeHelperSpy.setConfig(new ZenModeConfig(), "writing xml");
+        mZenModeHelperSpy.setConfig(new ZenModeConfig(), null, "writing xml");
         return baos;
     }
 
@@ -813,6 +820,30 @@
         setupZenConfigMaintained();
     }
 
+    @Test
+    public void testCountdownConditionSubscription() throws Exception {
+        ZenModeConfig config = new ZenModeConfig();
+        mZenModeHelperSpy.mConfig = config;
+        mZenModeHelperSpy.mConditions.evaluateConfig(mZenModeHelperSpy.mConfig, null, true);
+        assertEquals(0, mZenModeHelperSpy.mConditions.mSubscriptions.size());
+
+        mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule();
+        Uri conditionId = ZenModeConfig.toCountdownConditionId(9000000, false);
+        mZenModeHelperSpy.mConfig.manualRule.conditionId = conditionId;
+        mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("android",
+                CountdownConditionProvider.class.getName());
+        mZenModeHelperSpy.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0,
+                Condition.STATE_TRUE, Condition.FLAG_RELEVANT_NOW);
+        mZenModeHelperSpy.mConfig.manualRule.enabled = true;
+        ZenModeConfig originalConfig = mZenModeHelperSpy.mConfig.copy();
+
+        mZenModeHelperSpy.mConditions.evaluateConfig(mZenModeHelperSpy.mConfig, null, true);
+
+        assertEquals(true, ZenModeConfig.isValidCountdownConditionId(conditionId));
+        assertEquals(originalConfig, mZenModeHelperSpy.mConfig);
+        assertEquals(1, mZenModeHelperSpy.mConditions.mSubscriptions.size());
+    }
+
     private void setupZenConfig() {
         mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         mZenModeHelperSpy.mConfig.allowAlarms = false;
diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
index 3b08505..4239099 100644
--- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
@@ -34,10 +34,10 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.service.usb.UsbDebuggingManagerProto;
+import android.sysprop.VoldProperties;
 import android.util.Base64;
 import android.util.Slog;
 
@@ -263,7 +263,7 @@
 
                 case MESSAGE_ADB_CONFIRM: {
                     if ("trigger_restart_min_framework".equals(
-                            SystemProperties.get("vold.decrypt"))) {
+                            VoldProperties.decrypt().orElse(""))) {
                         Slog.d(TAG, "Deferring adb confirmation until after vold decrypt");
                         if (mThread != null) {
                             mThread.sendResponse("NO");
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 4da7285..aa93c6b 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -69,6 +69,7 @@
 import android.provider.Settings;
 import android.service.usb.UsbDeviceManagerProto;
 import android.service.usb.UsbHandlerProto;
+import android.sysprop.VoldProperties;
 import android.util.Pair;
 import android.util.Slog;
 
@@ -285,7 +286,7 @@
         mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd);
 
         boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);
-        boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt"));
+        boolean dataEncrypted = "1".equals(VoldProperties.decrypt().orElse(""));
         if (secureAdbEnabled && !dataEncrypted) {
             mDebuggingManager = new UsbDebuggingManager(context);
         }
diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp
index de40e0d..91cec554 100644
--- a/startop/view_compiler/Android.bp
+++ b/startop/view_compiler/Android.bp
@@ -24,6 +24,9 @@
         "libdexfile",
         "slicer",
     ],
+    static_libs: [
+        "libtinyxml2",
+    ],
 }
 
 cc_library_host_static {
@@ -32,7 +35,9 @@
     srcs: [
         "dex_builder.cc",
         "java_lang_builder.cc",
+        "tinyxml_layout_parser.cc",
         "util.cc",
+        "layout_validation.cc",
     ],
 }
 
@@ -43,7 +48,6 @@
         "main.cc",
     ],
     static_libs: [
-        "libtinyxml2",
         "libgflags",
         "libviewcompiler",
     ],
@@ -54,6 +58,7 @@
     defaults: ["viewcompiler_defaults"],
     srcs: [
         "dex_builder_test.cc",
+        "layout_validation_test.cc",
         "util_test.cc",
     ],
     static_libs: [
diff --git a/telephony/java/android/telephony/rcs/RcsThread.aidl b/startop/view_compiler/config.xml
similarity index 67%
copy from telephony/java/android/telephony/rcs/RcsThread.aidl
copy to startop/view_compiler/config.xml
index e2e0da5d..84e779d 100644
--- a/telephony/java/android/telephony/rcs/RcsThread.aidl
+++ b/startop/view_compiler/config.xml
@@ -1,5 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
 /*
-**
 ** Copyright 2018, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +15,11 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
+-->
 
-package android.telephony;
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
-parcelable RcsThread;
\ No newline at end of file
+    <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). -->
+    <bool name="config_safe_media_disable_on_volume_up">false</bool>
+
+</resources>
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index 906d64c..a78f7d5 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -61,18 +61,49 @@
     case Instruction::Op::kInvokeDirect:
       out << "kInvokeDirect";
       return out;
+    case Instruction::Op::kInvokeStatic:
+      out << "kInvokeStatic";
+      return out;
+    case Instruction::Op::kInvokeInterface:
+      out << "kInvokeInterface";
+      return out;
     case Instruction::Op::kBindLabel:
       out << "kBindLabel";
       return out;
     case Instruction::Op::kBranchEqz:
       out << "kBranchEqz";
       return out;
+    case Instruction::Op::kBranchNEqz:
+      out << "kBranchNEqz";
+      return out;
     case Instruction::Op::kNew:
       out << "kNew";
       return out;
+    case Instruction::Op::kCheckCast:
+      out << "kCheckCast";
+      return out;
   }
 }
 
+std::ostream& operator<<(std::ostream& out, const Value& value) {
+  if (value.is_register()) {
+    out << "Register(" << value.value() << ")";
+  } else if (value.is_parameter()) {
+    out << "Parameter(" << value.value() << ")";
+  } else if (value.is_immediate()) {
+    out << "Immediate(" << value.value() << ")";
+  } else if (value.is_string()) {
+    out << "String(" << value.value() << ")";
+  } else if (value.is_label()) {
+    out << "Label(" << value.value() << ")";
+  } else if (value.is_type()) {
+    out << "Type(" << value.value() << ")";
+  } else {
+    out << "UnknownValue";
+  }
+  return out;
+}
+
 void* TrackingAllocator::Allocate(size_t size) {
   std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
   void* raw_buffer = buffer.get();
@@ -289,12 +320,20 @@
       return EncodeInvoke(instruction, art::Instruction::INVOKE_VIRTUAL);
     case Instruction::Op::kInvokeDirect:
       return EncodeInvoke(instruction, art::Instruction::INVOKE_DIRECT);
+    case Instruction::Op::kInvokeStatic:
+      return EncodeInvoke(instruction, art::Instruction::INVOKE_STATIC);
+    case Instruction::Op::kInvokeInterface:
+      return EncodeInvoke(instruction, art::Instruction::INVOKE_INTERFACE);
     case Instruction::Op::kBindLabel:
       return BindLabel(instruction.args()[0]);
     case Instruction::Op::kBranchEqz:
       return EncodeBranch(art::Instruction::IF_EQZ, instruction);
+    case Instruction::Op::kBranchNEqz:
+      return EncodeBranch(art::Instruction::IF_NEZ, instruction);
     case Instruction::Op::kNew:
       return EncodeNew(instruction);
+    case Instruction::Op::kCheckCast:
+      return EncodeCast(instruction);
   }
 }
 
@@ -353,7 +392,9 @@
 
   // If there is a return value, add a move-result instruction
   if (instruction.dest().has_value()) {
-    Encode11x(art::Instruction::MOVE_RESULT, RegisterValue(*instruction.dest()));
+    Encode11x(instruction.result_is_object() ? art::Instruction::MOVE_RESULT_OBJECT
+                                             : art::Instruction::MOVE_RESULT,
+              RegisterValue(*instruction.dest()));
   }
 
   max_args_ = std::max(max_args_, instruction.args().size());
@@ -386,6 +427,18 @@
   Encode21c(::art::Instruction::NEW_INSTANCE, RegisterValue(*instruction.dest()), type.value());
 }
 
+void MethodBuilder::EncodeCast(const Instruction& instruction) {
+  DCHECK_EQ(Instruction::Op::kCheckCast, instruction.opcode());
+  DCHECK(instruction.dest().has_value());
+  DCHECK(instruction.dest()->is_variable());
+  DCHECK_EQ(1, instruction.args().size());
+
+  const Value& type = instruction.args()[0];
+  DCHECK_LT(RegisterValue(*instruction.dest()), 256);
+  DCHECK(type.is_type());
+  Encode21c(::art::Instruction::CHECK_CAST, RegisterValue(*instruction.dest()), type.value());
+}
+
 size_t MethodBuilder::RegisterValue(const Value& value) const {
   if (value.is_register()) {
     return value.value();
@@ -447,7 +500,7 @@
     auto& ir_node = dex_file_->methods_map[new_index];
     SLICER_CHECK(ir_node == nullptr);
     ir_node = decl;
-    decl->orig_index = new_index;
+    decl->orig_index = decl->index = new_index;
 
     entry = {id, decl};
   }
diff --git a/startop/view_compiler/dex_builder.h b/startop/view_compiler/dex_builder.h
index adf82bf..757d863 100644
--- a/startop/view_compiler/dex_builder.h
+++ b/startop/view_compiler/dex_builder.h
@@ -73,7 +73,7 @@
   bool operator<(const TypeDescriptor& rhs) const { return descriptor_ < rhs.descriptor_; }
 
  private:
-  TypeDescriptor(std::string descriptor) : descriptor_{descriptor} {}
+  explicit TypeDescriptor(std::string descriptor) : descriptor_{descriptor} {}
 
   const std::string descriptor_;
 };
@@ -83,7 +83,7 @@
 class Prototype {
  public:
   template <typename... TypeDescriptors>
-  Prototype(TypeDescriptor return_type, TypeDescriptors... param_types)
+  explicit Prototype(TypeDescriptor return_type, TypeDescriptors... param_types)
       : return_type_{return_type}, param_types_{param_types...} {}
 
   // Encode this prototype into the dex file.
@@ -142,14 +142,18 @@
   // The operation performed by this instruction. These are virtual instructions that do not
   // correspond exactly to DEX instructions.
   enum class Op {
-    kReturn,
-    kReturnObject,
-    kMove,
-    kInvokeVirtual,
-    kInvokeDirect,
     kBindLabel,
     kBranchEqz,
-    kNew
+    kBranchNEqz,
+    kCheckCast,
+    kInvokeDirect,
+    kInvokeInterface,
+    kInvokeStatic,
+    kInvokeVirtual,
+    kMove,
+    kNew,
+    kReturn,
+    kReturnObject,
   };
 
   ////////////////////////
@@ -163,19 +167,60 @@
   // For most instructions, which take some number of arguments and have an optional return value.
   template <typename... T>
   static inline Instruction OpWithArgs(Op opcode, std::optional<const Value> dest, T... args) {
-    return Instruction{opcode, /*method_id*/ 0, dest, args...};
+    return Instruction{opcode, /*method_id=*/0, /*result_is_object=*/false, dest, args...};
   }
+
+  // A cast instruction. Basically, `(type)val`
+  static inline Instruction Cast(Value val, Value type) {
+    DCHECK(type.is_type());
+    return OpWithArgs(Op::kCheckCast, val, type);
+  }
+
   // For method calls.
   template <typename... T>
   static inline Instruction InvokeVirtual(size_t method_id, std::optional<const Value> dest,
                                           Value this_arg, T... args) {
-    return Instruction{Op::kInvokeVirtual, method_id, dest, this_arg, args...};
+    return Instruction{
+        Op::kInvokeVirtual, method_id, /*result_is_object=*/false, dest, this_arg, args...};
+  }
+  // Returns an object
+  template <typename... T>
+  static inline Instruction InvokeVirtualObject(size_t method_id, std::optional<const Value> dest,
+                                                Value this_arg, T... args) {
+    return Instruction{
+        Op::kInvokeVirtual, method_id, /*result_is_object=*/true, dest, this_arg, args...};
   }
   // For direct calls (basically, constructors).
   template <typename... T>
   static inline Instruction InvokeDirect(size_t method_id, std::optional<const Value> dest,
                                          Value this_arg, T... args) {
-    return Instruction{Op::kInvokeDirect, method_id, dest, this_arg, args...};
+    return Instruction{
+        Op::kInvokeDirect, method_id, /*result_is_object=*/false, dest, this_arg, args...};
+  }
+  // Returns an object
+  template <typename... T>
+  static inline Instruction InvokeDirectObject(size_t method_id, std::optional<const Value> dest,
+                                               Value this_arg, T... args) {
+    return Instruction{
+        Op::kInvokeDirect, method_id, /*result_is_object=*/true, dest, this_arg, args...};
+  }
+  // For static calls.
+  template <typename... T>
+  static inline Instruction InvokeStatic(size_t method_id, std::optional<const Value> dest,
+                                         T... args) {
+    return Instruction{Op::kInvokeStatic, method_id, /*result_is_object=*/false, dest, args...};
+  }
+  // Returns an object
+  template <typename... T>
+  static inline Instruction InvokeStaticObject(size_t method_id, std::optional<const Value> dest,
+                                               T... args) {
+    return Instruction{Op::kInvokeStatic, method_id, /*result_is_object=*/true, dest, args...};
+  }
+  // For static calls.
+  template <typename... T>
+  static inline Instruction InvokeInterface(size_t method_id, std::optional<const Value> dest,
+                                            T... args) {
+    return Instruction{Op::kInvokeInterface, method_id, /*result_is_object=*/false, dest, args...};
   }
 
   ///////////////
@@ -184,21 +229,27 @@
 
   Op opcode() const { return opcode_; }
   size_t method_id() const { return method_id_; }
+  bool result_is_object() const { return result_is_object_; }
   const std::optional<const Value>& dest() const { return dest_; }
   const std::vector<const Value>& args() const { return args_; }
 
  private:
   inline Instruction(Op opcode, size_t method_id, std::optional<const Value> dest)
-      : opcode_{opcode}, method_id_{method_id}, dest_{dest}, args_{} {}
+      : opcode_{opcode}, method_id_{method_id}, result_is_object_{false}, dest_{dest}, args_{} {}
 
   template <typename... T>
-  inline constexpr Instruction(Op opcode, size_t method_id, std::optional<const Value> dest,
-                               T... args)
-      : opcode_{opcode}, method_id_{method_id}, dest_{dest}, args_{args...} {}
+  inline constexpr Instruction(Op opcode, size_t method_id, bool result_is_object,
+                               std::optional<const Value> dest, T... args)
+      : opcode_{opcode},
+        method_id_{method_id},
+        result_is_object_{result_is_object},
+        dest_{dest},
+        args_{args...} {}
 
   const Op opcode_;
   // The index of the method to invoke, for kInvokeVirtual and similar opcodes.
   const size_t method_id_{0};
+  const bool result_is_object_;
   const std::optional<const Value> dest_;
   const std::vector<const Value> args_;
 };
@@ -244,6 +295,8 @@
 
   // TODO: add builders for more instructions
 
+  DexBuilder* dex_file() const { return dex_; }
+
  private:
   void EncodeInstructions();
   void EncodeInstruction(const Instruction& instruction);
@@ -257,6 +310,7 @@
   void EncodeInvoke(const Instruction& instruction, ::art::Instruction::Code opcode);
   void EncodeBranch(art::Instruction::Code op, const Instruction& instruction);
   void EncodeNew(const Instruction& instruction);
+  void EncodeCast(const Instruction& instruction);
 
   // Low-level instruction format encoding. See
   // https://source.android.com/devices/tech/dalvik/instruction-formats for documentation of
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
index e20f3a9..42d4161 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
@@ -20,6 +20,7 @@
 import dalvik.system.InMemoryDexClassLoader;
 import dalvik.system.PathClassLoader;
 import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.nio.ByteBuffer;
 import org.junit.Assert;
@@ -84,6 +85,15 @@
   }
 
   @Test
+  public void returnIfNotZero() throws Exception {
+    ClassLoader loader = loadDexFile("simple.dex");
+    Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+    Method method = clazz.getMethod("returnIfNotZero", int.class);
+    Assert.assertEquals(3, method.invoke(null, 0));
+    Assert.assertEquals(5, method.invoke(null, 17));
+  }
+
+  @Test
   public void backwardsBranch() throws Exception {
     ClassLoader loader = loadDexFile("simple.dex");
     Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
@@ -124,4 +134,41 @@
     Assert.assertEquals("b", method.invoke(null, 0));
     Assert.assertEquals("a", method.invoke(null, 1));
   }
+
+  @Test
+  public void invokeStaticReturnObject() throws Exception {
+    ClassLoader loader = loadDexFile("simple.dex");
+    Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+    Method method = clazz.getMethod("invokeStaticReturnObject", int.class, int.class);
+    Assert.assertEquals("10", method.invoke(null, 10, 10));
+    Assert.assertEquals("a", method.invoke(null, 10, 16));
+    Assert.assertEquals("5", method.invoke(null, 5, 16));
+  }
+
+  @Test
+  public void invokeVirtualReturnObject() throws Exception {
+    ClassLoader loader = loadDexFile("simple.dex");
+    Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+    Method method = clazz.getMethod("invokeVirtualReturnObject", String.class, int.class);
+    Assert.assertEquals("bc", method.invoke(null, "abc", 1));
+  }
+
+  @Test
+  public void castObjectToString() throws Exception {
+    ClassLoader loader = loadDexFile("simple.dex");
+    Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+    Method method = clazz.getMethod("castObjectToString", Object.class);
+    Assert.assertEquals("abc", method.invoke(null, "abc"));
+    boolean castFailed = false;
+    try {
+      method.invoke(null, 5);
+    } catch (InvocationTargetException e) {
+      if (e.getCause() instanceof ClassCastException) {
+        castFailed = true;
+      } else {
+        throw e;
+      }
+    }
+    Assert.assertTrue(castFailed);
+  }
 }
diff --git a/startop/view_compiler/dex_testcase_generator.cc b/startop/view_compiler/dex_testcase_generator.cc
index e2bf43bc..f62ec5dd 100644
--- a/startop/view_compiler/dex_testcase_generator.cc
+++ b/startop/view_compiler/dex_testcase_generator.cc
@@ -108,6 +108,27 @@
   }
   returnIfZero.Encode();
 
+  // int returnIfNotZero(int x) { if (x != 0) { return 5; } else { return 3; } }
+  MethodBuilder returnIfNotZero{cbuilder.CreateMethod(
+      "returnIfNotZero", Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})};
+  {
+    Value resultIfNotZero{returnIfNotZero.MakeRegister()};
+    Value else_target{returnIfNotZero.MakeLabel()};
+    returnIfNotZero.AddInstruction(Instruction::OpWithArgs(
+        Instruction::Op::kBranchNEqz, /*dest=*/{}, Value::Parameter(0), else_target));
+    // else branch
+    returnIfNotZero.BuildConst4(resultIfNotZero, 3);
+    returnIfNotZero.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfNotZero));
+    // then branch
+    returnIfNotZero.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, else_target));
+    returnIfNotZero.BuildConst4(resultIfNotZero, 5);
+    returnIfNotZero.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfNotZero));
+  }
+  returnIfNotZero.Encode();
+
   // Make sure backwards branches work too.
   //
   // Pseudo code for test:
@@ -216,6 +237,51 @@
     method.Encode();
   }(returnStringIfZeroBA);
 
+  // Make sure we can invoke static methods that return an object
+  // String invokeStaticReturnObject(int n, int radix) { return java.lang.Integer.toString(n,
+  // radix); }
+  MethodBuilder invokeStaticReturnObject{
+      cbuilder.CreateMethod("invokeStaticReturnObject",
+                            Prototype{string_type, TypeDescriptor::Int(), TypeDescriptor::Int()})};
+  [&](MethodBuilder& method) {
+    Value result{method.MakeRegister()};
+    MethodDeclData to_string{dex_file.GetOrDeclareMethod(
+        TypeDescriptor::FromClassname("java.lang.Integer"),
+        "toString",
+        Prototype{string_type, TypeDescriptor::Int(), TypeDescriptor::Int()})};
+    method.AddInstruction(Instruction::InvokeStaticObject(
+        to_string.id, result, Value::Parameter(0), Value::Parameter(1)));
+    method.BuildReturn(result, /*is_object=*/true);
+    method.Encode();
+  }(invokeStaticReturnObject);
+
+  // Make sure we can invoke virtual methods that return an object
+  // String invokeVirtualReturnObject(String s, int n) { return s.substring(n); }
+  MethodBuilder invokeVirtualReturnObject{cbuilder.CreateMethod(
+      "invokeVirtualReturnObject", Prototype{string_type, string_type, TypeDescriptor::Int()})};
+  [&](MethodBuilder& method) {
+    Value result{method.MakeRegister()};
+    MethodDeclData substring{dex_file.GetOrDeclareMethod(
+        string_type, "substring", Prototype{string_type, TypeDescriptor::Int()})};
+    method.AddInstruction(Instruction::InvokeVirtualObject(
+        substring.id, result, Value::Parameter(0), Value::Parameter(1)));
+    method.BuildReturn(result, /*is_object=*/true);
+    method.Encode();
+  }(invokeVirtualReturnObject);
+
+  // Make sure we can cast objects
+  // String castObjectToString(Object o) { return (String)o; }
+  MethodBuilder castObjectToString{cbuilder.CreateMethod(
+      "castObjectToString",
+      Prototype{string_type, TypeDescriptor::FromClassname("java.lang.Object")})};
+  [&](MethodBuilder& method) {
+    const ir::Type* type_def = dex_file.GetOrAddType(string_type.descriptor());
+    method.AddInstruction(
+        Instruction::Cast(Value::Parameter(0), Value::Type(type_def->orig_index)));
+    method.BuildReturn(Value::Parameter(0), /*is_object=*/true);
+    method.Encode();
+  }(castObjectToString);
+
   slicer::MemView image{dex_file.CreateImage()};
   std::ofstream out_file(outdir + "/simple.dex");
   out_file.write(image.ptr<const char>(), image.size());
diff --git a/startop/view_compiler/layout_validation.cc b/startop/view_compiler/layout_validation.cc
new file mode 100644
index 0000000..8c77377
--- /dev/null
+++ b/startop/view_compiler/layout_validation.cc
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "layout_validation.h"
+
+#include "android-base/stringprintf.h"
+
+namespace startop {
+
+void LayoutValidationVisitor::VisitStartTag(const std::u16string& name) {
+  if (0 == name.compare(u"merge")) {
+    message_ = "Merge tags are not supported";
+    can_compile_ = false;
+  }
+  if (0 == name.compare(u"include")) {
+    message_ = "Include tags are not supported";
+    can_compile_ = false;
+  }
+  if (0 == name.compare(u"view")) {
+    message_ = "View tags are not supported";
+    can_compile_ = false;
+  }
+  if (0 == name.compare(u"fragment")) {
+    message_ = "Fragment tags are not supported";
+    can_compile_ = false;
+  }
+}
+
+}  // namespace startop
\ No newline at end of file
diff --git a/startop/view_compiler/layout_validation.h b/startop/view_compiler/layout_validation.h
new file mode 100644
index 0000000..bed34bb
--- /dev/null
+++ b/startop/view_compiler/layout_validation.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LAYOUT_VALIDATION_H_
+#define LAYOUT_VALIDATION_H_
+
+#include "dex_builder.h"
+
+#include <string>
+
+namespace startop {
+
+// This visitor determines whether a layout can be compiled. Since we do not currently support all
+// features, such as includes and merges, we need to pre-validate the layout before we start
+// compiling.
+class LayoutValidationVisitor {
+ public:
+  void VisitStartDocument() const {}
+  void VisitEndDocument() const {}
+  void VisitStartTag(const std::u16string& name);
+  void VisitEndTag() const {}
+
+  const std::string& message() const { return message_; }
+  bool can_compile() const { return can_compile_; }
+
+ private:
+  std::string message_{"Okay"};
+  bool can_compile_{true};
+};
+
+}  // namespace startop
+
+#endif  // LAYOUT_VALIDATION_H_
diff --git a/startop/view_compiler/layout_validation_test.cc b/startop/view_compiler/layout_validation_test.cc
new file mode 100644
index 0000000..b74cdae
--- /dev/null
+++ b/startop/view_compiler/layout_validation_test.cc
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "tinyxml_layout_parser.h"
+
+#include "gtest/gtest.h"
+
+using startop::CanCompileLayout;
+using std::string;
+
+namespace {
+void ValidateXmlText(const string& xml, bool expected) {
+  tinyxml2::XMLDocument doc;
+  doc.Parse(xml.c_str());
+  EXPECT_EQ(CanCompileLayout(doc), expected);
+}
+}  // namespace
+
+TEST(LayoutValidationTest, SingleButtonLayout) {
+  const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:text="Hello, World!">
+
+</Button>)";
+  ValidateXmlText(xml, /*expected=*/true);
+}
+
+TEST(LayoutValidationTest, SmallConstraintLayout) {
+  const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <Button
+        android:id="@+id/button6"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="16dp"
+        android:layout_marginBottom="16dp"
+        android:text="Button"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent" />
+
+    <Button
+        android:id="@+id/button7"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="8dp"
+        android:layout_marginBottom="16dp"
+        android:text="Button2"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/button6" />
+
+    <Button
+        android:id="@+id/button8"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginEnd="8dp"
+        android:layout_marginBottom="16dp"
+        android:text="Button1"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/button7" />
+</android.support.constraint.ConstraintLayout>)";
+  ValidateXmlText(xml, /*expected=*/true);
+}
+
+TEST(LayoutValidationTest, MergeNode) {
+  const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <TextView
+        android:id="@+id/textView3"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="TextView" />
+
+    <Button
+        android:id="@+id/button9"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Button" />
+</merge>)";
+  ValidateXmlText(xml, /*expected=*/false);
+}
+
+TEST(LayoutValidationTest, IncludeLayout) {
+  const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <include
+        layout="@layout/single_button_layout"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+</android.support.constraint.ConstraintLayout>)";
+  ValidateXmlText(xml, /*expected=*/false);
+}
+
+TEST(LayoutValidationTest, ViewNode) {
+  const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <view
+        class="android.support.design.button.MaterialButton"
+        id="@+id/view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+</android.support.constraint.ConstraintLayout>)";
+  ValidateXmlText(xml, /*expected=*/false);
+}
+
+TEST(LayoutValidationTest, FragmentNode) {
+  // This test case is from https://developer.android.com/guide/components/fragments
+  const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <fragment android:name="com.example.news.ArticleListFragment"
+            android:id="@+id/list"
+            android:layout_weight="1"
+            android:layout_width="0dp"
+            android:layout_height="match_parent" />
+    <fragment android:name="com.example.news.ArticleReaderFragment"
+            android:id="@+id/viewer"
+            android:layout_weight="2"
+            android:layout_width="0dp"
+            android:layout_height="match_parent" />
+</LinearLayout>)";
+  ValidateXmlText(xml, /*expected=*/false);
+}
diff --git a/startop/view_compiler/main.cc b/startop/view_compiler/main.cc
index 7d791c2..55bfdc7 100644
--- a/startop/view_compiler/main.cc
+++ b/startop/view_compiler/main.cc
@@ -18,6 +18,7 @@
 
 #include "dex_builder.h"
 #include "java_lang_builder.h"
+#include "tinyxml_layout_parser.h"
 #include "util.h"
 
 #include "tinyxml2.h"
@@ -41,7 +42,7 @@
 
 class ViewCompilerXmlVisitor : public XMLVisitor {
  public:
-  ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {}
+  explicit ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {}
 
   bool VisitEnter(const XMLDocument& /*doc*/) override {
     builder_->Start();
@@ -100,6 +101,12 @@
   XMLDocument xml;
   xml.LoadFile(filename);
 
+  string message{};
+  if (!startop::CanCompileLayout(xml, &message)) {
+    LOG(ERROR) << "Layout not supported: " << message;
+    return 1;
+  }
+
   std::ofstream outfile;
   if (FLAGS_out != kStdoutFilename) {
     outfile.open(FLAGS_out);
diff --git a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl b/startop/view_compiler/tinyxml_layout_parser.cc
similarity index 60%
copy from telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
copy to startop/view_compiler/tinyxml_layout_parser.cc
index 4c289ac..1b3a81f 100644
--- a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
+++ b/startop/view_compiler/tinyxml_layout_parser.cc
@@ -13,13 +13,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include "tinyxml_layout_parser.h"
 
-package com.android.internal.telephony.rcs;
+#include "layout_validation.h"
 
-interface IRcs {
-    // RcsManager APIs
-    void deleteThread(int threadId);
+namespace startop {
 
-    // RcsThread APIs
-    int getMessageCount(int rcsThreadId);
-}
\ No newline at end of file
+bool CanCompileLayout(const tinyxml2::XMLDocument& xml, std::string* message) {
+  LayoutValidationVisitor validator;
+  TinyXmlVisitorAdapter adapter{&validator};
+  xml.Accept(&adapter);
+
+  if (message != nullptr) {
+    *message = validator.message();
+  }
+
+  return validator.can_compile();
+}
+
+}  // namespace startop
diff --git a/startop/view_compiler/tinyxml_layout_parser.h b/startop/view_compiler/tinyxml_layout_parser.h
new file mode 100644
index 0000000..8f714a2
--- /dev/null
+++ b/startop/view_compiler/tinyxml_layout_parser.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef TINYXML_LAYOUT_PARSER_H_
+#define TINYXML_LAYOUT_PARSER_H_
+
+#include "tinyxml2.h"
+
+#include <codecvt>
+#include <locale>
+#include <string>
+
+namespace startop {
+
+template <typename Visitor>
+class TinyXmlVisitorAdapter : public tinyxml2::XMLVisitor {
+ public:
+  explicit TinyXmlVisitorAdapter(Visitor* visitor) : visitor_{visitor} {}
+
+  bool VisitEnter(const tinyxml2::XMLDocument& /*doc*/) override {
+    visitor_->VisitStartDocument();
+    return true;
+  }
+
+  bool VisitExit(const tinyxml2::XMLDocument& /*doc*/) override {
+    visitor_->VisitEndDocument();
+    return true;
+  }
+
+  bool VisitEnter(const tinyxml2::XMLElement& element,
+                  const tinyxml2::XMLAttribute* /*firstAttribute*/) override {
+    visitor_->VisitStartTag(
+        std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(
+            element.Name()));
+    return true;
+  }
+
+  bool VisitExit(const tinyxml2::XMLElement& /*element*/) override {
+    visitor_->VisitEndTag();
+    return true;
+  }
+
+ private:
+  Visitor* visitor_;
+};
+
+// Returns whether a layout resource represented by a TinyXML document is supported by the layout
+// compiler.
+bool CanCompileLayout(const tinyxml2::XMLDocument& xml, std::string* message = nullptr);
+
+}  // namespace startop
+
+#endif  // TINYXML_LAYOUT_PARSER_H_
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index cef99865..36d0188 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -29,7 +29,6 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
-import java.lang.String;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.nio.charset.StandardCharsets;
@@ -123,10 +122,21 @@
      * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call
      * extras. Used to pass the phone accounts to display on the front end to the user in order to
      * select phone accounts to (for example) place a call.
+     * @deprecated Use the list from {@link #EXTRA_SUGGESTED_PHONE_ACCOUNTS} instead.
      */
+    @Deprecated
     public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts";
 
     /**
+     * Key for extra used to pass along a list of {@link PhoneAccountSuggestion}s to the in-call
+     * UI when a call enters the {@link #STATE_SELECT_PHONE_ACCOUNT} state. The list included here
+     * will have the same length and be in the same order as the list passed with
+     * {@link #AVAILABLE_PHONE_ACCOUNTS}.
+     */
+    public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS =
+            "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS";
+
+    /**
      * Extra key used to indicate the time (in milliseconds since midnight, January 1, 1970 UTC)
      * when the last outgoing emergency call was made.  This is used to identify potential emergency
      * callbacks.
@@ -908,10 +918,16 @@
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder();
-            sb.append("[pa: ");
+            sb.append("[id: ");
+            sb.append(mTelecomCallId);
+            sb.append(", pa: ");
             sb.append(mAccountHandle);
             sb.append(", hdl: ");
-            sb.append(Log.pii(mHandle));
+            sb.append(Log.piiHandle(mHandle));
+            sb.append(", hdlPres: ");
+            sb.append(mHandlePresentation);
+            sb.append(", videoState: ");
+            sb.append(VideoProfile.videoStateToString(mVideoState));
             sb.append(", caps: ");
             sb.append(capabilitiesToString(mCallCapabilities));
             sb.append(", props: ");
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 7db6940..6628743 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -27,8 +27,8 @@
 import android.os.RemoteException;
 
 import com.android.internal.os.SomeArgs;
-import com.android.internal.telecom.ICallScreeningService;
 import com.android.internal.telecom.ICallScreeningAdapter;
+import com.android.internal.telecom.ICallScreeningService;
 
 /**
  * This service can be implemented by the default dialer (see
@@ -147,7 +147,7 @@
             private boolean mShouldSkipCallLog;
             private boolean mShouldSkipNotification;
 
-            /*
+            /**
              * Sets whether the incoming call should be blocked.
              */
             public Builder setDisallowCall(boolean shouldDisallowCall) {
@@ -155,7 +155,7 @@
                 return this;
             }
 
-            /*
+            /**
              * Sets whether the incoming call should be disconnected as if the user had manually
              * rejected it. This property should only be set to true if the call is disallowed.
              */
@@ -164,16 +164,20 @@
                 return this;
             }
 
-            /*
+            /**
              * Sets whether the incoming call should not be displayed in the call log. This property
              * should only be set to true if the call is disallowed.
+             * <p>
+             * Note: Calls will still be logged with type
+             * {@link android.provider.CallLog.Calls#BLOCKED_TYPE}, regardless of how this property
+             * is set.
              */
             public Builder setSkipCallLog(boolean shouldSkipCallLog) {
                 mShouldSkipCallLog = shouldSkipCallLog;
                 return this;
             }
 
-            /*
+            /**
              * Sets whether a missed call notification should not be shown for the incoming call.
              * This property should only be set to true if the call is disallowed.
              */
@@ -211,6 +215,17 @@
      * Called when a new incoming call is added.
      * {@link CallScreeningService#respondToCall(Call.Details, CallScreeningService.CallResponse)}
      * should be called to allow or disallow the call.
+     * <p>
+     * Note: The {@link Call.Details} instance provided to a call screening service will only have
+     * the following properties set.  The rest of the {@link Call.Details} properties will be set to
+     * their default value or {@code null}.
+     * <ul>
+     *     <li>{@link Call.Details#getState()}</li>
+     *     <li>{@link Call.Details#getConnectTimeMillis()}</li>
+     *     <li>{@link Call.Details#getCreationTimeMillis()}</li>
+     *     <li>{@link Call.Details#getHandle()}</li>
+     *     <li>{@link Call.Details#getHandlePresentation()}</li>
+     * </ul>
      *
      * @param callDetails Information about a new incoming call, see {@link Call.Details}.
      */
diff --git a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl b/telecomm/java/android/telecom/PhoneAccountSuggestion.aidl
similarity index 76%
copy from telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
copy to telecomm/java/android/telecom/PhoneAccountSuggestion.aidl
index 4c289ac..e2fa7e4 100644
--- a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
+++ b/telecomm/java/android/telecom/PhoneAccountSuggestion.aidl
@@ -14,12 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.rcs;
+package android.telecom;
 
-interface IRcs {
-    // RcsManager APIs
-    void deleteThread(int threadId);
-
-    // RcsThread APIs
-    int getMessageCount(int rcsThreadId);
-}
\ No newline at end of file
+/**
+ * {@hide}
+  */
+parcelable PhoneAccountSuggestion;
\ No newline at end of file
diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestion.java b/telecomm/java/android/telecom/PhoneAccountSuggestion.java
new file mode 100644
index 0000000..b401bcf
--- /dev/null
+++ b/telecomm/java/android/telecom/PhoneAccountSuggestion.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecom;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+public final class PhoneAccountSuggestion implements Parcelable {
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(value = {REASON_NONE, REASON_INTRA_CARRIER, REASON_FREQUENT,
+            REASON_USER_SET, REASON_OTHER}, prefix = { "REASON_" })
+    public @interface SuggestionReason {}
+
+    /**
+     * Indicates that this account is not suggested for use, but is still available.
+     */
+    public static final int REASON_NONE = 0;
+
+    /**
+     * Indicates that the {@link PhoneAccountHandle} is suggested because the number we're calling
+     * is on the same carrier, and therefore may have lower rates.
+     */
+    public static final int REASON_INTRA_CARRIER = 1;
+
+    /**
+     * Indicates that the {@link PhoneAccountHandle} is suggested because the user uses it
+     * frequently for the number that we are calling.
+     */
+    public static final int REASON_FREQUENT = 2;
+
+    /**
+     * Indicates that the {@link PhoneAccountHandle} is suggested because the user explicitly
+     * specified that it be used for the number we are calling.
+     */
+    public static final int REASON_USER_SET = 3;
+
+    /**
+     * Indicates that the {@link PhoneAccountHandle} is suggested for a reason not otherwise
+     * enumerated here.
+     */
+    public static final int REASON_OTHER = 4;
+
+    private PhoneAccountHandle mHandle;
+    private int mReason;
+    private boolean mShouldAutoSelect;
+
+    /**
+     * @hide
+     */
+    @SystemApi
+    @TestApi
+    public PhoneAccountSuggestion(PhoneAccountHandle handle, @SuggestionReason int reason,
+            boolean shouldAutoSelect) {
+        this.mHandle = handle;
+        this.mReason = reason;
+        this.mShouldAutoSelect = shouldAutoSelect;
+    }
+
+    private PhoneAccountSuggestion(Parcel in) {
+        mHandle = in.readParcelable(PhoneAccountHandle.class.getClassLoader());
+        mReason = in.readInt();
+        mShouldAutoSelect = in.readByte() != 0;
+    }
+
+    public static final Creator<PhoneAccountSuggestion> CREATOR =
+            new Creator<PhoneAccountSuggestion>() {
+                @Override
+                public PhoneAccountSuggestion createFromParcel(Parcel in) {
+                    return new PhoneAccountSuggestion(in);
+                }
+
+                @Override
+                public PhoneAccountSuggestion[] newArray(int size) {
+                    return new PhoneAccountSuggestion[size];
+                }
+            };
+
+    /**
+     * @return The {@link PhoneAccountHandle} for this suggestion.
+     */
+    public PhoneAccountHandle getPhoneAccountHandle() {
+        return mHandle;
+    }
+
+    /**
+     * @return The reason for this suggestion
+     */
+    public @SuggestionReason int getReason() {
+        return mReason;
+    }
+
+    /**
+     * Suggests whether the dialer should automatically place the call using this account without
+     * user interaction. This may be set on multiple {@link PhoneAccountSuggestion}s, and the dialer
+     * is free to choose which one to use.
+     * @return {@code true} if the hint is to auto-select, {@code false} otherwise.
+     */
+    public boolean shouldAutoSelect() {
+        return mShouldAutoSelect;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mHandle, flags);
+        dest.writeInt(mReason);
+        dest.writeByte((byte) (mShouldAutoSelect ? 1 : 0));
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PhoneAccountSuggestion that = (PhoneAccountSuggestion) o;
+        return mReason == that.mReason
+                && mShouldAutoSelect == that.mShouldAutoSelect
+                && Objects.equals(mHandle, that.mHandle);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mHandle, mReason, mShouldAutoSelect);
+    }
+}
diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestionService.java b/telecomm/java/android/telecom/PhoneAccountSuggestionService.java
new file mode 100644
index 0000000..ba3822c
--- /dev/null
+++ b/telecomm/java/android/telecom/PhoneAccountSuggestionService.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telecom;
+
+import android.annotation.NonNull;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import com.android.internal.telecom.IPhoneAccountSuggestionCallback;
+import com.android.internal.telecom.IPhoneAccountSuggestionService;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base class for service that allows system apps to suggest phone accounts for outgoing calls.
+ *
+ * Phone account suggestions allow OEMs to intelligently select phone accounts based on knowledge
+ * about the user's past behavior, carrier billing patterns, or other factors unknown to the AOSP
+ * Telecom system.
+ * OEMs who wish to provide a phone account suggestion service on their device should implement this
+ * service in an app that resides in the /system/priv-app/ directory on their device. For security
+ * reasons, the service's entry {@code AndroidManifest.xml} file must declare the
+ * {@link android.Manifest.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE} permission:
+ * <pre>
+ * {@code
+ * <service android:name="your.package.YourServiceName"
+ *          android:permission="android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE">
+ *      <intent-filter>
+ *          <action android:name="android.telecom.PhoneAccountSuggestionService"/>
+ *      </intent-filter>
+ * </service>
+ * }
+ * </pre>
+ * Only one system app on each device may implement this service. If multiple system apps implement
+ * this service, none of them will be queried for suggestions.
+ * @hide
+ */
+@SystemApi
+@TestApi
+public class PhoneAccountSuggestionService extends Service {
+    /**
+     * The {@link Intent} that must be declared in the {@code intent-filter} element of the
+     * service's manifest entry.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE = "android.telecom.PhoneAccountSuggestionService";
+
+    private IPhoneAccountSuggestionService mInterface = new IPhoneAccountSuggestionService.Stub() {
+        @Override
+        public void onAccountSuggestionRequest(IPhoneAccountSuggestionCallback callback,
+                String number) {
+            mCallbackMap.put(number, callback);
+            PhoneAccountSuggestionService.this.onAccountSuggestionRequest(number);
+        }
+    };
+
+    private final Map<String, IPhoneAccountSuggestionCallback> mCallbackMap =
+            new HashMap<>();
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mInterface.asBinder();
+    }
+
+    /**
+     * The system calls this method during the outgoing call flow if it needs account suggestions.
+     *
+     * The implementer of this service must override this method to implement its account suggestion
+     * logic. After preparing the suggestions, the implementation of the service must call
+     * {@link #suggestPhoneAccounts(String, List)} to deliver the suggestions back to the system.
+     *
+     * Note that the system will suspend the outgoing call process after it calls this method until
+     * this service calls {@link #suggestPhoneAccounts}.
+     *
+     * @param number The phone number to provide suggestions for.
+     */
+    public void onAccountSuggestionRequest(@NonNull String number) {}
+
+    /**
+     * The implementation of this service calls this method to deliver suggestions to the system.
+     *
+     * The implementation of this service must call this method after receiving a call to
+     * {@link #onAccountSuggestionRequest(String)}. If no suggestions are available, pass an empty
+     * list as the {@code suggestions} argument.
+     *
+     * @param number The phone number to provide suggestions for.
+     * @param suggestions The list of suggestions.
+     */
+    public final void suggestPhoneAccounts(@NonNull String number,
+            @NonNull List<PhoneAccountSuggestion> suggestions) {
+        IPhoneAccountSuggestionCallback callback = mCallbackMap.remove(number);
+        if (callback == null) {
+            Log.w(this, "No suggestions requested for the number %s", Log.pii(number));
+            return;
+        }
+        try {
+            callback.suggestPhoneAccounts(number, suggestions);
+        } catch (RemoteException e) {
+            Log.w(this, "Remote exception calling suggestPhoneAccounts");
+        }
+    }
+}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 9f0bdd7..e7ce78a 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1462,7 +1462,6 @@
      * otherwise.
      */
     @RequiresPermission(Manifest.permission.ANSWER_PHONE_CALLS)
-    @SystemApi
     public boolean endCall() {
         try {
             if (isServiceConnected()) {
@@ -1539,7 +1538,6 @@
     /**
      * Returns whether TTY is supported on this device.
      */
-    @SystemApi
     @RequiresPermission(anyOf = {
             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
             android.Manifest.permission.READ_PHONE_STATE
diff --git a/telecomm/java/android/telecom/VideoProfile.java b/telecomm/java/android/telecom/VideoProfile.java
index bbac8eb..7b23061 100644
--- a/telecomm/java/android/telecom/VideoProfile.java
+++ b/telecomm/java/android/telecom/VideoProfile.java
@@ -369,16 +369,13 @@
         }
 
         /**
-         * Create a call camera capabilities instance that optionally
-         * supports zoom.
+         * Create a call camera capabilities instance that optionally supports zoom.
          *
          * @param width The width of the camera video (in pixels).
          * @param height The height of the camera video (in pixels).
          * @param zoomSupported True when camera supports zoom.
          * @param maxZoom Maximum zoom supported by camera.
-         * @hide
          */
-        @UnsupportedAppUsage
         public CameraCapabilities(int width, int height, boolean zoomSupported, float maxZoom) {
             mWidth = width;
             mHeight = height;
@@ -455,16 +452,14 @@
         }
 
         /**
-         * Whether the camera supports zoom.
-         * @hide
+         * Returns {@code true} is zoom is supported, {@code false} otherwise.
          */
         public boolean isZoomSupported() {
             return mZoomSupported;
         }
 
         /**
-         * The maximum zoom supported by the camera.
-         * @hide
+         * Returns the maximum zoom supported by the camera.
          */
         public float getMaxZoom() {
             return mMaxZoom;
diff --git a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl b/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionCallback.aidl
similarity index 65%
copy from telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
copy to telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionCallback.aidl
index 4c289ac..cb14241 100644
--- a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
+++ b/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionCallback.aidl
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.rcs;
+package com.android.internal.telecom;
 
-interface IRcs {
-    // RcsManager APIs
-    void deleteThread(int threadId);
-
-    // RcsThread APIs
-    int getMessageCount(int rcsThreadId);
-}
\ No newline at end of file
+import android.telecom.PhoneAccountSuggestion;
+/**
+ * Internal remote callback interface for a phone acct suggestion service.
+ * @hide
+ */
+oneway interface IPhoneAccountSuggestionCallback{
+    void suggestPhoneAccounts(in String number, in List<PhoneAccountSuggestion> suggestions);
+}
diff --git a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl b/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionService.aidl
similarity index 63%
copy from telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
copy to telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionService.aidl
index 4c289ac..0ffab93 100644
--- a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
+++ b/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionService.aidl
@@ -14,12 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.rcs;
+package com.android.internal.telecom;
 
-interface IRcs {
-    // RcsManager APIs
-    void deleteThread(int threadId);
+import com.android.internal.telecom.IPhoneAccountSuggestionCallback;
 
-    // RcsThread APIs
-    int getMessageCount(int rcsThreadId);
-}
\ No newline at end of file
+/**
+ * Internal remote interface for a phone acct suggestion service.
+ * @hide
+ */
+oneway interface IPhoneAccountSuggestionService {
+    void onAccountSuggestionRequest(in IPhoneAccountSuggestionCallback callback,
+            in String number);
+}
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 143b323..6f1b66a 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -305,6 +305,10 @@
      */
     void handleCallIntent(in Intent intent);
 
+    void setTestDefaultCallRedirectionApp(String packageName);
+
+    void setTestPhoneAcctSuggestionComponent(String flattenedComponentName);
+
     void setTestDefaultCallScreeningApp(String packageName);
 
     void addOrRemoveTestCallCompanionApp(String packageName, boolean isAdded);
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 0b5aa14..3e4482e 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -2668,10 +2668,26 @@
 
         /**
          * The {@code content://} style URL for this table.
+         * For MSIM, this will return APNs for the default subscription
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId for MSIM,
+         * use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
          */
         public static final Uri CONTENT_URI = Uri.parse("content://telephony/carriers");
 
         /**
+         * The {@code content://} style URL for this table. Used for APN query based on current
+         * subscription. Instead of specifying carrier matching information in the selection,
+         * this API will return all matching APNs from current subscription carrier and queries
+         * will be applied on top of that. If there is no match for MVNO (Mobile Virtual Network
+         * Operator) APNs, return APNs from its MNO (based on mccmnc) instead. For MSIM, this will
+         * return APNs for the default subscription
+         * {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId for MSIM,
+         * use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
+         */
+        public static final Uri SIM_APN_URI = Uri.parse(
+                "content://telephony/carriers/sim_apn_list");
+
+        /**
          * The {@code content://} style URL to be called from DevicePolicyManagerService,
          * can manage DPC-owned APNs.
          * @hide
@@ -2681,7 +2697,9 @@
         /**
          * The {@code content://} style URL to be called from Telephony to query APNs.
          * When DPC-owned APNs are enforced, only DPC-owned APNs are returned, otherwise only
-         * non-DPC-owned APNs are returned.
+         * non-DPC-owned APNs are returned. For MSIM, this will return APNs for the default
+         * subscription {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId
+         * for MSIM, use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
          * @hide
          */
         public static final Uri FILTERED_URI = Uri.parse("content://telephony/carriers/filtered");
@@ -2695,13 +2713,6 @@
                 "content://telephony/carriers/enforce_managed");
 
         /**
-         * The {@code content://} style URL to be called from Telephony to query current APNs.
-         * @hide
-         */
-        public static final Uri SIM_APN_LIST = Uri.parse(
-                "content://telephony/carriers/sim_apn_list");
-
-        /**
          * The column name for ENFORCE_MANAGED_URI, indicates whether DPC-owned APNs are enforced.
          * @hide
          */
@@ -2775,18 +2786,30 @@
         /**
          * Mobile Country Code (MCC).
          * <P>Type: TEXT</P>
+         * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+         * matching APNs based on current subscription carrier, thus no need to specify MCC and
+         * other carrier matching information. In the future, Android will not support MCC for
+         * APN query.
          */
         public static final String MCC = "mcc";
 
         /**
          * Mobile Network Code (MNC).
          * <P>Type: TEXT</P>
+         * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+         * matching APNs based on current subscription carrier, thus no need to specify MNC and
+         * other carrier matching information. In the future, Android will not support MNC for
+         * APN query.
          */
         public static final String MNC = "mnc";
 
         /**
          * Numeric operator ID (as String). Usually {@code MCC + MNC}.
          * <P>Type: TEXT</P>
+         * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+         * matching APNs based on current subscription carrier, thus no need to specify Numeric
+         * and other carrier matching information. In the future, Android will not support Numeric
+         * for APN query.
          */
         public static final String NUMERIC = "numeric";
 
@@ -2867,6 +2890,10 @@
          * MVNO type:
          * {@code SPN (Service Provider Name), IMSI, GID (Group Identifier Level 1)}.
          * <P>Type: TEXT</P>
+         * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+         * matching APNs based on current subscription carrier, thus no need to specify MVNO_TYPE
+         * and other carrier matching information. In the future, Android will not support MVNO_TYPE
+         * for APN query.
          */
         public static final String MVNO_TYPE = "mvno_type";
 
@@ -2879,6 +2906,10 @@
          *     <li>GID: 4E, 33, ...</li>
          * </ul>
          * <P>Type: TEXT</P>
+         * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+         * matching APNs based on current subscription carrier, thus no need to specify
+         * MVNO_MATCH_DATA and other carrier matching information. In the future, Android will not
+         * support MVNO_MATCH_DATA for APN query.
          */
         public static final String MVNO_MATCH_DATA = "mvno_match_data";
 
@@ -3087,7 +3118,6 @@
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface EditStatus {}
-
     }
 
     /**
@@ -3577,8 +3607,9 @@
 
         /**
          * Generates a content {@link Uri} used to receive updates on precise carrier identity
-         * change on the given subscriptionId
-         * {@link TelephonyManager#ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED}.
+         * change on the given subscriptionId returned by
+         * {@link TelephonyManager#getSimPreciseCarrierId()}.
+         * @see TelephonyManager#ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED
          * <p>
          * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
          * precise carrier identity {@link TelephonyManager#getSimPreciseCarrierId()}
@@ -3589,7 +3620,6 @@
          *
          * @param subscriptionId the subscriptionId to receive updates on
          * @return the Uri used to observe precise carrier identity changes
-         * @hide
          */
         public static Uri getPreciseCarrierIdUriForSubscriptionId(int subscriptionId) {
             return Uri.withAppendedPath(Uri.withAppendedPath(CONTENT_URI, "precise"),
@@ -3611,24 +3641,22 @@
         public static final String CARRIER_ID = "carrier_id";
 
         /**
-         * A user facing carrier name for precise carrier id.
-         * @see TelephonyManager#getSimPreciseCarrierIdName()
-         * This is not a database column, only used to notify content observers for
-         * {@link #getPreciseCarrierIdUriForSubscriptionId(int)}
-         * @hide
-         */
-        public static final String PRECISE_CARRIER_ID_NAME = "precise_carrier_id_name";
-
-        /**
          * A fine-grained carrier id.
          * @see TelephonyManager#getSimPreciseCarrierId()
          * This is not a database column, only used to notify content observers for
          * {@link #getPreciseCarrierIdUriForSubscriptionId(int)}
-         * @hide
          */
         public static final String PRECISE_CARRIER_ID = "precise_carrier_id";
 
         /**
+         * A user facing carrier name for precise carrier id {@link #PRECISE_CARRIER_ID}.
+         * @see TelephonyManager#getSimPreciseCarrierIdName()
+         * This is not a database column, only used to notify content observers for
+         * {@link #getPreciseCarrierIdUriForSubscriptionId(int)}
+         */
+        public static final String PRECISE_CARRIER_ID_NAME = "precise_carrier_id_name";
+
+        /**
          * A unique parent carrier id. The parent-child
          * relationship can be used to further differentiate a single carrier by different networks,
          * by prepaid v.s. postpaid or even by 4G v.s. 3G plan. It's an optional field.
@@ -3640,18 +3668,6 @@
         public static final String PARENT_CARRIER_ID = "parent_carrier_id";
 
         /**
-         * A unique mno carrier id. mno carrier shares the same {@link All#MCCMNC} as carrier id
-         * and can be solely identified by {@link All#MCCMNC} only. If there is no such mno
-         * carrier, then mno carrier id equals to {@link #CARRIER_ID carrier id}.
-         *
-         * <p>mno carrier id can be used as fallback id. When the exact carrier id configurations
-         * are not found, usually fall back to its mno carrier id.
-         * <P>Type: INTEGER </P>
-         * @hide
-         */
-        public static final String MNO_CARRIER_ID = "mno_carrier_id";
-
-        /**
          * Contains mappings between matching rules with carrier id for all carriers.
          * @hide
          */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index e72d67b..4561ea3 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -68,7 +68,13 @@
      * This intent is broadcast by the system when carrier config changes. An int is specified in
      * {@link #EXTRA_SLOT_INDEX} to indicate the slot index that this is for. An optional int extra
      * {@link #EXTRA_SUBSCRIPTION_INDEX} is included to indicate the subscription index if a valid
-     * one is available for the slot index.
+     * one is available for the slot index. An optional int extra
+     * {@link TelephonyManager#EXTRA_CARRIER_ID} is included to indicate the carrier id for the
+     * changed carrier configuration. An optional int extra
+     * {@link TelephonyManager#EXTRA_PRECISE_CARRIER_ID} is included to indicate the precise
+     * carrier id for the changed carrier configuration.
+     * @see TelephonyManager#getSimCarrierId()
+     * @see TelephonyManager#getSimPreciseCarrierId()
      */
     public static final String
             ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
@@ -81,7 +87,6 @@
      * Specifies a value that identifies the version of the carrier configuration that is
      * currently in use. This string is displayed on the UI.
      * The format of the string is not specified.
-     * @hide
      */
     public static final String KEY_CARRIER_CONFIG_VERSION_STRING =
             "carrier_config_version_string";
@@ -403,7 +408,6 @@
      * @see SubscriptionManager#getSubscriptionPlans(int)
      * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List)
      */
-    @SystemApi
     public static final String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING =
             "config_plans_package_override_string";
 
@@ -1394,9 +1398,9 @@
      * Example: "default"
      *
      * {@code ERROR_CODE_1} is an integer defined in
-     * {@link com.android.internal.telephony.dataconnection.DcFailCause DcFailure}
+     * {@link DataFailCause DcFailure}
      * Example:
-     * {@link com.android.internal.telephony.dataconnection.DcFailCause#MISSING_UNKNOWN_APN}
+     * {@link DataFailCause#MISSING_UNKNOWN_APN}
      *
      * {@code CARRIER_ACTION_IDX_1} is an integer defined in
      * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils}
@@ -1996,6 +2000,8 @@
      * Determine whether to use only RSRP for the number of LTE signal bars.
      * @hide
      */
+    // FIXME: this key and related keys must not be exposed without a consistent philosophy for
+    // all RATs.
     public static final String KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL =
             "use_only_rsrp_for_lte_signal_bar_bool";
 
@@ -2239,6 +2245,8 @@
      * Currently this only supports the value "rscp"
      * @hide
      */
+    // FIXME: this key and related keys must not be exposed without a consistent philosophy for
+    // all RATs.
     public static final String KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING =
             "wcdma_default_signal_strength_measurement_string";
 
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 598f567..fa19867 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -16,7 +16,6 @@
 
 package android.telephony;
 
-import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.telephony.cdma.CdmaCellLocation;
 
@@ -71,30 +70,13 @@
      *        to 2592000
      * @param lat Latitude is a decimal number ranges from -1296000
      *        to 1296000
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat) {
-        this(nid, sid, bid, lon, lat, null, null);
-    }
-
-    /**
-     * public constructor
-     * @param nid Network Id 0..65535
-     * @param sid CDMA System Id 0..32767
-     * @param bid Base Station Id 0..65535
-     * @param lon Longitude is a decimal number ranges from -2592000
-     *        to 2592000
-     * @param lat Latitude is a decimal number ranges from -1296000
-     *        to 1296000
      * @param alphal long alpha Operator Name String or Enhanced Operator Name String
      * @param alphas short alpha Operator Name String or Enhanced Operator Name String
      *
      * @hide
      */
-    public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat, String alphal,
-                             String alphas) {
+    public CellIdentityCdma(
+            int nid, int sid, int bid, int lon, int lat, String alphal, String alphas) {
         super(TAG, CellInfo.TYPE_CDMA, null, null, alphal, alphas);
         mNetworkId = nid;
         mSystemId = sid;
@@ -107,6 +89,17 @@
         }
     }
 
+    /** @hide */
+    public CellIdentityCdma(android.hardware.radio.V1_0.CellIdentityCdma cid) {
+        this(cid.networkId, cid.systemId, cid.baseStationId, cid.longitude, cid.latitude, "", "");
+    }
+
+    /** @hide */
+    public CellIdentityCdma(android.hardware.radio.V1_2.CellIdentityCdma cid) {
+        this(cid.base.networkId, cid.base.systemId, cid.base.baseStationId, cid.base.longitude,
+                cid.base.latitude, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
+    }
+
     private CellIdentityCdma(CellIdentityCdma cid) {
         this(cid.mNetworkId, cid.mSystemId, cid.mBasestationId, cid.mLongitude, cid.mLatitude,
                 cid.mAlphaLong, cid.mAlphaShort);
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 04c28e5..9a24e47 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
@@ -35,10 +36,8 @@
     // 16-bit GSM Cell Identity described in TS 27.007, 0..65535
     private final int mCid;
     // 16-bit GSM Absolute RF Channel Number
-    @UnsupportedAppUsage
     private final int mArfcn;
     // 6-bit Base Station Identity Code
-    @UnsupportedAppUsage
     private final int mBsic;
 
     /**
@@ -52,34 +51,6 @@
         mArfcn = CellInfo.UNAVAILABLE;
         mBsic = CellInfo.UNAVAILABLE;
     }
-    /**
-     * public constructor
-     * @param mcc 3-digit Mobile Country Code, 0..999
-     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
-     * @param lac 16-bit Location Area Code, 0..65535
-     * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity
-     *
-     * @hide
-     */
-    public CellIdentityGsm(int mcc, int mnc, int lac, int cid) {
-        this(lac, cid, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
-                String.valueOf(mcc), String.valueOf(mnc), null, null);
-    }
-
-    /**
-     * public constructor
-     * @param mcc 3-digit Mobile Country Code, 0..999
-     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
-     * @param lac 16-bit Location Area Code, 0..65535
-     * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity
-     * @param arfcn 16-bit GSM Absolute RF Channel Number
-     * @param bsic 6-bit Base Station Identity Code
-     *
-     * @hide
-     */
-    public CellIdentityGsm(int mcc, int mnc, int lac, int cid, int arfcn, int bsic) {
-        this(lac, cid, arfcn, bsic, String.valueOf(mcc), String.valueOf(mnc), null, null);
-    }
 
     /**
      * public constructor
@@ -100,9 +71,21 @@
         mLac = lac;
         mCid = cid;
         mArfcn = arfcn;
-        // In RIL BSIC is a UINT8, so 0xFF is the 'INVALID' designator
-        // for inbound parcels
-        mBsic = (bsic == 0xFF) ? CellInfo.UNAVAILABLE : bsic;
+        mBsic = bsic;
+    }
+
+    /** @hide */
+    public CellIdentityGsm(android.hardware.radio.V1_0.CellIdentityGsm cid) {
+        this(cid.lac, cid.cid, cid.arfcn,
+                cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic,
+                cid.mcc, cid.mnc, "", "");
+    }
+
+    /** @hide */
+    public CellIdentityGsm(android.hardware.radio.V1_2.CellIdentityGsm cid) {
+        this(cid.base.lac, cid.base.cid, cid.base.arfcn,
+                cid.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.bsic, cid.base.mcc,
+                cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
     }
 
     private CellIdentityGsm(CellIdentityGsm cid) {
@@ -169,6 +152,7 @@
     /**
      * @return a 5 or 6 character string (MCC+MNC), null if any field is unknown.
      */
+    @Nullable
     public String getMobileNetworkOperator() {
         return (mMccStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
     }
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 04b6a6c..d957d07 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
@@ -37,7 +38,6 @@
     // 16-bit tracking area code
     private final int mTac;
     // 18-bit Absolute RF Channel Number
-    @UnsupportedAppUsage
     private final int mEarfcn;
     // cell bandwidth, in kHz
     private final int mBandwidth;
@@ -73,22 +73,6 @@
 
     /**
      *
-     * @param mcc 3-digit Mobile Country Code, 0..999
-     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
-     * @param ci 28-bit Cell Identity
-     * @param pci Physical Cell Id 0..503
-     * @param tac 16-bit Tracking Area Code
-     * @param earfcn 18-bit LTE Absolute RF Channel Number
-     *
-     * @hide
-     */
-    public CellIdentityLte(int mcc, int mnc, int ci, int pci, int tac, int earfcn) {
-        this(ci, pci, tac, earfcn, CellInfo.UNAVAILABLE, String.valueOf(mcc), String.valueOf(mnc),
-                null, null);
-    }
-
-    /**
-     *
      * @param ci 28-bit Cell Identity
      * @param pci Physical Cell Id 0..503
      * @param tac 16-bit Tracking Area Code
@@ -111,6 +95,18 @@
         mBandwidth = bandwidth;
     }
 
+    /** @hide */
+    public CellIdentityLte(android.hardware.radio.V1_0.CellIdentityLte cid) {
+        this(cid.ci, cid.pci, cid.tac, cid.earfcn, CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "");
+    }
+
+    /** @hide */
+    public CellIdentityLte(android.hardware.radio.V1_2.CellIdentityLte cid) {
+        this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, cid.bandwidth,
+                cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
+                cid.operatorNames.alphaShort);
+    }
+
     private CellIdentityLte(CellIdentityLte cid) {
         this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBandwidth, cid.mMccStr,
                 cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
@@ -197,6 +193,7 @@
     /**
      * @return a 5 or 6 character string (MCC+MNC), null if any field is unknown.
      */
+    @Nullable
     public String getMobileNetworkOperator() {
         return (mMccStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
     }
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 8b1c1b9..3814333 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.Nullable;
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
 
@@ -50,22 +51,6 @@
     }
 
     /**
-     * @param mcc 3-digit Mobile Country Code, 0..999
-     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
-     * @param lac 16-bit Location Area Code, 0..65535, CellInfo.UNAVAILABLE if unknown
-     * @param cid 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, CellInfo.
-     *        UNAVAILABLE if unknown
-     * @param cpid 8-bit Cell Parameters ID described in TS 25.331, 0..127, CellInfo.UNAVAILABLE
-     *        if unknown
-     * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
-     *
-     * @hide
-     */
-    public CellIdentityTdscdma(int mcc, int mnc, int lac, int cid, int cpid, int uarfcn) {
-        this(String.valueOf(mcc), String.valueOf(mnc), lac, cid, cpid, uarfcn, null, null);
-    }
-
-    /**
      * @param mcc 3-digit Mobile Country Code in string format
      * @param mnc 2 or 3-digit Mobile Network Code in string format
      * @param lac 16-bit Location Area Code, 0..65535, CellInfo.UNAVAILABLE if unknown
@@ -93,6 +78,17 @@
                 cid.mCpid, cid.mUarfcn, cid.mAlphaLong, cid.mAlphaShort);
     }
 
+    /** @hide */
+    public CellIdentityTdscdma(android.hardware.radio.V1_0.CellIdentityTdscdma cid) {
+        this(cid.mcc, cid.mnc, cid.lac, cid.cid, cid.cpid, CellInfo.UNAVAILABLE, "", "");
+    }
+
+    /** @hide */
+    public CellIdentityTdscdma(android.hardware.radio.V1_2.CellIdentityTdscdma cid) {
+        this(cid.base.mcc, cid.base.mnc, cid.base.lac, cid.base.cid, cid.base.cpid,
+                cid.uarfcn, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
+    }
+
     CellIdentityTdscdma copy() {
         return new CellIdentityTdscdma(this);
     }
@@ -116,6 +112,7 @@
     /**
      * @return a 5 or 6 character string (MCC+MNC), null if any field is unknown
      */
+    @Nullable
     public String getMobileNetworkOperator() {
         return (mMccStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
     }
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 3416ffe..6e09784 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -16,6 +16,7 @@
 
 package android.telephony;
 
+import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
@@ -50,35 +51,6 @@
         mPsc = CellInfo.UNAVAILABLE;
         mUarfcn = CellInfo.UNAVAILABLE;
     }
-    /**
-     * public constructor
-     * @param mcc 3-digit Mobile Country Code, 0..999
-     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
-     * @param lac 16-bit Location Area Code, 0..65535
-     * @param cid 28-bit UMTS Cell Identity
-     * @param psc 9-bit UMTS Primary Scrambling Code
-     *
-     * @hide
-     */
-    public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc) {
-        this(lac, cid, psc, CellInfo.UNAVAILABLE, String.valueOf(mcc), String.valueOf(mnc),
-                null, null);
-    }
-
-    /**
-     * public constructor
-     * @param mcc 3-digit Mobile Country Code, 0..999
-     * @param mnc 2 or 3-digit Mobile Network Code, 0..999
-     * @param lac 16-bit Location Area Code, 0..65535
-     * @param cid 28-bit UMTS Cell Identity
-     * @param psc 9-bit UMTS Primary Scrambling Code
-     * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
-     *
-     * @hide
-     */
-    public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc, int uarfcn) {
-        this(lac, cid, psc, uarfcn, String.valueOf(mcc), String.valueOf(mnc), null, null);
-    }
 
     /**
      * public constructor
@@ -102,6 +74,18 @@
         mUarfcn = uarfcn;
     }
 
+    /** @hide */
+    public CellIdentityWcdma(android.hardware.radio.V1_0.CellIdentityWcdma cid) {
+        this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", "");
+    }
+
+    /** @hide */
+    public CellIdentityWcdma(android.hardware.radio.V1_2.CellIdentityWcdma cid) {
+        this(cid.base.lac, cid.base.cid, cid.base.psc, cid.base.uarfcn,
+                cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
+                cid.operatorNames.alphaShort);
+    }
+
     private CellIdentityWcdma(CellIdentityWcdma cid) {
         this(cid.mLac, cid.mCid, cid.mPsc, cid.mUarfcn, cid.mMccStr,
                 cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
@@ -173,6 +157,7 @@
     /**
      * @return a 5 or 6 character string (MCC+MNC), null if any field is unknown
      */
+    @Nullable
     public String getMobileNetworkOperator() {
         return (mMccStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
     }
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index d0b2687..b761bd7 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -132,7 +132,8 @@
     /** Connection status is unknown. */
     public static final int CONNECTION_UNKNOWN = Integer.MAX_VALUE;
 
-    private int mCellConnectionStatus = CONNECTION_NONE;
+    /** A cell connection status */
+    private int mCellConnectionStatus;
 
     // True if device is mRegistered to the mobile network
     private boolean mRegistered;
@@ -144,6 +145,7 @@
     protected CellInfo() {
         this.mRegistered = false;
         this.mTimeStamp = Long.MAX_VALUE;
+        mCellConnectionStatus = CONNECTION_NONE;
     }
 
     /** @hide */
@@ -300,4 +302,44 @@
             return new CellInfo[size];
         }
     };
+
+    /** @hide */
+    protected CellInfo(android.hardware.radio.V1_0.CellInfo ci) {
+        this.mRegistered = ci.registered;
+        this.mTimeStamp = ci.timeStamp;
+        this.mCellConnectionStatus = CONNECTION_UNKNOWN;
+    }
+
+    /** @hide */
+    protected CellInfo(android.hardware.radio.V1_2.CellInfo ci) {
+        this.mRegistered = ci.registered;
+        this.mTimeStamp = ci.timeStamp;
+        this.mCellConnectionStatus = ci.connectionStatus;
+    }
+
+    /** @hide */
+    public static CellInfo create(android.hardware.radio.V1_0.CellInfo ci) {
+        if (ci == null) return null;
+        switch(ci.cellInfoType) {
+            case android.hardware.radio.V1_0.CellInfoType.GSM: return new CellInfoGsm(ci);
+            case android.hardware.radio.V1_0.CellInfoType.CDMA: return new CellInfoCdma(ci);
+            case android.hardware.radio.V1_0.CellInfoType.LTE: return new CellInfoLte(ci);
+            case android.hardware.radio.V1_0.CellInfoType.WCDMA: return new CellInfoWcdma(ci);
+            case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA: return new CellInfoTdscdma(ci);
+            default: return null;
+        }
+    }
+
+    /** @hide */
+    public static CellInfo create(android.hardware.radio.V1_2.CellInfo ci) {
+        if (ci == null) return null;
+        switch(ci.cellInfoType) {
+            case android.hardware.radio.V1_0.CellInfoType.GSM: return new CellInfoGsm(ci);
+            case android.hardware.radio.V1_0.CellInfoType.CDMA: return new CellInfoCdma(ci);
+            case android.hardware.radio.V1_0.CellInfoType.LTE: return new CellInfoLte(ci);
+            case android.hardware.radio.V1_0.CellInfoType.WCDMA: return new CellInfoWcdma(ci);
+            case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA: return new CellInfoTdscdma(ci);
+            default: return null;
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index f67733d..8c76eae 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -48,6 +48,24 @@
         this.mCellSignalStrengthCdma = ci.mCellSignalStrengthCdma.copy();
     }
 
+    /** @hide */
+    public CellInfoCdma(android.hardware.radio.V1_0.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_0.CellInfoCdma cic = ci.cdma.get(0);
+        mCellIdentityCdma = new CellIdentityCdma(cic.cellIdentityCdma);
+        mCellSignalStrengthCdma =
+            new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo);
+    }
+
+    /** @hide */
+    public CellInfoCdma(android.hardware.radio.V1_2.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_2.CellInfoCdma cic = ci.cdma.get(0);
+        mCellIdentityCdma = new CellIdentityCdma(cic.cellIdentityCdma);
+        mCellSignalStrengthCdma =
+            new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo);
+    }
+
     @Override
     public CellIdentityCdma getCellIdentity() {
         return mCellIdentityCdma;
diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java
index 7211de1..ad16dfa 100644
--- a/telephony/java/android/telephony/CellInfoGsm.java
+++ b/telephony/java/android/telephony/CellInfoGsm.java
@@ -43,8 +43,24 @@
     /** @hide */
     public CellInfoGsm(CellInfoGsm ci) {
         super(ci);
-        this.mCellIdentityGsm = ci.mCellIdentityGsm.copy();
-        this.mCellSignalStrengthGsm = ci.mCellSignalStrengthGsm.copy();
+        mCellIdentityGsm = ci.mCellIdentityGsm.copy();
+        mCellSignalStrengthGsm = ci.mCellSignalStrengthGsm.copy();
+    }
+
+    /** @hide */
+    public CellInfoGsm(android.hardware.radio.V1_0.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_0.CellInfoGsm cig = ci.gsm.get(0);
+        mCellIdentityGsm = new CellIdentityGsm(cig.cellIdentityGsm);
+        mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm);
+    }
+
+    /** @hide */
+    public CellInfoGsm(android.hardware.radio.V1_2.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_2.CellInfoGsm cig = ci.gsm.get(0);
+        mCellIdentityGsm = new CellIdentityGsm(cig.cellIdentityGsm);
+        mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm);
     }
 
     @Override
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index 7d5388b..8ca6a1a 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -51,6 +51,24 @@
         this.mCellConfig = new CellConfigLte(ci.mCellConfig);
     }
 
+    /** @hide */
+    public CellInfoLte(android.hardware.radio.V1_0.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_0.CellInfoLte cil = ci.lte.get(0);
+        mCellIdentityLte = new CellIdentityLte(cil.cellIdentityLte);
+        mCellSignalStrengthLte = new CellSignalStrengthLte(cil.signalStrengthLte);
+        mCellConfig = new CellConfigLte();
+    }
+
+    /** @hide */
+    public CellInfoLte(android.hardware.radio.V1_2.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_2.CellInfoLte cil = ci.lte.get(0);
+        mCellIdentityLte = new CellIdentityLte(cil.cellIdentityLte);
+        mCellSignalStrengthLte = new CellSignalStrengthLte(cil.signalStrengthLte);
+        mCellConfig = new CellConfigLte();
+    }
+
     @Override
     public CellIdentityLte getCellIdentity() {
         if (DBG) log("getCellIdentity: " + mCellIdentityLte);
diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java
index 40cadde..a8c49b7 100644
--- a/telephony/java/android/telephony/CellInfoTdscdma.java
+++ b/telephony/java/android/telephony/CellInfoTdscdma.java
@@ -48,8 +48,23 @@
         this.mCellSignalStrengthTdscdma = ci.mCellSignalStrengthTdscdma.copy();
     }
 
-    @Override
-    public CellIdentityTdscdma getCellIdentity() {
+    /** @hide */
+    public CellInfoTdscdma(android.hardware.radio.V1_0.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_0.CellInfoTdscdma cit = ci.tdscdma.get(0);
+        mCellIdentityTdscdma = new CellIdentityTdscdma(cit.cellIdentityTdscdma);
+        mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma);
+    }
+
+    /** @hide */
+    public CellInfoTdscdma(android.hardware.radio.V1_2.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_2.CellInfoTdscdma cit = ci.tdscdma.get(0);
+        mCellIdentityTdscdma = new CellIdentityTdscdma(cit.cellIdentityTdscdma);
+        mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma);
+    }
+
+    @Override public CellIdentityTdscdma getCellIdentity() {
         return mCellIdentityTdscdma;
     }
     /** @hide */
diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java
index 4f9dcb1..a427e80 100644
--- a/telephony/java/android/telephony/CellInfoWcdma.java
+++ b/telephony/java/android/telephony/CellInfoWcdma.java
@@ -47,6 +47,22 @@
         this.mCellSignalStrengthWcdma = ci.mCellSignalStrengthWcdma.copy();
     }
 
+    /** @hide */
+    public CellInfoWcdma(android.hardware.radio.V1_0.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_0.CellInfoWcdma ciw = ci.wcdma.get(0);
+        mCellIdentityWcdma = new CellIdentityWcdma(ciw.cellIdentityWcdma);
+        mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma);
+    }
+
+    /** @hide */
+    public CellInfoWcdma(android.hardware.radio.V1_2.CellInfo ci) {
+        super(ci);
+        final android.hardware.radio.V1_2.CellInfoWcdma ciw = ci.wcdma.get(0);
+        mCellIdentityWcdma = new CellIdentityWcdma(ciw.cellIdentityWcdma);
+        mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma);
+    }
+
     @Override
     public CellIdentityWcdma getCellIdentity() {
         return mCellIdentityWcdma;
diff --git a/telephony/java/android/telephony/CellSignalStrength.java b/telephony/java/android/telephony/CellSignalStrength.java
index afa4922..a18275f 100644
--- a/telephony/java/android/telephony/CellSignalStrength.java
+++ b/telephony/java/android/telephony/CellSignalStrength.java
@@ -16,6 +16,8 @@
 
 package android.telephony;
 
+import android.os.PersistableBundle;
+
 /**
  * Abstract base class for cell phone signal strength related information.
  */
@@ -80,9 +82,74 @@
      */
     public abstract CellSignalStrength copy();
 
+    /**
+     * Checks and returns whether there are any non-default values in this CellSignalStrength.
+     *
+     * Checks all the values in the subclass of CellSignalStrength and returns true if any of them
+     * have been set to a value other than their default.
+     *
+     * @hide
+     */
+    public abstract boolean isValid();
+
     @Override
     public abstract int hashCode();
 
     @Override
     public abstract boolean equals (Object o);
+
+    /**
+     * Calculate and set the carrier-influenced values such as the signal "Level".
+     *
+     * @hide
+     */
+    public abstract void updateLevel(PersistableBundle cc, ServiceState ss);
+
+    // Range for RSSI in ASU (0-31, 99) as defined in TS 27.007 8.69
+    /** @hide */
+    protected static final int getRssiDbmFromAsu(int asu) {
+        if (asu > 31 || asu < 0) return CellInfo.UNAVAILABLE;
+        return -113 + (2 * asu);
+    }
+
+    // Range for RSSI in ASU (0-31, 99) as defined in TS 27.007 8.69
+    /** @hide */
+    protected static final int getAsuFromRssiDbm(int dbm) {
+        if (dbm == CellInfo.UNAVAILABLE) return 99;
+        return (dbm / 2) + 113;
+    }
+
+    // Range for RSCP in ASU (0-96, 255) as defined in TS 27.007 8.69
+    /** @hide */
+    protected static final int getRscpDbmFromAsu(int asu) {
+        if (asu > 96 || asu < 0) return CellInfo.UNAVAILABLE;
+        return asu - 120;
+    }
+
+    // Range for RSCP in ASU (0-96, 255) as defined in TS 27.007 8.69
+    /** @hide */
+    protected static final int getAsuFromRscpDbm(int dbm) {
+        if (dbm == CellInfo.UNAVAILABLE) return 255;
+        return dbm + 120;
+    }
+
+    // Range for SNR in ASU (0-49, 255) as defined in TS 27.007 8.69
+    /** @hide */
+    protected static final int getEcNoDbFromAsu(int asu) {
+        if (asu > 49 || asu < 0) return CellInfo.UNAVAILABLE;
+        return -24 + (asu / 2);
+    }
+
+    /** @hide */
+    protected static final int inRangeOrUnavailable(int value, int rangeMin, int rangeMax) {
+        if (value < rangeMin || value > rangeMax) return CellInfo.UNAVAILABLE;
+        return value;
+    }
+
+    /** @hide */
+    protected static final int inRangeOrUnavailable(
+            int value, int rangeMin, int rangeMax, int special) {
+        if ((value < rangeMin || value > rangeMax) && value != special) return CellInfo.UNAVAILABLE;
+        return value;
+    }
 }
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index 5123052..47faf1e 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.telephony.Rlog;
 
 import java.util.Objects;
@@ -35,6 +36,7 @@
     private int mEvdoDbm;   // This value is the EVDO RSSI value
     private int mEvdoEcio;  // This value is the EVDO Ec/Io
     private int mEvdoSnr;   // Valid values are 0-8.  8 is the highest signal to noise ratio
+    private int mLevel;
 
     /** @hide */
     public CellSignalStrengthCdma() {
@@ -55,23 +57,29 @@
      * rather than left as -1, which is a departure from SignalStrength, which is stuck with the
      * values it currently reports.
      *
-     * @param cdmaDbm negative of the CDMA signal strength value or -1 if invalid.
-     * @param cdmaEcio negative of the CDMA pilot/noise ratio or -1 if invalid.
-     * @param evdoDbm negative of the EvDO signal strength value or -1 if invalid.
-     * @param evdoEcio negative of the EvDO pilot/noise ratio or -1 if invalid.
-     * @param evdoSnr an SNR value 0..8 or -1 if invalid.
+     * @param cdmaDbm CDMA signal strength value or CellInfo.UNAVAILABLE if invalid.
+     * @param cdmaEcio CDMA pilot/noise ratio or CellInfo.UNAVAILABLE  if invalid.
+     * @param evdoDbm negative of the EvDO signal strength value or CellInfo.UNAVAILABLE if invalid.
+     * @param evdoEcio negative of the EvDO pilot/noise ratio or CellInfo.UNAVAILABLE if invalid.
+     * @param evdoSnr an SNR value 0..8 or CellInfo.UNVAILABLE if invalid.
      * @hide
      */
     public CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio,
             int evdoSnr) {
-        // The values here were lifted from SignalStrength.validateInput()
-        // FIXME: Combine all checking and setting logic between this and SignalStrength.
-        mCdmaDbm = ((cdmaDbm > 0) && (cdmaDbm < 120))  ? -cdmaDbm : CellInfo.UNAVAILABLE;
-        mCdmaEcio = ((cdmaEcio > 0) && (cdmaEcio < 160)) ? -cdmaEcio : CellInfo.UNAVAILABLE;
+        mCdmaDbm = inRangeOrUnavailable(cdmaDbm, -120, 0);
+        mCdmaEcio = inRangeOrUnavailable(cdmaEcio, -160, 0);
+        mEvdoDbm = inRangeOrUnavailable(evdoDbm, -120, 0);
+        mEvdoEcio = inRangeOrUnavailable(evdoEcio, -160, 0);
+        mEvdoSnr = inRangeOrUnavailable(evdoSnr, 0, 8);
 
-        mEvdoDbm = ((evdoDbm > 0) && (evdoDbm < 120)) ? -evdoDbm : CellInfo.UNAVAILABLE;
-        mEvdoEcio = ((evdoEcio > 0) && (evdoEcio < 160)) ? -evdoEcio : CellInfo.UNAVAILABLE;
-        mEvdoSnr = ((evdoSnr > 0) && (evdoSnr <= 8)) ? evdoSnr : CellInfo.UNAVAILABLE;
+        updateLevel(null, null);
+    }
+
+    /** @hide */
+    public CellSignalStrengthCdma(android.hardware.radio.V1_0.CdmaSignalStrength cdma,
+            android.hardware.radio.V1_0.EvdoSignalStrength evdo) {
+        // Convert from HAL values as part of construction.
+        this(-cdma.dbm, -cdma.ecio, -evdo.dbm, -evdo.ecio, evdo.signalNoiseRatio);
     }
 
     /** @hide */
@@ -86,6 +94,7 @@
         mEvdoDbm = s.mEvdoDbm;
         mEvdoEcio = s.mEvdoEcio;
         mEvdoSnr = s.mEvdoSnr;
+        mLevel = s.mLevel;
     }
 
     /** @hide */
@@ -102,6 +111,7 @@
         mEvdoDbm = CellInfo.UNAVAILABLE;
         mEvdoEcio = CellInfo.UNAVAILABLE;
         mEvdoSnr = CellInfo.UNAVAILABLE;
+        mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     }
 
     /**
@@ -112,26 +122,54 @@
      */
     @Override
     public int getLevel() {
-        int level;
+        return mLevel;
+    }
 
+    /** @hide */
+    @Override
+    public void updateLevel(PersistableBundle cc, ServiceState ss) {
         int cdmaLevel = getCdmaLevel();
         int evdoLevel = getEvdoLevel();
         if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
             /* We don't know evdo, use cdma */
-            level = getCdmaLevel();
+            mLevel = getCdmaLevel();
         } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
             /* We don't know cdma, use evdo */
-            level = getEvdoLevel();
+            mLevel = getEvdoLevel();
         } else {
             /* We know both, use the lowest level */
-            level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
+            mLevel = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
         }
-        if (DBG) log("getLevel=" + level);
-        return level;
     }
 
     /**
-     * Get the signal level as an asu value between 0..97, 99 is unknown
+     * Get the 1xRTT Level in (Android) ASU.
+     *
+     * There is no standard definition of ASU for CDMA; however, Android defines it as the
+     * the lesser of the following two results (for 1xRTT):
+     * <table>
+     *     <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead>
+     *     <tbody>
+     *         <tr><td>-75..</td><td>16</td></tr>
+     *         <tr><td>-82..-76</td><td>8</td></tr>
+     *         <tr><td>-90..-83</td><td>4</td></tr>
+     *         <tr><td>-95..-91</td><td>2</td></tr>
+     *         <tr><td>-100..-96</td><td>1</td></tr>
+     *         <tr><td>..-101</td><td>99</td></tr>
+     *     </tbody>
+     * </table>
+     * <table>
+     *     <thead><tr><th>Ec/Io Range (dB)</th><th>ASU Value</th></tr><thead>
+     *     <tbody>
+     *         <tr><td>-90..</td><td>16</td></tr>
+     *         <tr><td>-100..-91</td><td>8</td></tr>
+     *         <tr><td>-115..-101</td><td>4</td></tr>
+     *         <tr><td>-130..-116</td><td>2</td></tr>
+     *         <tr><td>--150..-131</td><td>1</td></tr>
+     *         <tr><td>..-151</td><td>99</td></tr>
+     *     </tbody>
+     * </table>
+     * @return 1xRTT Level in Android ASU {1,2,4,8,16,99}
      */
     @Override
     public int getAsuLevel() {
@@ -220,6 +258,63 @@
     }
 
     /**
+     * Get the EVDO Level in (Android) ASU.
+     *
+     * There is no standard definition of ASU for CDMA; however, Android defines it as the
+     * the lesser of the following two results (for EVDO):
+     * <table>
+     *     <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead>
+     *     <tbody>
+     *         <tr><td>-65..</td><td>16</td></tr>
+     *         <tr><td>-75..-66</td><td>8</td></tr>
+     *         <tr><td>-85..-76</td><td>4</td></tr>
+     *         <tr><td>-95..-86</td><td>2</td></tr>
+     *         <tr><td>-105..-96</td><td>1</td></tr>
+     *         <tr><td>..-106</td><td>99</td></tr>
+     *     </tbody>
+     * </table>
+     * <table>
+     *     <thead><tr><th>SNR Range (unitless)</th><th>ASU Value</th></tr><thead>
+     *     <tbody>
+     *         <tr><td>7..</td><td>16</td></tr>
+     *         <tr><td>6</td><td>8</td></tr>
+     *         <tr><td>5</td><td>4</td></tr>
+     *         <tr><td>3..4</td><td>2</td></tr>
+     *         <tr><td>1..2</td><td>1</td></tr>
+     *         <tr><td>0</td><td>99</td></tr>
+     *     </tbody>
+     * </table>
+     *
+     * @return EVDO Level in Android ASU {1,2,4,8,16,99}
+     *
+     * @hide
+     */
+    public int getEvdoAsuLevel() {
+        int evdoDbm = getEvdoDbm();
+        int evdoSnr = getEvdoSnr();
+        int levelEvdoDbm;
+        int levelEvdoSnr;
+
+        if (evdoDbm >= -65) levelEvdoDbm = 16;
+        else if (evdoDbm >= -75) levelEvdoDbm = 8;
+        else if (evdoDbm >= -85) levelEvdoDbm = 4;
+        else if (evdoDbm >= -95) levelEvdoDbm = 2;
+        else if (evdoDbm >= -105) levelEvdoDbm = 1;
+        else levelEvdoDbm = 99;
+
+        if (evdoSnr >= 7) levelEvdoSnr = 16;
+        else if (evdoSnr >= 6) levelEvdoSnr = 8;
+        else if (evdoSnr >= 5) levelEvdoSnr = 4;
+        else if (evdoSnr >= 3) levelEvdoSnr = 2;
+        else if (evdoSnr >= 1) levelEvdoSnr = 1;
+        else levelEvdoSnr = 99;
+
+        int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
+        if (DBG) log("getEvdoAsuLevel=" + level);
+        return level;
+    }
+
+    /**
      * Get the signal strength as dBm
      */
     @Override
@@ -237,6 +332,7 @@
     public int getCdmaDbm() {
         return mCdmaDbm;
     }
+
     /** @hide */
     public void setCdmaDbm(int cdmaDbm) {
         mCdmaDbm = cdmaDbm;
@@ -248,6 +344,7 @@
     public int getCdmaEcio() {
         return mCdmaEcio;
     }
+
     /** @hide */
     public void setCdmaEcio(int cdmaEcio) {
         mCdmaEcio = cdmaEcio;
@@ -259,6 +356,7 @@
     public int getEvdoDbm() {
         return mEvdoDbm;
     }
+
     /** @hide */
     public void setEvdoDbm(int evdoDbm) {
         mEvdoDbm = evdoDbm;
@@ -270,6 +368,7 @@
     public int getEvdoEcio() {
         return mEvdoEcio;
     }
+
     /** @hide */
     public void setEvdoEcio(int evdoEcio) {
         mEvdoEcio = evdoEcio;
@@ -281,6 +380,7 @@
     public int getEvdoSnr() {
         return mEvdoSnr;
     }
+
     /** @hide */
     public void setEvdoSnr(int evdoSnr) {
         mEvdoSnr = evdoSnr;
@@ -288,28 +388,29 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mCdmaDbm, mCdmaEcio, mEvdoDbm, mEvdoEcio, mEvdoSnr);
+        return Objects.hash(mCdmaDbm, mCdmaEcio, mEvdoDbm, mEvdoEcio, mEvdoSnr, mLevel);
+    }
+
+    private static final CellSignalStrengthCdma sInvalid = new CellSignalStrengthCdma();
+
+    /** @hide */
+    @Override
+    public boolean isValid() {
+        return !this.equals(sInvalid);
     }
 
     @Override
     public boolean equals (Object o) {
         CellSignalStrengthCdma s;
-
-        try {
-            s = (CellSignalStrengthCdma) o;
-        } catch (ClassCastException ex) {
-            return false;
-        }
-
-        if (o == null) {
-            return false;
-        }
+        if (!(o instanceof CellSignalStrengthCdma)) return false;
+        s = (CellSignalStrengthCdma) o;
 
         return mCdmaDbm == s.mCdmaDbm
                 && mCdmaEcio == s.mCdmaEcio
                 && mEvdoDbm == s.mEvdoDbm
                 && mEvdoEcio == s.mEvdoEcio
-                && mEvdoSnr == s.mEvdoSnr;
+                && mEvdoSnr == s.mEvdoSnr
+                && mLevel == s.mLevel;
     }
 
     /**
@@ -322,7 +423,8 @@
                 + " cdmaEcio=" + mCdmaEcio
                 + " evdoDbm=" + mEvdoDbm
                 + " evdoEcio=" + mEvdoEcio
-                + " evdoSnr=" + mEvdoSnr;
+                + " evdoSnr=" + mEvdoSnr
+                + " level=" + mLevel;
     }
 
     /** Implement the Parcelable interface */
@@ -334,6 +436,7 @@
         dest.writeInt(mEvdoDbm);
         dest.writeInt(mEvdoEcio);
         dest.writeInt(mEvdoSnr);
+        dest.writeInt(mLevel);
     }
 
     /**
@@ -349,6 +452,7 @@
         mEvdoDbm = in.readInt();
         mEvdoEcio = in.readInt();
         mEvdoSnr = in.readInt();
+        mLevel = in.readInt();
         if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString());
     }
 
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index e906f46..7b29f69 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -19,6 +19,7 @@
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.telephony.Rlog;
 
 import java.util.Objects;
@@ -31,16 +32,18 @@
     private static final String LOG_TAG = "CellSignalStrengthGsm";
     private static final boolean DBG = false;
 
-    private static final int GSM_SIGNAL_STRENGTH_GREAT = 12;
-    private static final int GSM_SIGNAL_STRENGTH_GOOD = 8;
-    private static final int GSM_SIGNAL_STRENGTH_MODERATE = 5;
+    private static final int GSM_RSSI_MAX = -51;
+    private static final int GSM_RSSI_GREAT = -89;
+    private static final int GSM_RSSI_GOOD = -97;
+    private static final int GSM_RSSI_MODERATE = -103;
+    private static final int GSM_RSSI_POOR = -107;
 
+    private int mRssi; // in dBm [-113, -51] or UNAVAILABLE
     @UnsupportedAppUsage
-    private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
-    @UnsupportedAppUsage
-    private int mBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
-    @UnsupportedAppUsage
+    private int mBitErrorRate; // bit error rate (0-7, 99) TS 27.007 8.5 or UNAVAILABLE
+    @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
     private int mTimingAdvance; // range from 0-219 or CellInfo.UNAVAILABLE if unknown
+    private int mLevel;
 
     /** @hide */
     @UnsupportedAppUsage
@@ -49,15 +52,17 @@
     }
 
     /** @hide */
-    public CellSignalStrengthGsm(int ss, int ber) {
-        this(ss, ber, CellInfo.UNAVAILABLE);
+    public CellSignalStrengthGsm(int rssi, int ber, int ta) {
+        mRssi = inRangeOrUnavailable(rssi, -113, -51);
+        mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99);
+        mTimingAdvance = inRangeOrUnavailable(ta, 0, 219);
+        updateLevel(null, null);
     }
 
     /** @hide */
-    public CellSignalStrengthGsm(int ss, int ber, int ta) {
-        mSignalStrength = ss;
-        mBitErrorRate = ber;
-        mTimingAdvance = ta;
+    public CellSignalStrengthGsm(android.hardware.radio.V1_0.GsmSignalStrength gsm) {
+        // Convert from HAL values as part of construction.
+        this(getRssiDbmFromAsu(gsm.signalStrength), gsm.bitErrorRate, gsm.timingAdvance);
     }
 
     /** @hide */
@@ -67,9 +72,10 @@
 
     /** @hide */
     protected void copyFrom(CellSignalStrengthGsm s) {
-        mSignalStrength = s.mSignalStrength;
+        mRssi = s.mRssi;
         mBitErrorRate = s.mBitErrorRate;
         mTimingAdvance = s.mTimingAdvance;
+        mLevel = s.mLevel;
     }
 
     /** @hide */
@@ -81,9 +87,10 @@
     /** @hide */
     @Override
     public void setDefaultValues() {
-        mSignalStrength = CellInfo.UNAVAILABLE;
+        mRssi = CellInfo.UNAVAILABLE;
         mBitErrorRate = CellInfo.UNAVAILABLE;
         mTimingAdvance = CellInfo.UNAVAILABLE;
+        mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     }
 
     /**
@@ -94,20 +101,18 @@
      */
     @Override
     public int getLevel() {
-        int level;
+        return mLevel;
+    }
 
-        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
-        // asu = 0 (-113dB or less) is very weak
-        // signal, its better to show 0 bars to the user in such cases.
-        // asu = 99 is a special case, where the signal strength is unknown.
-        int asu = mSignalStrength;
-        if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-        else if (asu >= GSM_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT;
-        else if (asu >= GSM_SIGNAL_STRENGTH_GOOD)  level = SIGNAL_STRENGTH_GOOD;
-        else if (asu >= GSM_SIGNAL_STRENGTH_MODERATE)  level = SIGNAL_STRENGTH_MODERATE;
-        else level = SIGNAL_STRENGTH_POOR;
-        if (DBG) log("getLevel=" + level);
-        return level;
+    /** @hide */
+    @Override
+    public void updateLevel(PersistableBundle cc, ServiceState ss) {
+        if (mRssi > GSM_RSSI_MAX) mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        else if (mRssi >= GSM_RSSI_GREAT) mLevel = SIGNAL_STRENGTH_GREAT;
+        else if (mRssi >= GSM_RSSI_GOOD)  mLevel = SIGNAL_STRENGTH_GOOD;
+        else if (mRssi >= GSM_RSSI_MODERATE)  mLevel = SIGNAL_STRENGTH_MODERATE;
+        else if (mRssi >= GSM_RSSI_POOR) mLevel = SIGNAL_STRENGTH_POOR;
+        else mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     }
 
     /**
@@ -126,55 +131,52 @@
      */
     @Override
     public int getDbm() {
-        int dBm;
-
-        int level = mSignalStrength;
-        int asu = (level == 99 ? CellInfo.UNAVAILABLE : level);
-        if (asu != CellInfo.UNAVAILABLE) {
-            dBm = -113 + (2 * asu);
-        } else {
-            dBm = CellInfo.UNAVAILABLE;
-        }
-        if (DBG) log("getDbm=" + dBm);
-        return dBm;
+        return mRssi;
     }
 
     /**
-     * Get the signal level as an asu value between 0..31, 99 is unknown
+     * Get the RSSI in ASU.
+     *
      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+     *
+     * @return RSSI in ASU 0..31, 99, or UNAVAILABLE
      */
     @Override
     public int getAsuLevel() {
-        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
-        // asu = 0 (-113dB or less) is very weak
-        // signal, its better to show 0 bars to the user in such cases.
-        // asu = 99 is a special case, where the signal strength is unknown.
-        int level = mSignalStrength;
-        if (DBG) log("getAsuLevel=" + level);
-        return level;
+        return getAsuFromRssiDbm(mRssi);
+    }
+
+    /**
+     * Return the Bit Error Rate
+     * @returns the bit error rate (0-7, 99) as defined in TS 27.007 8.5 or UNAVAILABLE.
+     * @hide
+     */
+    public int getBitErrorRate() {
+        return mBitErrorRate;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mSignalStrength, mBitErrorRate, mTimingAdvance);
+        return Objects.hash(mRssi, mBitErrorRate, mTimingAdvance);
+    }
+
+    private static final CellSignalStrengthGsm sInvalid = new CellSignalStrengthGsm();
+
+    /** @hide */
+    @Override
+    public boolean isValid() {
+        return !this.equals(sInvalid);
     }
 
     @Override
-    public boolean equals (Object o) {
-        CellSignalStrengthGsm s;
+    public boolean equals(Object o) {
+        if (!(o instanceof CellSignalStrengthGsm)) return false;
+        CellSignalStrengthGsm s = (CellSignalStrengthGsm) o;
 
-        try {
-            s = (CellSignalStrengthGsm) o;
-        } catch (ClassCastException ex) {
-            return false;
-        }
-
-        if (o == null) {
-            return false;
-        }
-
-        return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate &&
-                        s.mTimingAdvance == mTimingAdvance;
+        return mRssi == s.mRssi
+                && mBitErrorRate == s.mBitErrorRate
+                && mTimingAdvance == s.mTimingAdvance
+                && mLevel == s.mLevel;
     }
 
     /**
@@ -183,18 +185,20 @@
     @Override
     public String toString() {
         return "CellSignalStrengthGsm:"
-                + " ss=" + mSignalStrength
+                + " rssi=" + mRssi
                 + " ber=" + mBitErrorRate
-                + " mTa=" + mTimingAdvance;
+                + " mTa=" + mTimingAdvance
+                + " mLevel=" + mLevel;
     }
 
     /** Implement the Parcelable interface */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         if (DBG) log("writeToParcel(Parcel, int): " + toString());
-        dest.writeInt(mSignalStrength);
+        dest.writeInt(mRssi);
         dest.writeInt(mBitErrorRate);
         dest.writeInt(mTimingAdvance);
+        dest.writeInt(mLevel);
     }
 
     /**
@@ -202,9 +206,10 @@
      * where the token is already been processed.
      */
     private CellSignalStrengthGsm(Parcel in) {
-        mSignalStrength = in.readInt();
+        mRssi = in.readInt();
         mBitErrorRate = in.readInt();
         mTimingAdvance = in.readInt();
+        mLevel = in.readInt();
         if (DBG) log("CellSignalStrengthGsm(Parcel): " + toString());
     }
 
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index d075394..893dbe3 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -19,7 +19,9 @@
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 
+import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -28,7 +30,7 @@
 public final class CellSignalStrengthLte extends CellSignalStrength implements Parcelable {
 
     private static final String LOG_TAG = "CellSignalStrengthLte";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
 
     /**
      * Indicates the unknown or undetectable RSSI value in ASU.
@@ -49,18 +51,23 @@
      */
     private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0;
 
-    @UnsupportedAppUsage
-    private int mSignalStrength;
-    @UnsupportedAppUsage
+    private static final int MAX_LTE_RSRP = -44;
+    private static final int MIN_LTE_RSRP = -140;
+
+    @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
+    private int mSignalStrength; // To be removed
+    private int mRssi;
+    @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
     private int mRsrp;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
     private int mRsrq;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
     private int mRssnr;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
     private int mCqi;
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
     private int mTimingAdvance;
+    private int mLevel;
 
     /** @hide */
     @UnsupportedAppUsage
@@ -68,15 +75,38 @@
         setDefaultValues();
     }
 
+    /**
+     * Construct a cell signal strength
+     *
+     * @param rssi in dBm [-113,-51], UNKNOWN
+     * @param rsrp in dBm [-140,-43], UNKNOWN
+     * @param rsrq in dB [-20,-3], UNKNOWN
+     * @param rssnr in 10*dB [-200, +300], UNKNOWN
+     * @param cqi [0, 15], UNKNOWN
+     * @param timingAdvance [0, 1282], UNKNOWN
+     *
+     */
     /** @hide */
-    public CellSignalStrengthLte(int signalStrength, int rsrp, int rsrq, int rssnr, int cqi,
+    public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi,
             int timingAdvance) {
-        mSignalStrength = signalStrength;
-        mRsrp = rsrp;
-        mRsrq = rsrq;
-        mRssnr = rssnr;
-        mCqi = cqi;
-        mTimingAdvance = timingAdvance;
+
+        mRssi = inRangeOrUnavailable(rssi, -113, -51);
+        mSignalStrength = mRssi;
+        mRsrp = inRangeOrUnavailable(rsrp, -140, -43);
+        mRsrq = inRangeOrUnavailable(rsrq, -20, -3);
+        mRssnr = inRangeOrUnavailable(rssnr, -200, 300);
+        mCqi = inRangeOrUnavailable(cqi, 0, 15);
+        mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282);
+        updateLevel(null, null);
+    }
+
+    /** @hide */
+    public CellSignalStrengthLte(android.hardware.radio.V1_0.LteSignalStrength lte) {
+        // Convert from HAL values as part of construction.
+        this(convertRssiAsuToDBm(lte.signalStrength),
+                lte.rsrp != CellInfo.UNAVAILABLE ? -lte.rsrp : lte.rsrp,
+                lte.rsrq != CellInfo.UNAVAILABLE ? -lte.rsrq : lte.rsrq,
+                lte.rssnr, lte.cqi, lte.timingAdvance);
     }
 
     /** @hide */
@@ -87,11 +117,13 @@
     /** @hide */
     protected void copyFrom(CellSignalStrengthLte s) {
         mSignalStrength = s.mSignalStrength;
+        mRssi = s.mRssi;
         mRsrp = s.mRsrp;
         mRsrq = s.mRsrq;
         mRssnr = s.mRssnr;
         mCqi = s.mCqi;
         mTimingAdvance = s.mTimingAdvance;
+        mLevel = s.mLevel;
     }
 
     /** @hide */
@@ -104,11 +136,13 @@
     @Override
     public void setDefaultValues() {
         mSignalStrength = CellInfo.UNAVAILABLE;
+        mRssi = CellInfo.UNAVAILABLE;
         mRsrp = CellInfo.UNAVAILABLE;
         mRsrq = CellInfo.UNAVAILABLE;
         mRssnr = CellInfo.UNAVAILABLE;
         mCqi = CellInfo.UNAVAILABLE;
         mTimingAdvance = CellInfo.UNAVAILABLE;
+        mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     }
 
     /**
@@ -119,34 +153,106 @@
      */
     @Override
     public int getLevel() {
-        int levelRsrp = 0;
-        int levelRssnr = 0;
+        return mLevel;
+    }
 
-        if (mRsrp == CellInfo.UNAVAILABLE) levelRsrp = 0;
-        else if (mRsrp >= -95) levelRsrp = SIGNAL_STRENGTH_GREAT;
-        else if (mRsrp >= -105) levelRsrp = SIGNAL_STRENGTH_GOOD;
-        else if (mRsrp >= -115) levelRsrp = SIGNAL_STRENGTH_MODERATE;
-        else levelRsrp = SIGNAL_STRENGTH_POOR;
+    // Lifted from Default carrier configs and max range of RSRP
+    private static final int[] sThresholds = new int[]{-115, -105, -95, -85};
+    private static final int sRsrpBoost = 0;
 
-        // See RIL_LTE_SignalStrength in ril.h
-        if (mRssnr == CellInfo.UNAVAILABLE) levelRssnr = 0;
-        else if (mRssnr >= 45) levelRssnr = SIGNAL_STRENGTH_GREAT;
-        else if (mRssnr >= 10) levelRssnr = SIGNAL_STRENGTH_GOOD;
-        else if (mRssnr >= -30) levelRssnr = SIGNAL_STRENGTH_MODERATE;
-        else levelRssnr = SIGNAL_STRENGTH_POOR;
-
-        int level;
-        if (mRsrp == CellInfo.UNAVAILABLE) {
-            level = levelRssnr;
-        } else if (mRssnr == CellInfo.UNAVAILABLE) {
-            level = levelRsrp;
+    /** @hide */
+    @Override
+    public void updateLevel(PersistableBundle cc, ServiceState ss) {
+        int[] thresholds;
+        boolean rsrpOnly;
+        if (cc == null) {
+            thresholds = sThresholds;
+            rsrpOnly = false;
         } else {
-            level = (levelRssnr < levelRsrp) ? levelRssnr : levelRsrp;
+            rsrpOnly = cc.getBoolean(
+                    CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL, false);
+            thresholds = cc.getIntArray(
+                    CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY);
+            if (thresholds == null) thresholds = sThresholds;
+            if (DBG) log("updateLevel() carrierconfig - rsrpOnly="
+                    + rsrpOnly + ", thresholds=" + Arrays.toString(thresholds));
         }
 
-        if (DBG) log("Lte rsrp level: " + levelRsrp
-                + " snr level: " + levelRssnr + " level: " + level);
-        return level;
+
+        int rsrpBoost = 0;
+        if (ss != null) {
+            rsrpBoost = ss.getLteEarfcnRsrpBoost();
+        }
+
+        int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        int rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        int snrIconLevel = -1;
+
+        int rsrp = mRsrp + rsrpBoost;
+
+        if (rsrp < MIN_LTE_RSRP || rsrp > MAX_LTE_RSRP) {
+            rsrpIconLevel = -1;
+        } else {
+            rsrpIconLevel = thresholds.length;
+            while (rsrpIconLevel > 0 && rsrp < thresholds[rsrpIconLevel - 1]) rsrpIconLevel--;
+        }
+
+        if (rsrpOnly) {
+            if (DBG) log("updateLevel() - rsrp = " + rsrpIconLevel);
+            if (rsrpIconLevel != -1) {
+                mLevel = rsrpIconLevel;
+                return;
+            }
+        }
+
+        /*
+         * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
+         * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
+         * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
+         * Icon Only
+         */
+        if (mRssnr > 300) snrIconLevel = -1;
+        else if (mRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
+        else if (mRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
+        else if (mRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
+        else if (mRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
+        else if (mRssnr >= -200)
+            snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+        if (DBG) log("updateLevel() - rsrp:" + mRsrp + " snr:" + mRssnr + " rsrpIconLevel:"
+                + rsrpIconLevel + " snrIconLevel:" + snrIconLevel
+                + " lteRsrpBoost:" + sRsrpBoost);
+
+        /* Choose a measurement type to use for notification */
+        if (snrIconLevel != -1 && rsrpIconLevel != -1) {
+            /*
+             * The number of bars displayed shall be the smaller of the bars
+             * associated with LTE RSRP and the bars associated with the LTE
+             * RS_SNR
+             */
+            mLevel = (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
+            return;
+        }
+
+        if (snrIconLevel != -1) {
+            mLevel = snrIconLevel;
+            return;
+        }
+
+        if (rsrpIconLevel != -1) {
+            mLevel = rsrpIconLevel;
+            return;
+        }
+
+        if (mRssi > -51) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        else if (mRssi >= -89) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
+        else if (mRssi >= -97) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
+        else if (mRssi >= -103) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
+        else if (mRssi >= -113) rssiIconLevel = SIGNAL_STRENGTH_POOR;
+        else rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        if (DBG) log("getLteLevel - rssi:" + mRssi + " rssiIconLevel:"
+                + rssiIconLevel);
+        mLevel = rssiIconLevel;
     }
 
     /**
@@ -169,7 +275,7 @@
      * @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable.
      */
     public int getRssi() {
-        return convertRssiAsuToDBm(mSignalStrength);
+        return mRssi;
     }
 
     /**
@@ -212,13 +318,16 @@
     }
 
     /**
-     * Get the LTE signal level as an asu value between 0..97, 99 is unknown
+     * Get the RSRP in ASU.
+     *
      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+     *
+     * @return RSCP in ASU 0..97, 255, or UNAVAILABLE
      */
     @Override
     public int getAsuLevel() {
         int lteAsuLevel = 99;
-        int lteDbm = getDbm();
+        int lteDbm = mRsrp;
         if (lteDbm == CellInfo.UNAVAILABLE) lteAsuLevel = 99;
         else if (lteDbm <= -140) lteAsuLevel = 0;
         else if (lteDbm >= -43) lteAsuLevel = 97;
@@ -241,29 +350,31 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mSignalStrength, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance);
+        return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance, mLevel);
+    }
+
+    private static final CellSignalStrengthLte sInvalid = new CellSignalStrengthLte();
+
+    /** @hide */
+    @Override
+    public boolean isValid() {
+        return !this.equals(sInvalid);
     }
 
     @Override
     public boolean equals (Object o) {
         CellSignalStrengthLte s;
 
-        try {
-            s = (CellSignalStrengthLte) o;
-        } catch (ClassCastException ex) {
-            return false;
-        }
+        if (!(o instanceof CellSignalStrengthLte)) return false;
+        s = (CellSignalStrengthLte) o;
 
-        if (o == null) {
-            return false;
-        }
-
-        return mSignalStrength == s.mSignalStrength
+        return mRssi == s.mRssi
                 && mRsrp == s.mRsrp
                 && mRsrq == s.mRsrq
                 && mRssnr == s.mRssnr
                 && mCqi == s.mCqi
-                && mTimingAdvance == s.mTimingAdvance;
+                && mTimingAdvance == s.mTimingAdvance
+                && mLevel == s.mLevel;
     }
 
     /**
@@ -272,27 +383,29 @@
     @Override
     public String toString() {
         return "CellSignalStrengthLte:"
-                + " ss=" + mSignalStrength
+                + " rssi=" + mRssi
                 + " rsrp=" + mRsrp
                 + " rsrq=" + mRsrq
                 + " rssnr=" + mRssnr
                 + " cqi=" + mCqi
-                + " ta=" + mTimingAdvance;
+                + " ta=" + mTimingAdvance
+                + " level=" + mLevel;
     }
 
     /** Implement the Parcelable interface */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         if (DBG) log("writeToParcel(Parcel, int): " + toString());
-        dest.writeInt(mSignalStrength);
+        dest.writeInt(mRssi);
         // Need to multiply rsrp and rsrq by -1
         // to ensure consistency when reading values written here
         // unless the values are invalid
-        dest.writeInt(mRsrp * (mRsrp != CellInfo.UNAVAILABLE ? -1 : 1));
-        dest.writeInt(mRsrq * (mRsrq != CellInfo.UNAVAILABLE ? -1 : 1));
+        dest.writeInt(mRsrp);
+        dest.writeInt(mRsrq);
         dest.writeInt(mRssnr);
         dest.writeInt(mCqi);
         dest.writeInt(mTimingAdvance);
+        dest.writeInt(mLevel);
     }
 
     /**
@@ -300,16 +413,14 @@
      * where the token is already been processed.
      */
     private CellSignalStrengthLte(Parcel in) {
-        mSignalStrength = in.readInt();
-        // rsrp and rsrq are written into the parcel as positive values.
-        // Need to convert into negative values unless the values are invalid
+        mRssi = in.readInt();
+        mSignalStrength = mRssi;
         mRsrp = in.readInt();
-        if (mRsrp != CellInfo.UNAVAILABLE) mRsrp *= -1;
         mRsrq = in.readInt();
-        if (mRsrq != CellInfo.UNAVAILABLE) mRsrq *= -1;
         mRssnr = in.readInt();
         mCqi = in.readInt();
         mTimingAdvance = in.readInt();
+        mLevel = in.readInt();
         if (DBG) log("CellSignalStrengthLte(Parcel): " + toString());
     }
 
@@ -342,13 +453,12 @@
     }
 
     private static int convertRssiAsuToDBm(int rssiAsu) {
-        if (rssiAsu != SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN
-                && (rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
-                || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
-            Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
+        if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
             return CellInfo.UNAVAILABLE;
         }
-        if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
+        if ((rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
+                || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
+            Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
             return CellInfo.UNAVAILABLE;
         }
         return -113 + (2 * rssiAsu);
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 8079242..061cd4b 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 
 import java.util.Objects;
 
@@ -48,6 +49,12 @@
     private int mSsRsrp;
     private int mSsRsrq;
     private int mSsSinr;
+    private int mLevel;
+
+    /** @hide */
+    public CellSignalStrengthNr() {
+        setDefaultValues();
+    }
 
     /**
      * @param csiRsrp CSI reference signal received power.
@@ -60,12 +67,13 @@
      */
     public CellSignalStrengthNr(
             int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) {
-        mCsiRsrp = csiRsrp;
-        mCsiRsrq = csiRsrq;
-        mCsiSinr = csiSinr;
-        mSsRsrp = ssRsrp;
-        mSsRsrq = ssRsrq;
-        mSsSinr = ssSinr;
+        mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44);
+        mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
+        mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
+        mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
+        mSsRsrq = inRangeOrUnavailable(ssRsrq, -20, -3);
+        mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
+        updateLevel(null, null);
     }
 
     /**
@@ -142,6 +150,7 @@
         dest.writeInt(mSsRsrp);
         dest.writeInt(mSsRsrq);
         dest.writeInt(mSsSinr);
+        dest.writeInt(mLevel);
     }
 
     private CellSignalStrengthNr(Parcel in) {
@@ -151,6 +160,7 @@
         mSsRsrp = in.readInt();
         mSsRsrq = in.readInt();
         mSsSinr = in.readInt();
+        mLevel = in.readInt();
     }
 
     /** @hide */
@@ -162,27 +172,36 @@
         mSsRsrp = CellInfo.UNAVAILABLE;
         mSsRsrq = CellInfo.UNAVAILABLE;
         mSsSinr = CellInfo.UNAVAILABLE;
+        mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     }
 
     @Override
     public int getLevel() {
+        return mLevel;
+    }
+
+    /** @hide */
+    @Override
+    public void updateLevel(PersistableBundle cc, ServiceState ss) {
         if (mCsiRsrp == CellInfo.UNAVAILABLE) {
-            return SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+            mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
         } else if (mCsiRsrp >= SIGNAL_GREAT_THRESHOLD) {
-            return SIGNAL_STRENGTH_GREAT;
+            mLevel = SIGNAL_STRENGTH_GREAT;
         } else if (mCsiRsrp >= SIGNAL_GOOD_THRESHOLD) {
-            return SIGNAL_STRENGTH_GOOD;
+            mLevel = SIGNAL_STRENGTH_GOOD;
         } else if (mCsiRsrp >= SIGNAL_MODERATE_THRESHOLD) {
-            return SIGNAL_STRENGTH_MODERATE;
+            mLevel = SIGNAL_STRENGTH_MODERATE;
         } else {
-            return SIGNAL_STRENGTH_POOR;
+            mLevel = SIGNAL_STRENGTH_POOR;
         }
     }
 
     /**
-     * Calculates the NR signal as an asu value between 0..97, 99 is unknown.
-     * Asu is calculated based on 3GPP RSRP, refer to 3GPP TS 27.007 section 8.69.
-     * @return an integer represent the asu level of the signal strength.
+     * Get the RSRP in ASU.
+     *
+     * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+     *
+     * @return RSCP in ASU 0..97, 255, or UNAVAILABLE
      */
     @Override
     public int getAsuLevel() {
@@ -206,15 +225,33 @@
     }
 
     /** @hide */
+    public CellSignalStrengthNr(CellSignalStrengthNr s) {
+        mCsiRsrp = s.mCsiRsrp;
+        mCsiRsrq = s.mCsiRsrq;
+        mCsiSinr = s.mCsiSinr;
+        mSsRsrp = s.mSsRsrp;
+        mSsRsrq = s.mSsRsrq;
+        mSsSinr = s.mSsSinr;
+        mLevel = s.mLevel;
+    }
+
+    /** @hide */
     @Override
-    public CellSignalStrength copy() {
-        return new CellSignalStrengthNr(
-                mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr);
+    public CellSignalStrengthNr copy() {
+        return new CellSignalStrengthNr(this);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr);
+        return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr, mLevel);
+    }
+
+    private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr();
+
+    /** @hide */
+    @Override
+    public boolean isValid() {
+        return !this.equals(sInvalid);
     }
 
     @Override
@@ -222,7 +259,8 @@
         if (obj instanceof CellSignalStrengthNr) {
             CellSignalStrengthNr o = (CellSignalStrengthNr) obj;
             return mCsiRsrp == o.mCsiRsrp && mCsiRsrq == o.mCsiRsrq && mCsiSinr == o.mCsiSinr
-                    && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr;
+                    && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr
+                    && mLevel == o.mLevel;
         }
         return false;
     }
@@ -237,6 +275,7 @@
                 .append(" ssRsrp = " + mSsRsrp)
                 .append(" ssRsrq = " + mSsRsrq)
                 .append(" ssSinr = " + mSsSinr)
+                .append(" level = " + mLevel)
                 .append(" }")
                 .toString();
     }
diff --git a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
index 4d040cc..6f52b85 100644
--- a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 
 import java.util.Objects;
 
@@ -31,27 +32,53 @@
     private static final String LOG_TAG = "CellSignalStrengthTdscdma";
     private static final boolean DBG = false;
 
-    private static final int TDSCDMA_SIGNAL_STRENGTH_GREAT = 12;
-    private static final int TDSCDMA_SIGNAL_STRENGTH_GOOD = 8;
-    private static final int TDSCDMA_SIGNAL_STRENGTH_MODERATE = 5;
+    private static final int TDSCDMA_RSSI_MAX = -51;
+    private static final int TDSCDMA_RSSI_GREAT = -77;
+    private static final int TDSCDMA_RSSI_GOOD = -87;
+    private static final int TDSCDMA_RSSI_MODERATE = -97;
+    private static final int TDSCDMA_RSSI_POOR = -107;
 
-    private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
-                                 // or CellInfo.UNAVAILABLE if unknown
+    private static final int TDSCDMA_RSCP_MIN = -120;
+    private static final int TDSCDMA_RSCP_MAX = -24;
+
+    private int mRssi; // in dBm [-113, -51], CellInfo.UNAVAILABLE
+
     private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or
                                // CellInfo.UNAVAILABLE if unknown
-    private int mRscp; // Pilot power (0-96, 255) as defined in TS 27.007 8.69 or
+    private int mRscp; // Pilot Power in dBm [-120, -24] or CellInfo.UNAVAILABLE
                        // CellInfo.UNAVAILABLE if unknown
 
+    private int mLevel;
+
     /** @hide */
     public CellSignalStrengthTdscdma() {
         setDefaultValues();
     }
 
+    /**
+     * @param rssi in dBm [-113, -51] or UNAVAILABLE
+     * @param ber [0-7], 99 or UNAVAILABLE
+     * @param rscp in dBm [-120, -24] or UNAVAILABLE
+     * @hide */
+    public CellSignalStrengthTdscdma(int rssi, int ber, int rscp) {
+        mRssi = inRangeOrUnavailable(rssi, -113, -51);
+        mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99);
+        mRscp = inRangeOrUnavailable(rscp, -120, -24);
+        updateLevel(null, null);
+    }
+
     /** @hide */
-    public CellSignalStrengthTdscdma(int ss, int ber, int rscp) {
-        mSignalStrength = ss;
-        mBitErrorRate = ber;
-        mRscp = rscp;
+    public CellSignalStrengthTdscdma(android.hardware.radio.V1_0.TdScdmaSignalStrength tdscdma) {
+        // Convert from HAL values as part of construction.
+        this(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+                tdscdma.rscp != CellInfo.UNAVAILABLE ? -tdscdma.rscp : tdscdma.rscp);
+    }
+
+    /** @hide */
+    public CellSignalStrengthTdscdma(android.hardware.radio.V1_2.TdscdmaSignalStrength tdscdma) {
+        // Convert from HAL values as part of construction.
+        this(getRssiDbmFromAsu(tdscdma.signalStrength),
+                tdscdma.bitErrorRate, getRscpDbmFromAsu(tdscdma.rscp));
     }
 
     /** @hide */
@@ -61,9 +88,10 @@
 
     /** @hide */
     protected void copyFrom(CellSignalStrengthTdscdma s) {
-        mSignalStrength = s.mSignalStrength;
+        mRssi = s.mRssi;
         mBitErrorRate = s.mBitErrorRate;
         mRscp = s.mRscp;
+        mLevel = s.mLevel;
     }
 
     /** @hide */
@@ -75,9 +103,10 @@
     /** @hide */
     @Override
     public void setDefaultValues() {
-        mSignalStrength = CellInfo.UNAVAILABLE;
+        mRssi = CellInfo.UNAVAILABLE;
         mBitErrorRate = CellInfo.UNAVAILABLE;
         mRscp = CellInfo.UNAVAILABLE;
+        mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     }
 
     /**
@@ -88,26 +117,18 @@
      */
     @Override
     public int getLevel() {
-        int level;
+        return mLevel;
+    }
 
-        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
-        // asu = 0 (-113dB or less) is very weak
-        // signal, its better to show 0 bars to the user in such cases.
-        // asu = 99 is a special case, where the signal strength is unknown.
-        int asu = mSignalStrength;
-        if (asu <= 2 || asu == 99) {
-            level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-        } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_GREAT) {
-            level = SIGNAL_STRENGTH_GREAT;
-        } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_GOOD) {
-            level = SIGNAL_STRENGTH_GOOD;
-        } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_MODERATE) {
-            level = SIGNAL_STRENGTH_MODERATE;
-        } else {
-            level = SIGNAL_STRENGTH_POOR;
-        }
-        if (DBG) log("getLevel=" + level);
-        return level;
+    /** @hide */
+    @Override
+    public void updateLevel(PersistableBundle cc, ServiceState ss) {
+        if (mRssi > TDSCDMA_RSSI_MAX) mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        else if (mRssi >= TDSCDMA_RSSI_GREAT) mLevel = SIGNAL_STRENGTH_GREAT;
+        else if (mRssi >= TDSCDMA_RSSI_GOOD)  mLevel = SIGNAL_STRENGTH_GOOD;
+        else if (mRssi >= TDSCDMA_RSSI_MODERATE)  mLevel = SIGNAL_STRENGTH_MODERATE;
+        else if (mRssi >= TDSCDMA_RSSI_POOR) mLevel = SIGNAL_STRENGTH_POOR;
+        else mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     }
 
     /**
@@ -115,56 +136,55 @@
      */
     @Override
     public int getDbm() {
-        int dBm;
-
-        int level = mSignalStrength;
-        int asu = (level == 99 ? CellInfo.UNAVAILABLE : level);
-        if (asu != CellInfo.UNAVAILABLE) {
-            dBm = -113 + (2 * asu);
-        } else {
-            dBm = CellInfo.UNAVAILABLE;
-        }
-        if (DBG) log("getDbm=" + dBm);
-        return dBm;
+        return mRscp;
     }
 
     /**
-     * Get the signal level as an asu value between 0..31, 99 is unknown
+     * Get the RSCP as dBm
+     * @hide
+     */
+    public int getRscp() {
+        return mRscp;
+    }
+
+    /**
+     * Get the RSCP in ASU.
+     *
      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+     *
+     * @return RSCP in ASU 0..96, 255, or UNAVAILABLE
      */
     @Override
     public int getAsuLevel() {
-        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
-        // asu = 0 (-113dB or less) is very weak
-        // signal, its better to show 0 bars to the user in such cases.
-        // asu = 99 is a special case, where the signal strength is unknown.
-        int level = mSignalStrength;
-        if (DBG) log("getAsuLevel=" + level);
-        return level;
+        if (mRscp != CellInfo.UNAVAILABLE) return getAsuFromRscpDbm(mRscp);
+        // For historical reasons, if RSCP is unavailable, this API will very incorrectly return
+        // RSSI. This hackery will be removed when most devices are using Radio HAL 1.2+
+        if (mRssi != CellInfo.UNAVAILABLE) return getAsuFromRssiDbm(mRssi);
+        return getAsuFromRscpDbm(CellInfo.UNAVAILABLE);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mSignalStrength, mBitErrorRate);
+        return Objects.hash(mRssi, mBitErrorRate, mRscp, mLevel);
+    }
+
+    private static final CellSignalStrengthTdscdma sInvalid = new CellSignalStrengthTdscdma();
+
+    /** @hide */
+    @Override
+    public boolean isValid() {
+        return !this.equals(sInvalid);
     }
 
     @Override
     public boolean equals(Object o) {
-        CellSignalStrengthTdscdma s;
+        if (!(o instanceof CellSignalStrengthTdscdma)) return false;
+        CellSignalStrengthTdscdma s = (CellSignalStrengthTdscdma) o;
 
-        try {
-            s = (CellSignalStrengthTdscdma) o;
-        } catch (ClassCastException ex) {
-            return false;
-        }
-
-        if (o == null) {
-            return false;
-        }
-
-        return mSignalStrength == s.mSignalStrength
+        return mRssi == s.mRssi
                 && mBitErrorRate == s.mBitErrorRate
-                && mRscp == s.mRscp;
+                && mRscp == s.mRscp
+                && mLevel == s.mLevel;
     }
 
     /**
@@ -173,18 +193,20 @@
     @Override
     public String toString() {
         return "CellSignalStrengthTdscdma:"
-                + " ss=" + mSignalStrength
+                + " rssi=" + mRssi
                 + " ber=" + mBitErrorRate
-                + " rscp=" + mRscp;
+                + " rscp=" + mRscp
+                + " level=" + mLevel;
     }
 
     /** Implement the Parcelable interface */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         if (DBG) log("writeToParcel(Parcel, int): " + toString());
-        dest.writeInt(mSignalStrength);
+        dest.writeInt(mRssi);
         dest.writeInt(mBitErrorRate);
         dest.writeInt(mRscp);
+        dest.writeInt(mLevel);
     }
 
     /**
@@ -192,9 +214,10 @@
      * where the token is already been processed.
      */
     private CellSignalStrengthTdscdma(Parcel in) {
-        mSignalStrength = in.readInt();
+        mRssi = in.readInt();
         mBitErrorRate = in.readInt();
         mRscp = in.readInt();
+        mLevel = in.readInt();
         if (DBG) log("CellSignalStrengthTdscdma(Parcel): " + toString());
     }
 
diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
index 0048cbd..88f6fbc 100644
--- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
@@ -16,11 +16,14 @@
 
 package android.telephony;
 
-import android.annotation.UnsupportedAppUsage;
+import android.annotation.StringDef;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.PersistableBundle;
 import android.telephony.Rlog;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
 
 /**
@@ -31,20 +34,32 @@
     private static final String LOG_TAG = "CellSignalStrengthWcdma";
     private static final boolean DBG = false;
 
-    private static final int WCDMA_SIGNAL_STRENGTH_GREAT = 12;
-    private static final int WCDMA_SIGNAL_STRENGTH_GOOD = 8;
-    private static final int WCDMA_SIGNAL_STRENGTH_MODERATE = 5;
+    private static final int WCDMA_RSSI_MAX = -51;
+    private static final int WCDMA_RSSI_GREAT = -77;
+    private static final int WCDMA_RSSI_GOOD = -87;
+    private static final int WCDMA_RSSI_MODERATE = -97;
+    private static final int WCDMA_RSSI_POOR = -107;
+    private static final int WCDMA_RSSI_MIN = -113;
 
-    @UnsupportedAppUsage
-    private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
-                                 // or CellInfo.UNAVAILABLE if unknown
-    @UnsupportedAppUsage
+    private static final int WCDMA_RSCP_MIN = -120;
+    private static final int WCDMA_RSCP_MAX = -24;
+
+    // TODO: Because these are used as values in CarrierConfig, they should be exposed somehow.
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @StringDef({LEVEL_CALCULATION_METHOD_RSSI, LEVEL_CALCULATION_METHOD_RSCP})
+    public @interface LevelCalculationMethod {}
+    /** @hide */
+    public static final String LEVEL_CALCULATION_METHOD_RSSI = "rssi";
+    /** @hide */
+    public static final String LEVEL_CALCULATION_METHOD_RSCP = "rscp";
+
+    private int mRssi; // in dBm [-113, 51] or CellInfo.UNAVAILABLE if unknown
     private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or
                                // CellInfo.UNAVAILABLE if unknown
-    private int mRscp; // bit error rate (0-96, 255) as defined in TS 27.007 8.69 or
-                       // CellInfo.UNAVAILABLE if unknown
-    private int mEcNo; // signal to noise radio (0-49, 255) as defined in TS 27.007 8.69 or
-                       // CellInfo.UNAVAILABLE if unknown
+    private int mRscp; // in dBm [-120, -24]
+    private int mEcNo; // range -24, 1, CellInfo.UNAVAILABLE if unknown
+    private int mLevel;
 
     /** @hide */
     public CellSignalStrengthWcdma() {
@@ -52,11 +67,28 @@
     }
 
     /** @hide */
-    public CellSignalStrengthWcdma(int ss, int ber, int rscp, int ecno) {
-        mSignalStrength = ss;
-        mBitErrorRate = ber;
-        mRscp = rscp;
-        mEcNo = ecno;
+    public CellSignalStrengthWcdma(int rssi, int ber, int rscp, int ecno) {
+        mRssi = inRangeOrUnavailable(rssi, WCDMA_RSSI_MIN, WCDMA_RSSI_MAX);
+        mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99);
+        mRscp = inRangeOrUnavailable(rscp, -120, -24);
+        mEcNo = inRangeOrUnavailable(ecno, -24, 1);
+        updateLevel(null, null);
+    }
+
+    /** @hide */
+    public CellSignalStrengthWcdma(android.hardware.radio.V1_0.WcdmaSignalStrength wcdma) {
+        // Convert from HAL values as part of construction.
+        this(getRssiDbmFromAsu(wcdma.signalStrength),
+                wcdma.bitErrorRate, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE);
+    }
+
+    /** @hide */
+    public CellSignalStrengthWcdma(android.hardware.radio.V1_2.WcdmaSignalStrength wcdma) {
+        // Convert from HAL values as part of construction.
+        this(getRssiDbmFromAsu(wcdma.base.signalStrength),
+                    wcdma.base.bitErrorRate,
+                    getRscpDbmFromAsu(wcdma.rscp),
+                    getEcNoDbFromAsu(wcdma.ecno));
     }
 
     /** @hide */
@@ -66,10 +98,11 @@
 
     /** @hide */
     protected void copyFrom(CellSignalStrengthWcdma s) {
-        mSignalStrength = s.mSignalStrength;
+        mRssi = s.mRssi;
         mBitErrorRate = s.mBitErrorRate;
         mRscp = s.mRscp;
         mEcNo = s.mEcNo;
+        mLevel = s.mLevel;
     }
 
     /** @hide */
@@ -81,12 +114,17 @@
     /** @hide */
     @Override
     public void setDefaultValues() {
-        mSignalStrength = CellInfo.UNAVAILABLE;
+        mRssi = CellInfo.UNAVAILABLE;
         mBitErrorRate = CellInfo.UNAVAILABLE;
         mRscp = CellInfo.UNAVAILABLE;
         mEcNo = CellInfo.UNAVAILABLE;
+        mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
     }
 
+    private static final String sLevelCalculationMethod = LEVEL_CALCULATION_METHOD_RSSI;
+    private static final int[] sThresholds = new int[]{
+            WCDMA_RSSI_POOR, WCDMA_RSSI_GOOD, WCDMA_RSSI_GOOD, WCDMA_RSSI_GREAT};
+
     /**
      * Retrieve an abstract level value for the overall signal strength.
      *
@@ -95,20 +133,49 @@
      */
     @Override
     public int getLevel() {
-        int level;
+        return mLevel;
+    }
 
-        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
-        // asu = 0 (-113dB or less) is very weak
-        // signal, its better to show 0 bars to the user in such cases.
-        // asu = 99 is a special case, where the signal strength is unknown.
-        int asu = mSignalStrength;
-        if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-        else if (asu >= WCDMA_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT;
-        else if (asu >= WCDMA_SIGNAL_STRENGTH_GOOD)  level = SIGNAL_STRENGTH_GOOD;
-        else if (asu >= WCDMA_SIGNAL_STRENGTH_MODERATE)  level = SIGNAL_STRENGTH_MODERATE;
-        else level = SIGNAL_STRENGTH_POOR;
-        if (DBG) log("getLevel=" + level);
-        return level;
+    /** @hide */
+    @Override
+    public void updateLevel(PersistableBundle cc, ServiceState ss) {
+        String calcMethod;
+        int[] thresholds;
+
+        if (cc == null) {
+            calcMethod = sLevelCalculationMethod;
+            thresholds = sThresholds;
+        } else {
+            // TODO: abstract this entire thing into a series of functions
+            calcMethod = cc.getString(
+                    CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
+                    sLevelCalculationMethod);
+            thresholds = cc.getIntArray(
+                    CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY);
+            if (thresholds == null) thresholds = sThresholds;
+        }
+
+        int level = thresholds.length;
+        switch (calcMethod) {
+            case LEVEL_CALCULATION_METHOD_RSCP:
+                if (mRscp < WCDMA_RSCP_MIN || mRscp > WCDMA_RSCP_MAX) {
+                    mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+                    return;
+                }
+                while (level > 0 && mRscp < thresholds[level - 1]) level--;
+                mLevel = level;
+                return;
+            case LEVEL_CALCULATION_METHOD_RSSI:
+                if (mRssi < WCDMA_RSSI_MIN || mRssi > WCDMA_RSSI_MAX) {
+                    mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+                    return;
+                }
+                while (level > 0 && mRssi < thresholds[level - 1]) level--;
+                mLevel = level;
+                return;
+            default:
+                mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        }
     }
 
     /**
@@ -116,57 +183,66 @@
      */
     @Override
     public int getDbm() {
-        int dBm;
-
-        int level = mSignalStrength;
-        int asu = (level == 99 ? CellInfo.UNAVAILABLE : level);
-        if (asu != CellInfo.UNAVAILABLE) {
-            dBm = -113 + (2 * asu);
-        } else {
-            dBm = CellInfo.UNAVAILABLE;
-        }
-        if (DBG) log("getDbm=" + dBm);
-        return dBm;
+        if (mRscp != CellInfo.UNAVAILABLE) return mRscp;
+        return mRssi;
     }
 
     /**
-     * Get the signal level as an asu value between 0..31, 99 is unknown
-     * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+     * Get the RSCP in ASU.
+     *
+     * Asu is calculated based on 3GPP RSCP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+     *
+     * @return RSCP in ASU 0..96, 255, or UNAVAILABLE
      */
     @Override
     public int getAsuLevel() {
-        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
-        // asu = 0 (-113dB or less) is very weak
-        // signal, its better to show 0 bars to the user in such cases.
-        // asu = 99 is a special case, where the signal strength is unknown.
-        int level = mSignalStrength;
-        if (DBG) log("getAsuLevel=" + level);
-        return level;
+        if (mRscp != CellInfo.UNAVAILABLE) return getAsuFromRscpDbm(mRscp);
+        // For historical reasons, if RSCP is unavailable, this API will very incorrectly return
+        // RSSI. This hackery will be removed when most devices are using Radio HAL 1.2+
+        if (mRssi != CellInfo.UNAVAILABLE) return getAsuFromRssiDbm(mRssi);
+        return getAsuFromRscpDbm(CellInfo.UNAVAILABLE);
+    }
+
+    /**
+     * Get the signal strength as dBm
+     *
+     * @hide
+     */
+    public int getRssi() {
+        return mRssi;
+    }
+
+    /**
+     * Get the RSCP as dBm
+     * @hide
+     */
+    public int getRscp() {
+        return mRscp;
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mSignalStrength, mBitErrorRate);
+        return Objects.hash(mRssi, mBitErrorRate, mRscp, mEcNo, mLevel);
+    }
+
+    private static final CellSignalStrengthWcdma sInvalid = new CellSignalStrengthWcdma();
+
+    /** @hide */
+    @Override
+    public boolean isValid() {
+        return !this.equals(sInvalid);
     }
 
     @Override
-    public boolean equals (Object o) {
-        CellSignalStrengthWcdma s;
+    public boolean equals(Object o) {
+        if (!(o instanceof CellSignalStrengthWcdma)) return false;
+        CellSignalStrengthWcdma s = (CellSignalStrengthWcdma) o;
 
-        try {
-            s = (CellSignalStrengthWcdma) o;
-        } catch (ClassCastException ex) {
-            return false;
-        }
-
-        if (o == null) {
-            return false;
-        }
-
-        return mSignalStrength == s.mSignalStrength
+        return mRssi == s.mRssi
                 && mBitErrorRate == s.mBitErrorRate
                 && mRscp == s.mRscp
-                && mEcNo == s.mEcNo;
+                && mEcNo == s.mEcNo
+                && mLevel == s.mLevel;
     }
 
     /**
@@ -175,20 +251,22 @@
     @Override
     public String toString() {
         return "CellSignalStrengthWcdma:"
-                + " ss=" + mSignalStrength
+                + " ss=" + mRssi
                 + " ber=" + mBitErrorRate
                 + " rscp=" + mRscp
-                + " ecno=" + mEcNo;
+                + " ecno=" + mEcNo
+                + " level=" + mLevel;
     }
 
     /** Implement the Parcelable interface */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         if (DBG) log("writeToParcel(Parcel, int): " + toString());
-        dest.writeInt(mSignalStrength);
+        dest.writeInt(mRssi);
         dest.writeInt(mBitErrorRate);
         dest.writeInt(mRscp);
         dest.writeInt(mEcNo);
+        dest.writeInt(mLevel);
     }
 
     /**
@@ -196,10 +274,11 @@
      * where the token is already been processed.
      */
     private CellSignalStrengthWcdma(Parcel in) {
-        mSignalStrength = in.readInt();
+        mRssi = in.readInt();
         mBitErrorRate = in.readInt();
         mRscp = in.readInt();
         mEcNo = in.readInt();
+        mLevel = in.readInt();
         if (DBG) log("CellSignalStrengthWcdma(Parcel): " + toString());
     }
 
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
new file mode 100644
index 0000000..c53b37d
--- /dev/null
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.PersistableBundle;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Returned as the reason for a data connection failure as defined by modem and some local errors.
+ * @hide
+ */
+public final class DataFailCause {
+    /** There is no failure */
+    public static final int NONE = 0;
+
+    // This series of errors as specified by the standards
+    // specified in ril.h
+    /** Operator determined barring. */
+    public static final int OPERATOR_BARRED = 0x08;
+    /** NAS signalling. */
+    public static final int NAS_SIGNALLING = 0x0E;
+    /** Logical Link Control (LLC) Sub Network Dependent Convergence Protocol (SNDCP). */
+    public static final int LLC_SNDCP = 0x19;
+    /** Insufficient resources. */
+    public static final int INSUFFICIENT_RESOURCES = 0x1A;
+    /** Missing or unknown APN. */
+    public static final int MISSING_UNKNOWN_APN = 0x1B;              /* no retry */
+    /** Unknown Packet Data Protocol (PDP) address type. */
+    public static final int UNKNOWN_PDP_ADDRESS_TYPE = 0x1C;         /* no retry */
+    /** User authentication. */
+    public static final int USER_AUTHENTICATION = 0x1D;              /* no retry */
+    /** Activation rejected by Gateway GPRS Support Node (GGSN), Serving Gateway or PDN Gateway. */
+    public static final int ACTIVATION_REJECT_GGSN = 0x1E;           /* no retry */
+    /** Activation rejected, unspecified. */
+    public static final int ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
+    /** Service option not supported. */
+    public static final int SERVICE_OPTION_NOT_SUPPORTED = 0x20;     /* no retry */
+    /** Requested service option not subscribed. */
+    public static final int SERVICE_OPTION_NOT_SUBSCRIBED = 0x21;    /* no retry */
+    /** Service option temporarily out of order. */
+    public static final int SERVICE_OPTION_OUT_OF_ORDER = 0x22;
+    /** The Network Service Access Point Identifier (NSAPI) is in use. */
+    public static final int NSAPI_IN_USE = 0x23;                     /* no retry */
+    /* possibly restart radio, based on config */
+    /** Regular deactivation. */
+    public static final int REGULAR_DEACTIVATION = 0x24;
+    /** Quality of service (QoS) is not accepted. */
+    public static final int QOS_NOT_ACCEPTED = 0x25;
+    /** Network Failure. */
+    public static final int NETWORK_FAILURE = 0x26;
+    /** Universal Mobile Telecommunications System (UMTS) reactivation request. */
+    public static final int UMTS_REACTIVATION_REQ = 0x27;
+    /** Feature not supported. */
+    public static final int FEATURE_NOT_SUPP = 0x28;
+    /** Semantic error in the Traffic flow templates (TFT) operation. */
+    public static final int TFT_SEMANTIC_ERROR = 0x29;
+    /** Syntactical error in the Traffic flow templates (TFT) operation. */
+    public static final int TFT_SYTAX_ERROR = 0x2A;
+    /** Unknown Packet Data Protocol (PDP) context. */
+    public static final int UNKNOWN_PDP_CONTEXT = 0x2B;
+    /** Semantic errors in packet filter. */
+    public static final int FILTER_SEMANTIC_ERROR = 0x2C;
+    /** Syntactical errors in packet filter(s). */
+    public static final int FILTER_SYTAX_ERROR = 0x2D;
+    /** Packet Data Protocol (PDP) without active traffic flow template (TFT). */
+    public static final int PDP_WITHOUT_ACTIVE_TFT = 0x2E;
+    /** Packet Data Protocol (PDP) type IPv4 only allowed. */
+    public static final int ONLY_IPV4_ALLOWED = 0x32;                /* no retry */
+    /** Packet Data Protocol (PDP) type IPv6 only allowed. */
+    public static final int ONLY_IPV6_ALLOWED = 0x33;                /* no retry */
+    /** Single address bearers only allowed. */
+    public static final int ONLY_SINGLE_BEARER_ALLOWED = 0x34;
+    /** EPS Session Management (ESM) information is not received. */
+    public static final int ESM_INFO_NOT_RECEIVED = 0x35;
+    /** PDN connection does not exist. */
+    public static final int PDN_CONN_DOES_NOT_EXIST = 0x36;
+    /** Multiple connections to a same PDN is not allowed. */
+    public static final int MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37;
+    /** Packet Data Protocol (PDP) */
+    public static final int MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41;
+    /** Unsupported APN in current public land mobile network (PLMN). */
+    public static final int UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42;
+    /** Invalid transaction id. */
+    public static final int INVALID_TRANSACTION_ID = 0x51;
+    /** Incorrect message semantic. */
+    public static final int MESSAGE_INCORRECT_SEMANTIC = 0x5F;
+    /** Invalid mandatory information. */
+    public static final int INVALID_MANDATORY_INFO = 0x60;
+    /** Unsupported message type. */
+    public static final int MESSAGE_TYPE_UNSUPPORTED = 0x61;
+    /** Message type uncompatible. */
+    public static final int MSG_TYPE_NONCOMPATIBLE_STATE = 0x62;
+    /** Unknown info element. */
+    public static final int UNKNOWN_INFO_ELEMENT = 0x63;
+    /** Conditional Information Element (IE) error. */
+    public static final int CONDITIONAL_IE_ERROR = 0x64;
+    /** Message and protocol state uncompatible. */
+    public static final int MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65;
+    /** Protocol errors. */
+    public static final int PROTOCOL_ERRORS = 0x6F;                  /* no retry */
+    /** APN type conflict. */
+    public static final int APN_TYPE_CONFLICT = 0x70;
+    /** Invalid Proxy-Call Session Control Function (P-CSCF) address. */
+    public static final int INVALID_PCSCF_ADDR = 0x71;
+    /** Internal data call preempt by high priority APN. */
+    public static final int INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72;
+    /** EPS (Evolved Packet System) Mobility Management (EMM) access barred. */
+    public static final int EMM_ACCESS_BARRED = 0x73;
+    /** Emergency interface only. */
+    public static final int EMERGENCY_IFACE_ONLY = 0x74;
+    /** Interface mismatch. */
+    public static final int IFACE_MISMATCH = 0x75;
+    /** Companion interface in use. */
+    public static final int COMPANION_IFACE_IN_USE = 0x76;
+    /** IP address mismatch. */
+    public static final int IP_ADDRESS_MISMATCH = 0x77;
+    public static final int IFACE_AND_POL_FAMILY_MISMATCH = 0x78;
+    /** EPS (Evolved Packet System) Mobility Management (EMM) access barred infinity retry. **/
+    public static final int EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79;
+    /** Authentication failure on emergency call. */
+    public static final int AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A;
+
+    // OEM sepecific error codes. To be used by OEMs when they don't
+    // want to reveal error code which would be replaced by ERROR_UNSPECIFIED
+    public static final int OEM_DCFAILCAUSE_1 = 0x1001;
+    public static final int OEM_DCFAILCAUSE_2 = 0x1002;
+    public static final int OEM_DCFAILCAUSE_3 = 0x1003;
+    public static final int OEM_DCFAILCAUSE_4 = 0x1004;
+    public static final int OEM_DCFAILCAUSE_5 = 0x1005;
+    public static final int OEM_DCFAILCAUSE_6 = 0x1006;
+    public static final int OEM_DCFAILCAUSE_7 = 0x1007;
+    public static final int OEM_DCFAILCAUSE_8 = 0x1008;
+    public static final int OEM_DCFAILCAUSE_9 = 0x1009;
+    public static final int OEM_DCFAILCAUSE_10 = 0x100A;
+    public static final int OEM_DCFAILCAUSE_11 = 0x100B;
+    public static final int OEM_DCFAILCAUSE_12 = 0x100C;
+    public static final int OEM_DCFAILCAUSE_13 = 0x100D;
+    public static final int OEM_DCFAILCAUSE_14 = 0x100E;
+    public static final int OEM_DCFAILCAUSE_15 = 0x100F;
+
+    // Local errors generated by Vendor RIL
+    // specified in ril.h
+    public static final int REGISTRATION_FAIL = -1;
+    public static final int GPRS_REGISTRATION_FAIL = -2;
+    public static final int SIGNAL_LOST = -3;                        /* no retry */
+    public static final int PREF_RADIO_TECH_CHANGED = -4;
+    public static final int RADIO_POWER_OFF = -5;                    /* no retry */
+    public static final int TETHERED_CALL_ACTIVE = -6;               /* no retry */
+    public static final int ERROR_UNSPECIFIED = 0xFFFF;
+
+    // Errors generated by the Framework
+    // specified here
+    public static final int UNKNOWN = 0x10000;
+    public static final int RADIO_NOT_AVAILABLE = 0x10001;                   /* no retry */
+    public static final int UNACCEPTABLE_NETWORK_PARAMETER = 0x10002;        /* no retry */
+    public static final int CONNECTION_TO_DATACONNECTIONAC_BROKEN = 0x10003;
+    public static final int LOST_CONNECTION = 0x10004;
+    /** Data was reset by framework. */
+    public static final int RESET_BY_FRAMEWORK = 0x10005;
+
+    /** @hide */
+    @IntDef(value = {
+            NONE,
+            OPERATOR_BARRED,
+            NAS_SIGNALLING,
+            LLC_SNDCP,
+            INSUFFICIENT_RESOURCES,
+            MISSING_UNKNOWN_APN,
+            UNKNOWN_PDP_ADDRESS_TYPE,
+            USER_AUTHENTICATION,
+            ACTIVATION_REJECT_GGSN,
+            ACTIVATION_REJECT_UNSPECIFIED,
+            SERVICE_OPTION_NOT_SUPPORTED,
+            SERVICE_OPTION_NOT_SUBSCRIBED,
+            SERVICE_OPTION_OUT_OF_ORDER,
+            NSAPI_IN_USE,
+            REGULAR_DEACTIVATION,
+            QOS_NOT_ACCEPTED,
+            NETWORK_FAILURE,
+            UMTS_REACTIVATION_REQ,
+            FEATURE_NOT_SUPP,
+            TFT_SEMANTIC_ERROR,
+            TFT_SYTAX_ERROR,
+            UNKNOWN_PDP_CONTEXT,
+            FILTER_SEMANTIC_ERROR,
+            FILTER_SYTAX_ERROR,
+            PDP_WITHOUT_ACTIVE_TFT,
+            ONLY_IPV4_ALLOWED,
+            ONLY_IPV6_ALLOWED,
+            ONLY_SINGLE_BEARER_ALLOWED,
+            ESM_INFO_NOT_RECEIVED,
+            PDN_CONN_DOES_NOT_EXIST,
+            MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED,
+            MAX_ACTIVE_PDP_CONTEXT_REACHED,
+            UNSUPPORTED_APN_IN_CURRENT_PLMN,
+            INVALID_TRANSACTION_ID,
+            MESSAGE_INCORRECT_SEMANTIC,
+            INVALID_MANDATORY_INFO,
+            MESSAGE_TYPE_UNSUPPORTED,
+            MSG_TYPE_NONCOMPATIBLE_STATE,
+            UNKNOWN_INFO_ELEMENT,
+            CONDITIONAL_IE_ERROR,
+            MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE,
+            PROTOCOL_ERRORS,                 /* no retry */
+            APN_TYPE_CONFLICT,
+            INVALID_PCSCF_ADDR,
+            INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN,
+            EMM_ACCESS_BARRED,
+            EMERGENCY_IFACE_ONLY,
+            IFACE_MISMATCH,
+            COMPANION_IFACE_IN_USE,
+            IP_ADDRESS_MISMATCH,
+            IFACE_AND_POL_FAMILY_MISMATCH,
+            EMM_ACCESS_BARRED_INFINITE_RETRY,
+            AUTH_FAILURE_ON_EMERGENCY_CALL,
+            OEM_DCFAILCAUSE_1,
+            OEM_DCFAILCAUSE_2,
+            OEM_DCFAILCAUSE_3,
+            OEM_DCFAILCAUSE_4,
+            OEM_DCFAILCAUSE_5,
+            OEM_DCFAILCAUSE_6,
+            OEM_DCFAILCAUSE_7,
+            OEM_DCFAILCAUSE_8,
+            OEM_DCFAILCAUSE_9,
+            OEM_DCFAILCAUSE_10,
+            OEM_DCFAILCAUSE_11,
+            OEM_DCFAILCAUSE_12,
+            OEM_DCFAILCAUSE_13,
+            OEM_DCFAILCAUSE_14,
+            OEM_DCFAILCAUSE_15,
+            REGISTRATION_FAIL,
+            GPRS_REGISTRATION_FAIL,
+            SIGNAL_LOST,
+            PREF_RADIO_TECH_CHANGED,
+            RADIO_POWER_OFF,
+            TETHERED_CALL_ACTIVE,
+            ERROR_UNSPECIFIED,
+            UNKNOWN,
+            RADIO_NOT_AVAILABLE,
+            UNACCEPTABLE_NETWORK_PARAMETER,
+            CONNECTION_TO_DATACONNECTIONAC_BROKEN,
+            LOST_CONNECTION,
+            RESET_BY_FRAMEWORK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FailCause{}
+
+    private static final Map<Integer, String> sFailCauseMap;
+    static {
+        sFailCauseMap = new HashMap<>();
+        sFailCauseMap.put(NONE, "NONE");
+        sFailCauseMap.put(OPERATOR_BARRED, "OPERATOR_BARRED");
+        sFailCauseMap.put(NAS_SIGNALLING, "NAS_SIGNALLING");
+        sFailCauseMap.put(LLC_SNDCP, "LLC_SNDCP");
+        sFailCauseMap.put(INSUFFICIENT_RESOURCES, "INSUFFICIENT_RESOURCES");
+        sFailCauseMap.put(MISSING_UNKNOWN_APN, "MISSING_UNKNOWN_APN");
+        sFailCauseMap.put(UNKNOWN_PDP_ADDRESS_TYPE, "UNKNOWN_PDP_ADDRESS_TYPE");
+        sFailCauseMap.put(USER_AUTHENTICATION, "USER_AUTHENTICATION");
+        sFailCauseMap.put(ACTIVATION_REJECT_GGSN, "ACTIVATION_REJECT_GGSN");
+        sFailCauseMap.put(ACTIVATION_REJECT_UNSPECIFIED,
+                "ACTIVATION_REJECT_UNSPECIFIED");
+        sFailCauseMap.put(SERVICE_OPTION_NOT_SUPPORTED,
+                "SERVICE_OPTION_NOT_SUPPORTED");
+        sFailCauseMap.put(SERVICE_OPTION_NOT_SUBSCRIBED,
+                "SERVICE_OPTION_NOT_SUBSCRIBED");
+        sFailCauseMap.put(SERVICE_OPTION_OUT_OF_ORDER, "SERVICE_OPTION_OUT_OF_ORDER");
+        sFailCauseMap.put(NSAPI_IN_USE, "NSAPI_IN_USE");
+        sFailCauseMap.put(REGULAR_DEACTIVATION, "REGULAR_DEACTIVATION");
+        sFailCauseMap.put(QOS_NOT_ACCEPTED, "QOS_NOT_ACCEPTED");
+        sFailCauseMap.put(NETWORK_FAILURE, "NETWORK_FAILURE");
+        sFailCauseMap.put(UMTS_REACTIVATION_REQ, "UMTS_REACTIVATION_REQ");
+        sFailCauseMap.put(FEATURE_NOT_SUPP, "FEATURE_NOT_SUPP");
+        sFailCauseMap.put(TFT_SEMANTIC_ERROR, "TFT_SEMANTIC_ERROR");
+        sFailCauseMap.put(TFT_SYTAX_ERROR, "TFT_SYTAX_ERROR");
+        sFailCauseMap.put(UNKNOWN_PDP_CONTEXT, "UNKNOWN_PDP_CONTEXT");
+        sFailCauseMap.put(FILTER_SEMANTIC_ERROR, "FILTER_SEMANTIC_ERROR");
+        sFailCauseMap.put(FILTER_SYTAX_ERROR, "FILTER_SYTAX_ERROR");
+        sFailCauseMap.put(PDP_WITHOUT_ACTIVE_TFT, "PDP_WITHOUT_ACTIVE_TFT");
+        sFailCauseMap.put(ONLY_IPV4_ALLOWED, "ONLY_IPV4_ALLOWED");
+        sFailCauseMap.put(ONLY_IPV6_ALLOWED, "ONLY_IPV6_ALLOWED");
+        sFailCauseMap.put(ONLY_SINGLE_BEARER_ALLOWED, "ONLY_SINGLE_BEARER_ALLOWED");
+        sFailCauseMap.put(ESM_INFO_NOT_RECEIVED, "ESM_INFO_NOT_RECEIVED");
+        sFailCauseMap.put(PDN_CONN_DOES_NOT_EXIST, "PDN_CONN_DOES_NOT_EXIST");
+        sFailCauseMap.put(MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED,
+                "MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED");
+        sFailCauseMap.put(MAX_ACTIVE_PDP_CONTEXT_REACHED,
+                "MAX_ACTIVE_PDP_CONTEXT_REACHED");
+        sFailCauseMap.put(UNSUPPORTED_APN_IN_CURRENT_PLMN,
+                "UNSUPPORTED_APN_IN_CURRENT_PLMN");
+        sFailCauseMap.put(INVALID_TRANSACTION_ID, "INVALID_TRANSACTION_ID");
+        sFailCauseMap.put(MESSAGE_INCORRECT_SEMANTIC, "MESSAGE_INCORRECT_SEMANTIC");
+        sFailCauseMap.put(INVALID_MANDATORY_INFO, "INVALID_MANDATORY_INFO");
+        sFailCauseMap.put(MESSAGE_TYPE_UNSUPPORTED, "MESSAGE_TYPE_UNSUPPORTED");
+        sFailCauseMap.put(MSG_TYPE_NONCOMPATIBLE_STATE, "MSG_TYPE_NONCOMPATIBLE_STATE");
+        sFailCauseMap.put(UNKNOWN_INFO_ELEMENT, "UNKNOWN_INFO_ELEMENT");
+        sFailCauseMap.put(CONDITIONAL_IE_ERROR, "CONDITIONAL_IE_ERROR");
+        sFailCauseMap.put(MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE,
+                "MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE");
+        sFailCauseMap.put(PROTOCOL_ERRORS, "PROTOCOL_ERRORS");
+        sFailCauseMap.put(APN_TYPE_CONFLICT, "APN_TYPE_CONFLICT");
+        sFailCauseMap.put(INVALID_PCSCF_ADDR, "INVALID_PCSCF_ADDR");
+        sFailCauseMap.put(INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN,
+                "INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN");
+        sFailCauseMap.put(EMM_ACCESS_BARRED, "EMM_ACCESS_BARRED");
+        sFailCauseMap.put(EMERGENCY_IFACE_ONLY, "EMERGENCY_IFACE_ONLY");
+        sFailCauseMap.put(IFACE_MISMATCH, "IFACE_MISMATCH");
+        sFailCauseMap.put(COMPANION_IFACE_IN_USE, "COMPANION_IFACE_IN_USE");
+        sFailCauseMap.put(IP_ADDRESS_MISMATCH, "IP_ADDRESS_MISMATCH");
+        sFailCauseMap.put(IFACE_AND_POL_FAMILY_MISMATCH,
+                "IFACE_AND_POL_FAMILY_MISMATCH");
+        sFailCauseMap.put(EMM_ACCESS_BARRED_INFINITE_RETRY,
+                "EMM_ACCESS_BARRED_INFINITE_RETRY");
+        sFailCauseMap.put(AUTH_FAILURE_ON_EMERGENCY_CALL,
+                "AUTH_FAILURE_ON_EMERGENCY_CALL");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_1, "OEM_DCFAILCAUSE_1");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_2, "OEM_DCFAILCAUSE_2");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_3, "OEM_DCFAILCAUSE_3");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_4, "OEM_DCFAILCAUSE_4");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_5, "OEM_DCFAILCAUSE_5");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_6, "OEM_DCFAILCAUSE_6");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_7, "OEM_DCFAILCAUSE_7");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_8, "OEM_DCFAILCAUSE_8");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_9, "OEM_DCFAILCAUSE_9");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_10, "OEM_DCFAILCAUSE_10");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_11, "OEM_DCFAILCAUSE_11");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_12, "OEM_DCFAILCAUSE_12");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_13, "OEM_DCFAILCAUSE_13");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_14, "OEM_DCFAILCAUSE_14");
+        sFailCauseMap.put(OEM_DCFAILCAUSE_15, "OEM_DCFAILCAUSE_15");
+        sFailCauseMap.put(REGISTRATION_FAIL, "REGISTRATION_FAIL");
+        sFailCauseMap.put(GPRS_REGISTRATION_FAIL, "GPRS_REGISTRATION_FAIL");
+        sFailCauseMap.put(SIGNAL_LOST, "SIGNAL_LOST");
+        sFailCauseMap.put(PREF_RADIO_TECH_CHANGED, "PREF_RADIO_TECH_CHANGED");
+        sFailCauseMap.put(RADIO_POWER_OFF, "RADIO_POWER_OFF");
+        sFailCauseMap.put(TETHERED_CALL_ACTIVE, "TETHERED_CALL_ACTIVE");
+        sFailCauseMap.put(ERROR_UNSPECIFIED, "ERROR_UNSPECIFIED");
+        sFailCauseMap.put(UNKNOWN, "UNKNOWN");
+        sFailCauseMap.put(RADIO_NOT_AVAILABLE, "RADIO_NOT_AVAILABLE");
+        sFailCauseMap.put(UNACCEPTABLE_NETWORK_PARAMETER,
+                "UNACCEPTABLE_NETWORK_PARAMETER");
+        sFailCauseMap.put(CONNECTION_TO_DATACONNECTIONAC_BROKEN,
+                "CONNECTION_TO_DATACONNECTIONAC_BROKEN");
+        sFailCauseMap.put(LOST_CONNECTION, "LOST_CONNECTION");
+        sFailCauseMap.put(RESET_BY_FRAMEWORK, "RESET_BY_FRAMEWORK");
+    }
+
+    /**
+     * Map of subId -> set of data call setup permanent failure for the carrier.
+     */
+    private static final HashMap<Integer, Set<Integer>> sPermanentFailureCache =
+            new HashMap<>();
+
+    /**
+     * Returns whether or not the fail cause is a failure that requires a modem restart
+     *
+     * @param context device context
+     * @param cause data disconnect cause
+     * @param subId subscription index
+     * @return true if the fail cause code needs platform to trigger a modem restart.
+     */
+    public static boolean isRadioRestartFailure(@NonNull Context context, @FailCause int cause,
+                                                int subId) {
+        CarrierConfigManager configManager = (CarrierConfigManager)
+                context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        if (configManager != null) {
+            PersistableBundle b = configManager.getConfigForSubId(subId);
+
+            if (b != null) {
+                if (cause == REGULAR_DEACTIVATION
+                        && b.getBoolean(CarrierConfigManager
+                        .KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL)) {
+                    // This is for backward compatibility support. We need to continue support this
+                    // old configuration until it gets removed in the future.
+                    return true;
+                }
+                // Check the current configurations.
+                int[] causeCodes = b.getIntArray(CarrierConfigManager
+                        .KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY);
+                if (causeCodes != null) {
+                    return Arrays.stream(causeCodes).anyMatch(i -> i == cause);
+                }
+            }
+        }
+
+        return false;
+    }
+
+    public static boolean isPermanentFailure(@NonNull Context context, @FailCause int failCause,
+                                             int subId) {
+        synchronized (sPermanentFailureCache) {
+
+            Set<Integer> permanentFailureSet = sPermanentFailureCache.get(subId);
+
+            // In case of cache miss, we need to look up the settings from carrier config.
+            if (permanentFailureSet == null) {
+                // Retrieve the permanent failure from carrier config
+                CarrierConfigManager configManager = (CarrierConfigManager)
+                        context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+                if (configManager != null) {
+                    PersistableBundle b = configManager.getConfigForSubId(subId);
+                    if (b != null) {
+                        String[] permanentFailureStrings = b.getStringArray(CarrierConfigManager.
+                                KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS);
+                        if (permanentFailureStrings != null) {
+                            permanentFailureSet = new HashSet<>();
+                            for (Map.Entry<Integer, String> e : sFailCauseMap.entrySet()) {
+                                if (ArrayUtils.contains(permanentFailureStrings, e.getValue())) {
+                                    permanentFailureSet.add(e.getKey());
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // If we are not able to find the configuration from carrier config, use the default
+                // ones.
+                if (permanentFailureSet == null) {
+                    permanentFailureSet = new HashSet<Integer>() {
+                        {
+                            add(OPERATOR_BARRED);
+                            add(MISSING_UNKNOWN_APN);
+                            add(UNKNOWN_PDP_ADDRESS_TYPE);
+                            add(USER_AUTHENTICATION);
+                            add(ACTIVATION_REJECT_GGSN);
+                            add(SERVICE_OPTION_NOT_SUPPORTED);
+                            add(SERVICE_OPTION_NOT_SUBSCRIBED);
+                            add(NSAPI_IN_USE);
+                            add(ONLY_IPV4_ALLOWED);
+                            add(ONLY_IPV6_ALLOWED);
+                            add(PROTOCOL_ERRORS);
+                            add(RADIO_POWER_OFF);
+                            add(TETHERED_CALL_ACTIVE);
+                            add(RADIO_NOT_AVAILABLE);
+                            add(UNACCEPTABLE_NETWORK_PARAMETER);
+                            add(SIGNAL_LOST);
+                        }
+                    };
+                }
+
+                sPermanentFailureCache.put(subId, permanentFailureSet);
+            }
+
+            return permanentFailureSet.contains(failCause);
+        }
+    }
+
+    public static boolean isEventLoggable(@FailCause int dataFailCause) {
+        return (dataFailCause == OPERATOR_BARRED) || (dataFailCause == INSUFFICIENT_RESOURCES)
+                || (dataFailCause == UNKNOWN_PDP_ADDRESS_TYPE)
+                || (dataFailCause == USER_AUTHENTICATION)
+                || (dataFailCause == ACTIVATION_REJECT_GGSN)
+                || (dataFailCause == ACTIVATION_REJECT_UNSPECIFIED)
+                || (dataFailCause == SERVICE_OPTION_NOT_SUBSCRIBED)
+                || (dataFailCause == SERVICE_OPTION_NOT_SUPPORTED)
+                || (dataFailCause == SERVICE_OPTION_OUT_OF_ORDER)
+                || (dataFailCause == NSAPI_IN_USE)
+                || (dataFailCause == ONLY_IPV4_ALLOWED)
+                || (dataFailCause == ONLY_IPV6_ALLOWED)
+                || (dataFailCause == PROTOCOL_ERRORS)
+                || (dataFailCause == SIGNAL_LOST)
+                || (dataFailCause == RADIO_POWER_OFF)
+                || (dataFailCause == TETHERED_CALL_ACTIVE)
+                || (dataFailCause == UNACCEPTABLE_NETWORK_PARAMETER);
+    }
+
+    public static String toString(@FailCause int dataFailCause) {
+        int cause = getFailCause(dataFailCause);
+        return (cause == UNKNOWN) ? "UNKNOWN(" + dataFailCause + ")" : sFailCauseMap.get(cause);
+    }
+
+    public static int getFailCause(@FailCause int failCause) {
+        if (sFailCauseMap.containsKey(failCause)) {
+            return failCause;
+        } else {
+            return UNKNOWN;
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationStates.java
index b6e6cba..5d809d0 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationStates.java
@@ -33,17 +33,31 @@
      */
     public final boolean isNrAvailable;
 
+    /**
+     * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving
+     * cell.
+     *
+     * True the primary serving cell is LTE cell and the plmn-InfoList-r15 is present in SIB2 and
+     * at least one bit in this list is true, otherwise this value should be false.
+     *
+     * Reference: 3GPP TS 36.331 v15.2.2 6.3.1 System information blocks.
+     */
+    public final boolean isEnDcAvailable;
+
     DataSpecificRegistrationStates(
-            int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable) {
+            int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
+            boolean isEnDcAvailable) {
         this.maxDataCalls = maxDataCalls;
         this.isDcNrRestricted = isDcNrRestricted;
         this.isNrAvailable = isNrAvailable;
+        this.isEnDcAvailable = isEnDcAvailable;
     }
 
     private DataSpecificRegistrationStates(Parcel source) {
         maxDataCalls = source.readInt();
         isDcNrRestricted = source.readBoolean();
         isNrAvailable = source.readBoolean();
+        isEnDcAvailable = source.readBoolean();
     }
 
     @Override
@@ -51,6 +65,7 @@
         dest.writeInt(maxDataCalls);
         dest.writeBoolean(isDcNrRestricted);
         dest.writeBoolean(isNrAvailable);
+        dest.writeBoolean(isEnDcAvailable);
     }
 
     @Override
@@ -65,13 +80,14 @@
                 .append(" maxDataCalls = " + maxDataCalls)
                 .append(" isDcNrRestricted = " + isDcNrRestricted)
                 .append(" isNrAvailable = " + isNrAvailable)
+                .append(" isEnDcAvailable = " + isEnDcAvailable)
                 .append(" }")
                 .toString();
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable);
+        return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable);
     }
 
     @Override
@@ -83,7 +99,8 @@
         DataSpecificRegistrationStates other = (DataSpecificRegistrationStates) o;
         return this.maxDataCalls == other.maxDataCalls
                 && this.isDcNrRestricted == other.isDcNrRestricted
-                && this.isNrAvailable == other.isNrAvailable;
+                && this.isNrAvailable == other.isNrAvailable
+                && this.isEnDcAvailable == other.isEnDcAvailable;
     }
 
     public static final Parcelable.Creator<DataSpecificRegistrationStates> CREATOR =
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index c6887ab..f53cb82 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -16,12 +16,16 @@
 
 package android.telephony;
 
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 
 /**
- * Contains disconnect call causes generated by the framework and the RIL.
+ * Describes the cause of a disconnected call. Those disconnect causes can be converted into a more
+ * generic {@link android.telecom.DisconnectCause} object.
+ *
  * @hide
  */
+@SystemApi
 public class DisconnectCause {
 
     /** The disconnect cause is not valid (Not received a disconnect cause) */
@@ -101,8 +105,8 @@
     /** Unknown error or not specified */
     public static final int ERROR_UNSPECIFIED              = 36;
     /**
-     * Only emergency numbers are allowed, but we tried to dial
-     * a non-emergency number.
+     * Only emergency numbers are allowed, but we tried to dial a non-emergency number.
+     * @hide
      */
     // TODO: This should be the same as NOT_EMERGENCY
     public static final int EMERGENCY_ONLY                 = 37;
@@ -115,8 +119,7 @@
      */
     public static final int DIALED_MMI                     = 39;
     /**
-     * We tried to call a voicemail: URI but the device has no
-     * voicemail number configured.
+     * We tried to call a voicemail: URI but the device has no voicemail number configured.
      */
     public static final int VOICEMAIL_NUMBER_MISSING       = 40;
     /**
@@ -129,6 +132,8 @@
      * needs to be triggered by a *disconnect* event, rather than when
      * the InCallScreen first comes to the foreground.  For now we use
      * the needToShowCallLostDialog field for this (see below.)
+     *
+     * @hide
      */
     public static final int CDMA_CALL_LOST                 = 41;
     /**
@@ -169,62 +174,52 @@
 
     /**
      * Stk Call Control modified DIAL request to USSD request.
-     * {@hide}
      */
     public static final int DIAL_MODIFIED_TO_USSD          = 46;
     /**
      * Stk Call Control modified DIAL request to SS request.
-     * {@hide}
      */
     public static final int DIAL_MODIFIED_TO_SS            = 47;
     /**
      * Stk Call Control modified DIAL request to DIAL with modified data.
-     * {@hide}
      */
     public static final int DIAL_MODIFIED_TO_DIAL          = 48;
 
     /**
      * The call was terminated because CDMA phone service and roaming have already been activated.
-     * {@hide}
      */
     public static final int CDMA_ALREADY_ACTIVATED         = 49;
 
     /**
      * The call was terminated because it is not possible to place a video call while TTY is
      * enabled.
-     * {@hide}
      */
     public static final int VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED = 50;
 
     /**
      * The call was terminated because it was pulled to another device.
-     * {@hide}
      */
     public static final int CALL_PULLED = 51;
 
     /**
      * The call was terminated because it was answered on another device.
-     * {@hide}
      */
     public static final int ANSWERED_ELSEWHERE = 52;
 
     /**
      * The call was terminated because the maximum allowable number of calls has been reached.
-     * {@hide}
      */
     public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53;
 
     /**
      * The call was terminated because cellular data has been disabled.
      * Used when in a video call and the user disables cellular data via the settings.
-     * {@hide}
      */
     public static final int DATA_DISABLED = 54;
 
     /**
      * The call was terminated because the data policy has disabled cellular data.
      * Used when in a video call and the user has exceeded the device data limit.
-     * {@hide}
      */
     public static final int DATA_LIMIT_REACHED = 55;
 
@@ -237,7 +232,6 @@
     /**
      * The network does not accept the emergency call request because IMEI was used as
      * identification and this cability is not supported by the network.
-     * {@hide}
      */
     public static final int IMEI_NOT_ACCEPTED = 58;
 
@@ -249,7 +243,6 @@
 
     /**
      * The call has failed because of access class barring.
-     * {@hide}
      */
     public static final int IMS_ACCESS_BLOCKED = 60;
 
@@ -265,51 +258,43 @@
 
     /**
      * Emergency call failed with a temporary fail cause and can be redialed on this slot.
-     * {@hide}
      */
     public static final int EMERGENCY_TEMP_FAILURE = 63;
 
     /**
      * Emergency call failed with a permanent fail cause and should not be redialed on this
-     * slot. 
-     * {@hide}
+     * slot.
      */
     public static final int EMERGENCY_PERM_FAILURE = 64;
 
     /**
      * This cause is used to report a normal event only when no other cause in the normal class
      * applies.
-     * {@hide}
      */
     public static final int NORMAL_UNSPECIFIED = 65;
 
     /**
      * Stk Call Control modified DIAL request to video DIAL request.
-     * {@hide}
      */
     public static final int DIAL_MODIFIED_TO_DIAL_VIDEO = 66;
 
     /**
      * Stk Call Control modified Video DIAL request to SS request.
-     * {@hide}
      */
     public static final int DIAL_VIDEO_MODIFIED_TO_SS = 67;
 
     /**
      * Stk Call Control modified Video DIAL request to USSD request.
-     * {@hide}
      */
     public static final int DIAL_VIDEO_MODIFIED_TO_USSD = 68;
 
     /**
      * Stk Call Control modified Video DIAL request to DIAL request.
-     * {@hide}
      */
     public static final int DIAL_VIDEO_MODIFIED_TO_DIAL = 69;
 
     /**
      * Stk Call Control modified Video DIAL request to Video DIAL request.
-     * {@hide}
      */
     public static final int DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 70;
 
@@ -359,7 +344,10 @@
         // Do nothing.
     }
 
-    /** Returns descriptive string for the specified disconnect cause. */
+    /**
+     * Returns descriptive string for the specified disconnect cause.
+     * @hide
+     */
     @UnsupportedAppUsage
     public static String toString(int cause) {
         switch (cause) {
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index aee744f..b00665e 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -219,12 +219,13 @@
     public NetworkRegistrationState(int domain, int transportType, int regState,
             int accessNetworkTechnology, int rejectCause, boolean emergencyOnly,
             int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls,
-            boolean isDcNrRestricted, boolean isNrAvailable) {
+            boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable) {
         this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly,
                 availableServices, cellIdentity);
 
         mDataSpecificStates = new DataSpecificRegistrationStates(
-                maxDataCalls, isDcNrRestricted, isNrAvailable);
+                maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable);
+        updateNrStatus(mDataSpecificStates);
     }
 
     protected NetworkRegistrationState(Parcel source) {
@@ -448,6 +449,34 @@
         dest.writeInt(mNrStatus);
     }
 
+    /**
+     * Use the 5G NR Non-Standalone indicators from the network registration state to update the
+     * NR status. There are 3 indicators in the network registration state:
+     *
+     * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell.
+     * 2. if NR is supported by the selected PLMN.
+     * 3. if the use of dual connectivity with NR is restricted.
+     *
+     * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary
+     * serving cell.
+     *
+     * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of
+     * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G
+     * NR is restricted.
+     *
+     * @param state data specific registration state contains the 5G NR indicators.
+     */
+    private void updateNrStatus(DataSpecificRegistrationStates state) {
+        mNrStatus = NR_STATUS_NONE;
+        if (state.isEnDcAvailable) {
+            if (!state.isDcNrRestricted && state.isNrAvailable) {
+                mNrStatus = NR_STATUS_NOT_RESTRICTED;
+            } else {
+                mNrStatus = NR_STATUS_RESTRICTED;
+            }
+        }
+    }
+
     public static final Parcelable.Creator<NetworkRegistrationState> CREATOR =
             new Parcelable.Creator<NetworkRegistrationState>() {
         @Override
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index 4354314..4bca404 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -16,7 +16,6 @@
 
 package android.telephony;
 
-import android.annotation.CallSuper;
 import android.annotation.SystemApi;
 import android.app.Service;
 import android.content.Intent;
@@ -53,7 +52,6 @@
     private final String TAG = NetworkService.class.getSimpleName();
 
     public static final String NETWORK_SERVICE_INTERFACE = "android.telephony.NetworkService";
-    public static final String NETWORK_SERVICE_EXTRA_SLOT_ID = "android.telephony.extra.SLOT_ID";
 
     private static final int NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER                 = 1;
     private static final int NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER                 = 2;
@@ -81,7 +79,7 @@
      * must extend this class to support network connection. Note that each instance of network
      * service is associated with one physical SIM slot.
      */
-    public class NetworkServiceProvider {
+    public abstract class NetworkServiceProvider implements AutoCloseable {
         private final int mSlotId;
 
         private final List<INetworkServiceCallback>
@@ -137,12 +135,12 @@
         }
 
         /**
-         * Called when the instance of network service is destroyed (e.g. got unbind or binder died).
+         * Called when the instance of network service is destroyed (e.g. got unbind or binder died)
+         * or when the network service provider is removed. The extended class should implement this
+         * method to perform cleanup works.
          */
-        @CallSuper
-        protected void onDestroy() {
-            mNetworkRegistrationStateChangedCallbacks.clear();
-        }
+        @Override
+        public abstract void close();
     }
 
     private class NetworkServiceHandler extends Handler {
@@ -168,7 +166,7 @@
                 case NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER:
                     // If the service provider doesn't exist yet, we try to create it.
                     if (serviceProvider != null) {
-                        serviceProvider.onDestroy();
+                        serviceProvider.close();
                         mServiceMap.remove(slotId);
                     }
                     break;
@@ -176,7 +174,7 @@
                     for (int i = 0; i < mServiceMap.size(); i++) {
                         serviceProvider = mServiceMap.get(i);
                         if (serviceProvider != null) {
-                            serviceProvider.onDestroy();
+                            serviceProvider.close();
                         }
                     }
                     mServiceMap.clear();
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index e8a28ca..2b1628c 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -171,14 +171,14 @@
     public static final int LISTEN_CELL_INFO = 0x00000400;
 
     /**
-     * Listen for precise changes and fails to the device calls (cellular).
+     * Listen for {@link PreciseCallState.State} of ringing, background and foreground calls.
      * {@more}
      * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
      * READ_PRECISE_PHONE_STATE}
      *
      * @hide
      */
-    @UnsupportedAppUsage
+    @SystemApi
     public static final int LISTEN_PRECISE_CALL_STATE                       = 0x00000800;
 
     /**
@@ -316,6 +316,18 @@
      */
     public static final int LISTEN_EMERGENCY_NUMBER_LIST                   = 0x01000000;
 
+    /**
+     * Listen for call disconnect causes which contains {@link DisconnectCause} and
+     * {@link PreciseDisconnectCause}.
+     * {@more}
+     * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+     * READ_PRECISE_PHONE_STATE}
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int LISTEN_CALL_DISCONNECT_CAUSES                  = 0x02000000;
+
     /*
      * Subscription used to listen to the phone state changes
      * @hide
@@ -526,11 +538,23 @@
 
     /**
      * Callback invoked when precise device call state changes.
+     * @param callState {@link PreciseCallState}
+     * @hide
+     */
+    @SystemApi
+    public void onPreciseCallStateChanged(PreciseCallState callState) {
+        // default implementation empty
+    }
+
+    /**
+     * Callback invoked when call disconnect cause changes.
+     * @param disconnectCause {@link DisconnectCause}.
+     * @param preciseDisconnectCause {@link PreciseDisconnectCause}.
      *
      * @hide
      */
-    @UnsupportedAppUsage
-    public void onPreciseCallStateChanged(PreciseCallState callState) {
+    @SystemApi
+    public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) {
         // default implementation empty
     }
 
@@ -780,6 +804,15 @@
                     () -> mExecutor.execute(() -> psl.onPreciseCallStateChanged(callState)));
         }
 
+        public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) {
+            PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
+            if (psl == null) return;
+
+            Binder.withCleanCallingIdentity(
+                    () -> mExecutor.execute(() -> psl.onCallDisconnectCauseChanged(
+                            disconnectCause, preciseDisconnectCause)));
+        }
+
         public void onPreciseDataConnectionStateChanged(
                 PreciseDataConnectionState dataConnectionState) {
             PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index ed5c26a..59f3e1f 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -16,29 +16,51 @@
 
 package android.telephony;
 
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.DisconnectCause;
 import android.telephony.PreciseDisconnectCause;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
 /**
- * Contains precise call state and call fail causes generated by the
- * framework and the RIL.
+ * Contains precise call states.
  *
  * The following call information is included in returned PreciseCallState:
  *
  * <ul>
- *   <li>Ringing call state.
- *   <li>Foreground call state.
- *   <li>Background call state.
- *   <li>Disconnect cause; generated by the framework.
- *   <li>Precise disconnect cause; generated by the RIL.
+ *   <li>Precise ringing call state.
+ *   <li>Precise foreground call state.
+ *   <li>Precise background call state.
  * </ul>
  *
+ * @see android.telephony.TelephonyManager.CallState which contains generic call states.
+ *
  * @hide
  */
-public class PreciseCallState implements Parcelable {
+@SystemApi
+public final class PreciseCallState implements Parcelable {
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"PRECISE_CALL_STATE_"},
+            value = {
+                    PRECISE_CALL_STATE_NOT_VALID,
+                    PRECISE_CALL_STATE_IDLE,
+                    PRECISE_CALL_STATE_ACTIVE,
+                    PRECISE_CALL_STATE_HOLDING,
+                    PRECISE_CALL_STATE_DIALING,
+                    PRECISE_CALL_STATE_ALERTING,
+                    PRECISE_CALL_STATE_INCOMING,
+                    PRECISE_CALL_STATE_WAITING,
+                    PRECISE_CALL_STATE_DISCONNECTED,
+                    PRECISE_CALL_STATE_DISCONNECTING})
+    public @interface State {}
 
     /** Call state is not valid (Not received a call state). */
     public static final int PRECISE_CALL_STATE_NOT_VALID =      -1;
@@ -61,9 +83,9 @@
     /** Call state: Disconnecting. */
     public static final int PRECISE_CALL_STATE_DISCONNECTING =  8;
 
-    private int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
-    private int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
-    private int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+    private @State int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
+    private @State int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+    private @State int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
     private int mDisconnectCause = DisconnectCause.NOT_VALID;
     private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
 
@@ -73,8 +95,9 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public PreciseCallState(int ringingCall, int foregroundCall, int backgroundCall,
-            int disconnectCause, int preciseDisconnectCause) {
+    public PreciseCallState(@State int ringingCall, @State int foregroundCall,
+                            @State int backgroundCall, int disconnectCause,
+                            int preciseDisconnectCause) {
         mRingingCallState = ringingCall;
         mForegroundCallState = foregroundCall;
         mBackgroundCallState = backgroundCall;
@@ -92,6 +115,8 @@
 
     /**
      * Construct a PreciseCallState object from the given parcel.
+     *
+     * @hide
      */
     private PreciseCallState(Parcel in) {
         mRingingCallState = in.readInt();
@@ -102,59 +127,23 @@
     }
 
     /**
-     * Get precise ringing call state
-     *
-     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
-     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
-     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
-     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
-     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
-     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
-     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
-     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
-     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
-     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+     * Returns the precise ringing call state.
      */
-    @UnsupportedAppUsage
-    public int getRingingCallState() {
+    public @State int getRingingCallState() {
         return mRingingCallState;
     }
 
     /**
-     * Get precise foreground call state
-     *
-     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
-     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
-     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
-     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
-     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
-     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
-     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
-     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
-     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
-     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+     * Returns the precise foreground call state.
      */
-    @UnsupportedAppUsage
-    public int getForegroundCallState() {
+    public @State int getForegroundCallState() {
         return mForegroundCallState;
     }
 
     /**
-     * Get precise background call state
-     *
-     * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
-     * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
-     * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
-     * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
-     * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
-     * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
-     * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
-     * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
-     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
-     * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+     * Returns the precise background call state.
      */
-    @UnsupportedAppUsage
-    public int getBackgroundCallState() {
+    public @State int getBackgroundCallState() {
         return mBackgroundCallState;
     }
 
@@ -199,6 +188,11 @@
      * @see DisconnectCause#CDMA_NOT_EMERGENCY
      * @see DisconnectCause#CDMA_ACCESS_BLOCKED
      * @see DisconnectCause#ERROR_UNSPECIFIED
+     *
+     * TODO: remove disconnect cause from preciseCallState as there is no link between random
+     * connection disconnect cause with foreground, background or ringing call.
+     *
+     * @hide
      */
     @UnsupportedAppUsage
     public int getDisconnectCause() {
@@ -238,6 +232,11 @@
      * @see PreciseDisconnectCause#CDMA_NOT_EMERGENCY
      * @see PreciseDisconnectCause#CDMA_ACCESS_BLOCKED
      * @see PreciseDisconnectCause#ERROR_UNSPECIFIED
+     *
+     * TODO: remove precise disconnect cause from preciseCallState as there is no link between
+     * random connection disconnect cause with foreground, background or ringing call.
+     *
+     * @hide
      */
     @UnsupportedAppUsage
     public int getPreciseDisconnectCause() {
@@ -272,14 +271,8 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + mRingingCallState;
-        result = prime * result + mForegroundCallState;
-        result = prime * result + mBackgroundCallState;
-        result = prime * result + mDisconnectCause;
-        result = prime * result + mPreciseDisconnectCause;
-        return result;
+        return Objects.hash(mRingingCallState, mForegroundCallState, mForegroundCallState,
+                mDisconnectCause, mPreciseDisconnectCause);
     }
 
     @Override
diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java
index 2acaf34..af88748 100644
--- a/telephony/java/android/telephony/PreciseDisconnectCause.java
+++ b/telephony/java/android/telephony/PreciseDisconnectCause.java
@@ -16,279 +16,329 @@
 
 package android.telephony;
 
+import android.annotation.SystemApi;
+
 /**
- * Contains precise disconnect call causes generated by the
- * framework and the RIL.
- *
+ * Contains precise disconnect call causes generated by the framework and the RIL.
  * @hide
  */
+@SystemApi
 public class PreciseDisconnectCause {
 
-    /** The disconnect cause is not valid (Not received a disconnect cause)*/
+    /** The disconnect cause is not valid (Not received a disconnect cause).*/
     public static final int NOT_VALID                                        = -1;
-    /** No disconnect cause provided. Generally a local disconnect or an incoming missed call */
+    /** No disconnect cause provided. Generally a local disconnect or an incoming missed call. */
     public static final int NO_DISCONNECT_CAUSE_AVAILABLE                    = 0;
     /**
      * The destination cannot be reached because the number, although valid,
-     * is not currently assigned
+     * is not currently assigned.
      */
     public static final int UNOBTAINABLE_NUMBER                              = 1;
-    /** The user cannot be reached because the network through which the call has been
-     *  routed does not serve the destination desired
+    /**
+     * The user cannot be reached because the network through which the call has been routed does
+     * not serve the destination desired.
      */
     public static final int NO_ROUTE_TO_DESTINATION                          = 3;
-    /** The channel most recently identified is not acceptable to the sending entity for
-     *  use in this call
+    /**
+     * The channel most recently identified is not acceptable to the sending entity for use in this
+     * call.
      */
     public static final int CHANNEL_UNACCEPTABLE                             = 6;
-    /** The MS has tried to access a service that the MS's network operator or service
-     *  provider is not prepared to allow
+    /**
+     * The mobile station (MS) has tried to access a service that the MS's network operator or
+     * service provider is not prepared to allow.
      */
     public static final int OPERATOR_DETERMINED_BARRING                      = 8;
-    /** One of the users involved in the call has requested that the call is cleared */
+    /** One of the users involved in the call has requested that the call is cleared. */
     public static final int NORMAL                                           = 16;
-    /** The called user is unable to accept another call */
+    /** The called user is unable to accept another call. */
     public static final int BUSY                                             = 17;
-    /** The user does not respond to a call establishment message with either an alerting
-     *  or connect indication within the prescribed period of time allocated
+    /**
+     * The user does not respond to a call establishment message with either an alerting or connect
+     * indication within the prescribed period of time allocated.
      */
     public static final int NO_USER_RESPONDING                               = 18;
-    /** The user has provided an alerting indication but has not provided a connect
-     *  indication within a prescribed period of time
+    /**
+     * The user has provided an alerting indication but has not provided a connect indication
+     * within a prescribed period of time.
      */
     public static final int NO_ANSWER_FROM_USER                              = 19;
-    /** The equipment sending this cause does not wish to accept this call */
+    /** The equipment sending this cause does not wish to accept this call. */
     public static final int CALL_REJECTED                                    = 21;
-    /** The called number is no longer assigned */
+    /** The called number is no longer assigned. */
     public static final int NUMBER_CHANGED                                   = 22;
-    /** This cause is returned to the network when a mobile station clears an active
-     *  call which is being pre-empted by another call with higher precedence
+    /**
+     * This cause is returned to the network when a mobile station clears an active call which is
+     * being pre-empted by another call with higher precedence.
      */
     public static final int PREEMPTION                                       = 25;
-    /** The destination indicated by the mobile station cannot be reached because
-     *  the interface to the destination is not functioning correctly
+    /**
+     * The destination indicated by the mobile station cannot be reached because the interface to
+     * the destination is not functioning correctly.
      */
     public static final int DESTINATION_OUT_OF_ORDER                         = 27;
-    /** The called party number is not a valid format or is not complete */
+    /** The called party number is not a valid format or is not complete. */
     public static final int INVALID_NUMBER_FORMAT                            = 28;
-    /** The facility requested by user can not be provided by the network */
+    /** The facility requested by user can not be provided by the network. */
     public static final int FACILITY_REJECTED                                = 29;
-    /** Provided in response to a STATUS ENQUIRY message */
+    /** Provided in response to a STATUS ENQUIRY message. */
     public static final int STATUS_ENQUIRY                                   = 30;
-    /** Reports a normal disconnect only when no other normal cause applies */
+    /** Reports a normal disconnect only when no other normal cause applies. */
     public static final int NORMAL_UNSPECIFIED                               = 31;
-    /** There is no channel presently available to handle the call */
+    /** There is no channel presently available to handle the call. */
     public static final int NO_CIRCUIT_AVAIL                                 = 34;
-    /** The network is not functioning correctly and that the condition is likely
-     *  to last a relatively long period of time
+    /**
+     * The network is not functioning correctly and that the condition is likely to last a
+     * relatively long period of time.
      */
     public static final int NETWORK_OUT_OF_ORDER                             = 38;
     /**
-     * The network is not functioning correctly and the condition is not likely to last
-     * a long period of time
+     * The network is not functioning correctly and the condition is not likely to last a long
+     * period of time.
      */
     public static final int TEMPORARY_FAILURE                                = 41;
-    /** The switching equipment is experiencing a period of high traffic */
+    /** The switching equipment is experiencing a period of high traffic. */
     public static final int SWITCHING_CONGESTION                             = 42;
-    /** The network could not deliver access information to the remote user as requested */
+    /** The network could not deliver access information to the remote user as requested. */
     public static final int ACCESS_INFORMATION_DISCARDED                     = 43;
-    /** The channel cannot be provided */
+    /** The channel cannot be provided. */
     public static final int CHANNEL_NOT_AVAIL                                = 44;
-    /** This cause is used to report a resource unavailable event only when no other
-     *  cause in the resource unavailable class applies
+    /**
+     * This cause is used to report a resource unavailable event only when no other cause in the
+     * resource unavailable class applies.
      */
     public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED             = 47;
-    /** The requested quality of service (ITU-T X.213) cannot be provided */
+    /** The requested quality of service (ITU-T X.213) cannot be provided. */
     public static final int QOS_NOT_AVAIL                                    = 49;
-    /** The facility could not be provided by the network because the user has no
-     *  complete subscription
+    /**
+     * The facility could not be provided by the network because the user has no complete
+     * subscription.
      */
     public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED                = 50;
-    /** Incoming calls are not allowed within this CUG */
+    /** Incoming calls are not allowed within this calling user group (CUG). */
     public static final int INCOMING_CALLS_BARRED_WITHIN_CUG                 = 55;
-    /** The mobile station is not authorized to use bearer capability requested */
+    /** The mobile station is not authorized to use bearer capability requested. */
     public static final int BEARER_CAPABILITY_NOT_AUTHORIZED                 = 57;
-    /** The requested bearer capability is not available at this time */
+    /** The requested bearer capability is not available at this time. */
     public static final int BEARER_NOT_AVAIL                                 = 58;
-    /** The service option is not availble at this time */
+    /** The service option is not availble at this time. */
     public static final int SERVICE_OPTION_NOT_AVAILABLE                     = 63;
-    /** The equipment sending this cause does not support the bearer capability requested */
+    /** The equipment sending this cause does not support the bearer capability requested. */
     public static final int BEARER_SERVICE_NOT_IMPLEMENTED                   = 65;
-    /** The call clearing is due to ACM being greater than or equal to ACMmax */
+    /** The call clearing is due to ACM being greater than or equal to ACMmax. */
     public static final int ACM_LIMIT_EXCEEDED                               = 68;
-    /** The equipment sending this cause does not support the requested facility */
+    /** The equipment sending this cause does not support the requested facility. */
     public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED               = 69;
-    /** The equipment sending this cause only supports the restricted version of
-     *  the requested bearer capability
+    /**
+     * The equipment sending this cause only supports the restricted version of the requested bearer
+     * capability.
      */
     public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE        = 70;
-    /** The service requested is not implemented at network */
+    /** The service requested is not implemented at network. */
     public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED                = 79;
-    /** The equipment sending this cause has received a message with a transaction identifier
-     *  which is not currently in use on the MS-network interface
+    /**
+     * The equipment sending this cause has received a message with a transaction identifier
+     * which is not currently in use on the mobile station network interface.
      */
     public static final int INVALID_TRANSACTION_IDENTIFIER                   = 81;
-    /** The called user for the incoming CUG call is not a member of the specified CUG */
+    /**
+     * The called user for the incoming CUG call is not a member of the specified calling user
+     * group (CUG).
+     */
     public static final int USER_NOT_MEMBER_OF_CUG                           = 87;
-    /** The equipment sending this cause has received a request which can't be accomodated */
+    /** The equipment sending this cause has received a request which can't be accomodated. */
     public static final int INCOMPATIBLE_DESTINATION                         = 88;
-    /** This cause is used to report receipt of a message with semantically incorrect contents */
+    /** This cause is used to report receipt of a message with semantically incorrect contents. */
     public static final int SEMANTICALLY_INCORRECT_MESSAGE                   = 95;
-    /** The equipment sending this cause has received a message with a non-semantical
-     *  mandatory IE error
+    /**
+     * The equipment sending this cause has received a message with a non-semantical mandatory
+     * information element (IE) error.
      */
     public static final int INVALID_MANDATORY_INFORMATION                    = 96;
-    /** This is sent in response to a message which is not defined, or defined but not
-     *  implemented by the equipment sending this cause
+    /**
+     * This is sent in response to a message which is not defined, or defined but not implemented
+     * by the equipment sending this cause.
      */
     public static final int MESSAGE_TYPE_NON_IMPLEMENTED                     = 97;
-    /** The equipment sending this cause has received a message not compatible with the
-     *  protocol state
+    /**
+     * The equipment sending this cause has received a message not compatible with the protocol
+     * state.
      */
     public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE  = 98;
-    /** The equipment sending this cause has received a message which includes information
-     *  elements not recognized because its identifier is not defined or it is defined but not
-     *  implemented by the equipment sending the cause
+    /**
+     * The equipment sending this cause has received a message which includes information
+     * elements not recognized because its identifier is not defined or it is defined but not
+     * implemented by the equipment sending the cause.
      */
     public static final int INFORMATION_ELEMENT_NON_EXISTENT                 = 99;
-    /** The equipment sending this cause has received a message with conditional IE errors */
+    /** The equipment sending this cause has received a message with conditional IE errors. */
     public static final int CONDITIONAL_IE_ERROR                             = 100;
-    /** The message has been received which is incompatible with the protocol state */
+    /** The message has been received which is incompatible with the protocol state. */
     public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE       = 101;
-    /** The  procedure has been initiated by the expiry of a timer in association with
-     *  3GPP TS 24.008 error handling procedures
+    /**
+     * The procedure has been initiated by the expiry of a timer in association with
+     * 3GPP TS 24.008 error handling procedures.
      */
     public static final int RECOVERY_ON_TIMER_EXPIRED                        = 102;
-    /** This protocol error event is reported only when no other cause in the protocol
-     *  error class applies
+    /**
+     * This protocol error event is reported only when no other cause in the protocol error class
+     * applies.
      */
     public static final int PROTOCOL_ERROR_UNSPECIFIED                       = 111;
-    /** interworking with a network which does not provide causes for actions it takes
-     *  thus, the precise cause for a message which is being sent cannot be ascertained
+    /**
+     * Interworking with a network which does not provide causes for actions it takes thus, the
+     * precise cause for a message which is being sent cannot be ascertained.
      */
     public static final int INTERWORKING_UNSPECIFIED                         = 127;
-    /** The call is restricted */
+    /** The call is restricted. */
     public static final int CALL_BARRED                                      = 240;
-    /** The call is blocked by the Fixed Dialing Number list */
+    /** The call is blocked by the Fixed Dialing Number list. */
     public static final int FDN_BLOCKED                                      = 241;
-    /** The given IMSI is not known at the VLR */
-    /** TS 24.008 cause 4 */
+    /** The given IMSI is not known at the Visitor Location Register (VLR) TS 24.008 cause . */
     public static final int IMSI_UNKNOWN_IN_VLR                              = 242;
     /**
      * The network does not accept emergency call establishment using an IMEI or not accept attach
-     * procedure for emergency services using an IMEI
+     * procedure for emergency services using an IMEI.
      */
     public static final int IMEI_NOT_ACCEPTED                                = 243;
-    /** The call cannot be established because RADIO is OFF */
+    /** The call cannot be established because RADIO is OFF. */
     public static final int RADIO_OFF                                        = 247;
-    /** The call cannot be established because of no cell coverage */
+    /** The call cannot be established because of no cell coverage. */
     public static final int OUT_OF_SRV                                       = 248;
-    /** The call cannot be established because of no valid SIM */
+    /** The call cannot be established because of no valid SIM. */
     public static final int NO_VALID_SIM                                     = 249;
-    /** The call is dropped or failed internally by modem */
+    /** The call is dropped or failed internally by modem. */
     public static final int RADIO_INTERNAL_ERROR                             = 250;
-    /** Call failed because of UE timer expired while waiting for a response from network */
+    /** Call failed because of UE timer expired while waiting for a response from network. */
     public static final int NETWORK_RESP_TIMEOUT                             = 251;
-    /** Call failed because of a network reject */
+    /** Call failed because of a network reject. */
     public static final int NETWORK_REJECT                                   = 252;
-    /** Call failed because of radio access failure. ex. RACH failure */
+    /** Call failed because of radio access failure. ex. RACH failure. */
     public static final int RADIO_ACCESS_FAILURE                             = 253;
-    /** Call failed/dropped because of a RLF */
+    /** Call failed/dropped because of a Radio Link Failure (RLF). */
     public static final int RADIO_LINK_FAILURE                               = 254;
-    /** Call failed/dropped because of radio link lost */
+    /** Call failed/dropped because of radio link lost. */
     public static final int RADIO_LINK_LOST                                  = 255;
-    /** Call failed because of a radio uplink issue */
+    /** Call failed because of a radio uplink issue. */
     public static final int RADIO_UPLINK_FAILURE                             = 256;
-    /** Call failed because of a RRC connection setup failure */
+    /** Call failed because of a RRC (Radio Resource Control) connection setup failure. */
     public static final int RADIO_SETUP_FAILURE                              = 257;
-    /** Call failed/dropped because of RRC connection release from NW */
+    /** Call failed/dropped because of RRC (Radio Resource Control) connection release from NW. */
     public static final int RADIO_RELEASE_NORMAL                             = 258;
-    /** Call failed/dropped because of RRC abnormally released by modem/network */
+    /**
+     * Call failed/dropped because of RRC (Radio Resource Control) abnormally released by
+     * modem/network.
+     */
     public static final int RADIO_RELEASE_ABNORMAL                           = 259;
-    /** Call setup failed because of access class barring */
+    /** Call setup failed because of access class barring. */
     public static final int ACCESS_CLASS_BLOCKED                             = 260;
-    /** Call failed/dropped because of a network detach */
+    /** Call failed/dropped because of a network detach. */
     public static final int NETWORK_DETACH                                   = 261;
 
-    /** MS is locked until next power cycle */
+    /** Mobile station (MS) is locked until next power cycle. */
     public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE                    = 1000;
-    /** Drop call*/
+    /** Drop call. */
     public static final int CDMA_DROP                                        = 1001;
-    /** INTERCEPT order received, MS state idle entered */
+    /** INTERCEPT order received, Mobile station (MS) state idle entered. */
     public static final int CDMA_INTERCEPT                                   = 1002;
-    /** MS has been redirected, call is cancelled */
+    /** Mobile station (MS) has been redirected, call is cancelled. */
     public static final int CDMA_REORDER                                     = 1003;
-    /** Service option rejection */
+    /** Service option rejection. */
     public static final int CDMA_SO_REJECT                                   = 1004;
-    /** Requested service is rejected, retry delay is set */
+    /** Requested service is rejected, retry delay is set. */
     public static final int CDMA_RETRY_ORDER                                 = 1005;
-    /** Unable to obtain access to the CDMA system */
+    /** Unable to obtain access to the CDMA system. */
     public static final int CDMA_ACCESS_FAILURE                              = 1006;
-    /** Not a preempted call */
+    /** Not a preempted call. */
     public static final int CDMA_PREEMPTED                                   = 1007;
-    /** Not an emergency call */
+    /** Not an emergency call. */
     public static final int CDMA_NOT_EMERGENCY                               = 1008;
-    /** Access Blocked by CDMA network */
+    /** Access Blocked by CDMA network. */
     public static final int CDMA_ACCESS_BLOCKED                              = 1009;
 
     /** Mapped from ImsReasonInfo */
+    // TODO: remove ImsReasonInfo from preciseDisconnectCause
     /* The passed argument is an invalid */
+    /** @hide */
     public static final int LOCAL_ILLEGAL_ARGUMENT                           = 1200;
     // The operation is invoked in invalid call state
+    /** @hide */
     public static final int LOCAL_ILLEGAL_STATE                              = 1201;
     // IMS service internal error
+    /** @hide */
     public static final int LOCAL_INTERNAL_ERROR                             = 1202;
     // IMS service goes down (service connection is lost)
+    /** @hide */
     public static final int LOCAL_IMS_SERVICE_DOWN                           = 1203;
     // No pending incoming call exists
+    /** @hide */
     public static final int LOCAL_NO_PENDING_CALL                            = 1204;
     // Service unavailable; by power off
+    /** @hide */
     public static final int LOCAL_POWER_OFF                                  = 1205;
     // Service unavailable; by low battery
+    /** @hide */
     public static final int LOCAL_LOW_BATTERY                                = 1206;
     // Service unavailable; by out of service (data service state)
+    /** @hide */
     public static final int LOCAL_NETWORK_NO_SERVICE                         = 1207;
     /* Service unavailable; by no LTE coverage
      * (VoLTE is not supported even though IMS is registered)
      */
+    /** @hide */
     public static final int LOCAL_NETWORK_NO_LTE_COVERAGE                    = 1208;
     /** Service unavailable; by located in roaming area */
+    /** @hide */
     public static final int LOCAL_NETWORK_ROAMING                            = 1209;
     /** Service unavailable; by IP changed */
+    /** @hide */
     public static final int LOCAL_NETWORK_IP_CHANGED                         = 1210;
     /** Service unavailable; other */
+    /** @hide */
     public static final int LOCAL_SERVICE_UNAVAILABLE                        = 1211;
     /* Service unavailable; IMS connection is lost (IMS is not registered) */
+    /** @hide */
     public static final int LOCAL_NOT_REGISTERED                             = 1212;
     /** Max call exceeded */
+    /** @hide */
     public static final int LOCAL_MAX_CALL_EXCEEDED                          = 1213;
     /** Call decline */
+    /** @hide */
     public static final int LOCAL_CALL_DECLINE                               = 1214;
     /** SRVCC is in progress */
+    /** @hide */
     public static final int LOCAL_CALL_VCC_ON_PROGRESSING                    = 1215;
     /** Resource reservation is failed (QoS precondition) */
+    /** @hide */
     public static final int LOCAL_CALL_RESOURCE_RESERVATION_FAILED           = 1216;
     /** Retry CS call; VoLTE service can't be provided by the network or remote end
      *  Resolve the extra code(EXTRA_CODE_CALL_RETRY_*) if the below code is set
+     *  @hide
      */
     public static final int LOCAL_CALL_CS_RETRY_REQUIRED                     = 1217;
     /** Retry VoLTE call; VoLTE service can't be provided by the network temporarily */
+    /** @hide */
     public static final int LOCAL_CALL_VOLTE_RETRY_REQUIRED                  = 1218;
     /** IMS call is already terminated (in TERMINATED state) */
+    /** @hide */
     public static final int LOCAL_CALL_TERMINATED                            = 1219;
     /** Handover not feasible */
+    /** @hide */
     public static final int LOCAL_HO_NOT_FEASIBLE                            = 1220;
 
     /** 1xx waiting timer is expired after sending INVITE request (MO only) */
+    /** @hide */
     public static final int TIMEOUT_1XX_WAITING                              = 1221;
     /** User no answer during call setup operation (MO/MT)
      *  MO : 200 OK to INVITE request is not received,
      *  MT : No action from user after alerting the call
+     *  @hide
      */
     public static final int TIMEOUT_NO_ANSWER                                = 1222;
     /** User no answer during call update operation (MO/MT)
      *  MO : 200 OK to re-INVITE request is not received,
      *  MT : No action from user after alerting the call
+     *  @hide
      */
     public static final int TIMEOUT_NO_ANSWER_CALL_UPDATE                    = 1223;
 
@@ -296,102 +346,142 @@
      * STATUSCODE (SIP response code) (IMS -> Telephony)
      */
     /** SIP request is redirected */
+    /** @hide */
     public static final int SIP_REDIRECTED                                   = 1300;
     /** 4xx responses */
     /** 400 : Bad Request */
+    /** @hide */
     public static final int SIP_BAD_REQUEST                                  = 1310;
     /** 403 : Forbidden */
+    /** @hide */
     public static final int SIP_FORBIDDEN                                    = 1311;
     /** 404 : Not Found */
+    /** @hide */
     public static final int SIP_NOT_FOUND                                    = 1312;
     /** 415 : Unsupported Media Type
      *  416 : Unsupported URI Scheme
      *  420 : Bad Extension
      */
+    /** @hide */
     public static final int SIP_NOT_SUPPORTED                                = 1313;
     /** 408 : Request Timeout */
+    /** @hide */
     public static final int SIP_REQUEST_TIMEOUT                              = 1314;
     /** 480 : Temporarily Unavailable */
+    /** @hide */
     public static final int SIP_TEMPRARILY_UNAVAILABLE                       = 1315;
     /** 484 : Address Incomplete */
+    /** @hide */
     public static final int SIP_BAD_ADDRESS                                  = 1316;
     /** 486 : Busy Here
      *  600 : Busy Everywhere
      */
+    /** @hide */
     public static final int SIP_BUSY                                         = 1317;
     /** 487 : Request Terminated */
+    /** @hide */
     public static final int SIP_REQUEST_CANCELLED                            = 1318;
     /** 406 : Not Acceptable
      *  488 : Not Acceptable Here
      *  606 : Not Acceptable
      */
+    /** @hide */
     public static final int SIP_NOT_ACCEPTABLE                               = 1319;
     /** 410 : Gone
      *  604 : Does Not Exist Anywhere
      */
+    /** @hide */
     public static final int SIP_NOT_REACHABLE                                = 1320;
     /** Others */
+    /** @hide */
     public static final int SIP_CLIENT_ERROR                                 = 1321;
     /** 481 : Transaction Does Not Exist */
+    /** @hide */
     public static final int SIP_TRANSACTION_DOES_NOT_EXIST                   = 1322;
     /** 5xx responses
      *  501 : Server Internal Error
      */
+    /** @hide */
     public static final int SIP_SERVER_INTERNAL_ERROR                        = 1330;
     /** 503 : Service Unavailable */
+    /** @hide */
     public static final int SIP_SERVICE_UNAVAILABLE                          = 1331;
     /** 504 : Server Time-out */
+    /** @hide */
     public static final int SIP_SERVER_TIMEOUT                               = 1332;
     /** Others */
+    /** @hide */
     public static final int SIP_SERVER_ERROR                                 = 1333;
     /** 6xx responses
      *  603 : Decline
      */
+    /** @hide */
     public static final int SIP_USER_REJECTED                                = 1340;
     /** Others */
+    /** @hide */
     public static final int SIP_GLOBAL_ERROR                                 = 1341;
     /** Emergency failure */
+    /** @hide */
     public static final int EMERGENCY_TEMP_FAILURE                           = 1342;
+    /** @hide */
     public static final int EMERGENCY_PERM_FAILURE                           = 1343;
     /** Media resource initialization failed */
+    /** @hide */
     public static final int MEDIA_INIT_FAILED                                = 1400;
     /** RTP timeout (no audio / video traffic in the session) */
+    /** @hide */
     public static final int MEDIA_NO_DATA                                    = 1401;
     /** Media is not supported; so dropped the call */
+    /** @hide */
     public static final int MEDIA_NOT_ACCEPTABLE                             = 1402;
     /** Unknown media related errors */
+    /** @hide */
     public static final int MEDIA_UNSPECIFIED                                = 1403;
     /** User triggers the call end */
+    /** @hide */
     public static final int USER_TERMINATED                                  = 1500;
     /** No action while an incoming call is ringing */
+    /** @hide */
     public static final int USER_NOANSWER                                    = 1501;
     /** User ignores an incoming call */
+    /** @hide */
     public static final int USER_IGNORE                                      = 1502;
     /** User declines an incoming call */
+    /** @hide */
     public static final int USER_DECLINE                                     = 1503;
     /** Device declines/ends a call due to low battery */
+    /** @hide */
     public static final int LOW_BATTERY                                      = 1504;
     /** Device declines call due to blacklisted call ID */
+    /** @hide */
     public static final int BLACKLISTED_CALL_ID                              = 1505;
     /** The call is terminated by the network or remote user */
+    /** @hide */
     public static final int USER_TERMINATED_BY_REMOTE                        = 1510;
 
     /**
      * UT
      */
+    /** @hide */
     public static final int UT_NOT_SUPPORTED                                 = 1800;
+    /** @hide */
     public static final int UT_SERVICE_UNAVAILABLE                           = 1801;
+    /** @hide */
     public static final int UT_OPERATION_NOT_ALLOWED                         = 1802;
+    /** @hide */
     public static final int UT_NETWORK_ERROR                                 = 1803;
+    /** @hide */
     public static final int UT_CB_PASSWORD_MISMATCH                          = 1804;
 
     /**
      * ECBM
+     * @hide
      */
     public static final int ECBM_NOT_SUPPORTED                               = 1900;
 
     /**
      * Fail code used to indicate that Multi-endpoint is not supported by the Ims framework.
+     * @hide
      */
     public static final int MULTIENDPOINT_NOT_SUPPORTED                      = 1901;
 
@@ -405,56 +495,68 @@
      * active wifi call and at the edge of coverage and there is no qualified LTE network available
      * to handover the call to. We get a handover NOT_TRIGERRED message from the modem. This error
      * code is received as part of the handover message.
+     * @hide
      */
     public static final int CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE               = 2000;
 
     /**
      * MT call has ended due to a release from the network
      * because the call was answered elsewhere
+     * @hide
      */
     public static final int ANSWERED_ELSEWHERE                               = 2100;
 
     /**
      * For MultiEndpoint - Call Pull request has failed
+     * @hide
      */
     public static final int CALL_PULL_OUT_OF_SYNC                            = 2101;
 
     /**
      * For MultiEndpoint - Call has been pulled from primary to secondary
+     * @hide
      */
     public static final int CALL_PULLED                                      = 2102;
 
     /**
      * Supplementary services (HOLD/RESUME) failure error codes.
      * Values for Supplemetary services failure - Failed, Cancelled and Re-Invite collision.
+     * @hide
      */
     public static final int SUPP_SVC_FAILED                                  = 2300;
+    /** @hide */
     public static final int SUPP_SVC_CANCELLED                               = 2301;
+    /** @hide */
     public static final int SUPP_SVC_REINVITE_COLLISION                      = 2302;
 
     /**
      * DPD Procedure received no response or send failed
+     * @hide
      */
     public static final int IWLAN_DPD_FAILURE                                = 2400;
 
     /**
      * Establishment of the ePDG Tunnel Failed
+     * @hide
      */
     public static final int EPDG_TUNNEL_ESTABLISH_FAILURE                    = 2500;
 
     /**
      * Re-keying of the ePDG Tunnel Failed; may not always result in teardown
+     * @hide
      */
     public static final int EPDG_TUNNEL_REKEY_FAILURE                        = 2501;
 
     /**
      * Connection to the packet gateway is lost
+     * @hide
      */
     public static final int EPDG_TUNNEL_LOST_CONNECTION                      = 2502;
 
     /**
      * The maximum number of calls allowed has been reached.  Used in a multi-endpoint scenario
      * where the number of calls across all connected devices has reached the maximum.
+     * @hide
      */
     public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED                  = 2503;
 
@@ -462,21 +564,25 @@
      * Similar to {@link #CODE_LOCAL_CALL_DECLINE}, except indicates that a remote device has
      * declined the call.  Used in a multi-endpoint scenario where a remote device declined an
      * incoming call.
+     * @hide
      */
     public static final int REMOTE_CALL_DECLINE                              = 2504;
 
     /**
      * Indicates the call was disconnected due to the user reaching their data limit.
+     * @hide
      */
     public static final int DATA_LIMIT_REACHED                               = 2505;
 
     /**
      * Indicates the call was disconnected due to the user disabling cellular data.
+     * @hide
      */
     public static final int DATA_DISABLED                                    = 2506;
 
     /**
      * Indicates a call was disconnected due to loss of wifi signal.
+     * @hide
      */
     public static final int WIFI_LOST                                        = 2507;
 
@@ -499,7 +605,7 @@
     public static final int OEM_CAUSE_14                                     = 0xf00e;
     public static final int OEM_CAUSE_15                                     = 0xf00f;
 
-    /** Disconnected due to unspecified reasons */
+    /** Disconnected due to unspecified reasons. */
     public static final int ERROR_UNSPECIFIED                                = 0xffff;
 
     /** Private constructor to avoid class instantiation. */
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 13fbeaa..ca0c854 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -118,6 +118,13 @@
      */
     public static final int FREQUENCY_RANGE_MMWAVE = 4;
 
+    private static final List<Integer> FREQUENCY_RANGE_ORDER = Arrays.asList(
+            FREQUENCY_RANGE_UNKNOWN,
+            FREQUENCY_RANGE_LOW,
+            FREQUENCY_RANGE_MID,
+            FREQUENCY_RANGE_HIGH,
+            FREQUENCY_RANGE_MMWAVE);
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = "DUPLEX_MODE_",
@@ -1835,4 +1842,13 @@
             mNetworkRegistrationStates.add(regState);
         }
     }
+
+    /**
+     * @hide
+     */
+    public static final int getBetterNRFrequencyRange(int range1, int range2) {
+        return FREQUENCY_RANGE_ORDER.indexOf(range1) > FREQUENCY_RANGE_ORDER.indexOf(range2)
+                ? range1
+                : range2;
+    }
 }
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 240b8a9..ef185c5 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -16,16 +16,14 @@
 
 package android.telephony;
 
+import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.telephony.CarrierConfigManager;
-import android.util.Log;
+import android.os.PersistableBundle;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Objects;
 
 /**
@@ -59,6 +57,8 @@
     /** @hide */
     @UnsupportedAppUsage
     public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
+
+    /** SIGNAL_STRENGTH_NAMES is currently used by BatteryStats, but to-be-removed soon. */
     /** @hide */
     public static final String[] SIGNAL_STRENGTH_NAMES = {
         "none", "poor", "moderate", "good", "great"
@@ -72,66 +72,22 @@
     public static final int INVALID = Integer.MAX_VALUE;
 
     private static final int LTE_RSRP_THRESHOLDS_NUM = 4;
-    private static final int MAX_LTE_RSRP = -44;
-    private static final int MIN_LTE_RSRP = -140;
 
     private static final int WCDMA_RSCP_THRESHOLDS_NUM = 4;
-    private static final int MAX_WCDMA_RSCP = -24;
-    private static final int MIN_WCDMA_RSCP = -120;
 
     /* The type of signal measurement */
-    private static final String MEASUMENT_TYPE_RSCP = "rscp";
+    private static final String MEASUREMENT_TYPE_RSCP = "rscp";
 
-    /** Parameters reported by the Radio */
-    @UnsupportedAppUsage
-    private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
-    @UnsupportedAppUsage
-    private int mGsmBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
-    @UnsupportedAppUsage
-    private int mCdmaDbm;   // This value is the RSSI value
-    @UnsupportedAppUsage
-    private int mCdmaEcio;  // This value is the Ec/Io
-    @UnsupportedAppUsage
-    private int mEvdoDbm;   // This value is the EVDO RSSI value
-    @UnsupportedAppUsage
-    private int mEvdoEcio;  // This value is the EVDO Ec/Io
-    @UnsupportedAppUsage
-    private int mEvdoSnr;   // Valid values are 0-8.  8 is the highest signal to noise ratio
-    @UnsupportedAppUsage
-    private int mLteSignalStrength;
-    @UnsupportedAppUsage
-    private int mLteRsrp;
-    @UnsupportedAppUsage
-    private int mLteRsrq;
-    @UnsupportedAppUsage
-    private int mLteRssnr;
-    @UnsupportedAppUsage
-    private int mLteCqi;
-    @UnsupportedAppUsage
-    private int mTdScdmaRscp; // Valid values are -24...-120dBm or INVALID if unknown
-    private int mWcdmaSignalStrength;
-    private int mWcdmaRscpAsu;  // the WCDMA RSCP in ASU as reported from the HAL
-    @UnsupportedAppUsage
-    private int mWcdmaRscp;     // the WCDMA RSCP in dBm
+    CellSignalStrengthCdma mCdma;
+    CellSignalStrengthGsm mGsm;
+    CellSignalStrengthWcdma mWcdma;
+    CellSignalStrengthTdscdma mTdscdma;
+    CellSignalStrengthLte mLte;
 
     /** Parameters from the framework */
     @UnsupportedAppUsage
     private int mLteRsrpBoost; // offset to be reduced from the rsrp threshold while calculating
                                 // signal strength level
-    private boolean mIsGsm; // This value is set by the ServiceStateTracker
-                            // onSignalStrengthResult.
-    private boolean mUseOnlyRsrpForLteLevel; // Use only RSRP for the number of LTE signal bar.
-
-    // The threshold of LTE RSRP for determining the display level of LTE signal bar. Note that the
-    // min and max are fixed at MIN_LTE_RSRP (-140) and MAX_LTE_RSRP (-44).
-    private int mLteRsrpThresholds[] = new int[LTE_RSRP_THRESHOLDS_NUM];
-
-    // The type of default measurement for determining the display level of WCDMA signal bar.
-    private String mWcdmaDefaultSignalMeasurement;
-
-    // The threshold of WCDMA RSCP for determining the display level of WCDMA signal bar. Note that
-    // the min and max are fixed at MIN_WCDMA_RSCP (-120) and MAX_WCDMA_RSCP (-24).
-    private int mWcdmaRscpThresholds[] = new int[WCDMA_RSCP_THRESHOLDS_NUM];
 
     /**
      * Create a new SignalStrength from a intent notifier Bundle
@@ -153,47 +109,17 @@
     }
 
     /**
-     * Empty constructor
-     *
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public SignalStrength() {
-        this(true);
-    }
-
-    /**
      * This constructor is used to create SignalStrength with default
-     * values and set the gsmFlag with the value passed in the input
+     * values.
      *
-     * @param gsmFlag true if Gsm Phone,false if Cdma phone
      * @return newly created SignalStrength
      * @hide
      */
     @UnsupportedAppUsage
-    public SignalStrength(boolean gsmFlag) {
-        mGsmSignalStrength = 99;
-        mGsmBitErrorRate = -1;
-        mCdmaDbm = INVALID;
-        mCdmaEcio = -1;
-        mEvdoDbm = INVALID;
-        mEvdoEcio = -1;
-        mEvdoSnr = -1;
-        mLteSignalStrength = 99;
-        mLteRsrp = INVALID;
-        mLteRsrq = INVALID;
-        mLteRssnr = INVALID;
-        mLteCqi = INVALID;
-        mTdScdmaRscp = INVALID;
-        mWcdmaSignalStrength = 99;
-        mWcdmaRscp = INVALID;
-        mWcdmaRscpAsu = 255;
-        mLteRsrpBoost = 0;
-        mIsGsm = gsmFlag;
-        mUseOnlyRsrpForLteLevel = false;
-        mWcdmaDefaultSignalMeasurement = "";
-        setLteRsrpThresholds(getDefaultLteRsrpThresholds());
-        setWcdmaRscpThresholds(getDefaultWcdmaRscpThresholds());
+    public SignalStrength() {
+        this(new CellSignalStrengthCdma(), new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(), new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte());
     }
 
     /**
@@ -202,68 +128,64 @@
      * @hide
      */
     public SignalStrength(
-            int gsmSignalStrength, int gsmBitErrorRate,
-            int cdmaDbm, int cdmaEcio,
-            int evdoDbm, int evdoEcio, int evdoSnr,
-            int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
-            int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscpAsu,
-            // values Added by config
-            int lteRsrpBoost, boolean gsmFlag, boolean lteLevelBaseOnRsrp,
-            String wcdmaDefaultMeasurement) {
-        mGsmSignalStrength = gsmSignalStrength;
-        mGsmBitErrorRate = gsmBitErrorRate;
-        mCdmaDbm = cdmaDbm;
-        mCdmaEcio = cdmaEcio;
-        mEvdoDbm = evdoDbm;
-        mEvdoEcio = evdoEcio;
-        mEvdoSnr = evdoSnr;
-        mLteSignalStrength = lteSignalStrength;
-        mLteRsrp = lteRsrp;
-        mLteRsrq = lteRsrq;
-        mLteRssnr = lteRssnr;
-        mLteCqi = lteCqi;
-        mTdScdmaRscp = INVALID;
-        mWcdmaSignalStrength = wcdmaSignalStrength;
-        mWcdmaRscpAsu = wcdmaRscpAsu;
-        mWcdmaRscp = wcdmaRscpAsu - 120;
-        mLteRsrpBoost = lteRsrpBoost;
-        mIsGsm = gsmFlag;
-        mUseOnlyRsrpForLteLevel = lteLevelBaseOnRsrp;
-        mWcdmaDefaultSignalMeasurement = wcdmaDefaultMeasurement;
-        setLteRsrpThresholds(getDefaultLteRsrpThresholds());
-        setWcdmaRscpThresholds(getDefaultWcdmaRscpThresholds());
-        if (DBG) log("initialize: " + toString());
+            @NonNull CellSignalStrengthCdma cdma,
+            @NonNull CellSignalStrengthGsm gsm,
+            @NonNull CellSignalStrengthWcdma wcdma,
+            @NonNull CellSignalStrengthTdscdma tdscdma,
+            @NonNull CellSignalStrengthLte lte) {
+        mCdma = cdma;
+        mGsm = gsm;
+        mWcdma = wcdma;
+        mTdscdma = tdscdma;
+        mLte = lte;
+        mLteRsrpBoost = 0;
     }
 
     /**
-     * Constructor for only values provided by Radio HAL V1.0
+     * Constructor for Radio HAL V1.0
      *
      * @hide
      */
-    public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
-            int cdmaDbm, int cdmaEcio,
-            int evdoDbm, int evdoEcio, int evdoSnr,
-            int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
-            int tdScdmaRscp) {
-        this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
-                evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
-                lteRsrq, lteRssnr, lteCqi, tdScdmaRscp, 99, INVALID, 0, true, false, "");
+    public SignalStrength(android.hardware.radio.V1_0.SignalStrength signalStrength) {
+        this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo),
+                new CellSignalStrengthGsm(signalStrength.gw),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(signalStrength.tdScdma),
+                new CellSignalStrengthLte(signalStrength.lte));
     }
 
     /**
-     * Constructor for only values provided by Radio HAL V1.2
+     * Constructor for Radio HAL V1.2
      *
      * @hide
      */
-    public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
-            int cdmaDbm, int cdmaEcio,
-            int evdoDbm, int evdoEcio, int evdoSnr,
-            int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
-            int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscp) {
-        this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
-                evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
-                lteRsrq, lteRssnr, lteCqi, tdScdmaRscp, wcdmaSignalStrength, wcdmaRscp, 0, true,
-                false, "");
+    public SignalStrength(android.hardware.radio.V1_2.SignalStrength signalStrength) {
+        this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo),
+                new CellSignalStrengthGsm(signalStrength.gsm),
+                new CellSignalStrengthWcdma(signalStrength.wcdma),
+                new CellSignalStrengthTdscdma(signalStrength.tdScdma),
+                new CellSignalStrengthLte(signalStrength.lte));
+    }
+
+    private CellSignalStrength getPrimary() {
+        // This behavior is intended to replicate the legacy behavior of getLevel() by prioritizing
+        // newer faster RATs for default/for display purposes.
+        if (mLte.isValid()) return mLte;
+        if (mCdma.isValid()) return mCdma;
+        if (mTdscdma.isValid()) return mTdscdma;
+        if (mWcdma.isValid()) return mWcdma;
+        if (mGsm.isValid()) return mGsm;
+        return mLte;
+    }
+
+    /** @hide */
+    public void updateLevel(PersistableBundle cc, ServiceState ss) {
+        mLteRsrpBoost = ss.getLteEarfcnRsrpBoost();
+        mCdma.updateLevel(cc, ss);
+        mGsm.updateLevel(cc, ss);
+        mWcdma.updateLevel(cc, ss);
+        mTdscdma.updateLevel(cc, ss);
+        mLte.updateLevel(cc, ss);
     }
 
     /**
@@ -283,28 +205,12 @@
      */
     @UnsupportedAppUsage
     protected void copyFrom(SignalStrength s) {
-        mGsmSignalStrength = s.mGsmSignalStrength;
-        mGsmBitErrorRate = s.mGsmBitErrorRate;
-        mCdmaDbm = s.mCdmaDbm;
-        mCdmaEcio = s.mCdmaEcio;
-        mEvdoDbm = s.mEvdoDbm;
-        mEvdoEcio = s.mEvdoEcio;
-        mEvdoSnr = s.mEvdoSnr;
-        mLteSignalStrength = s.mLteSignalStrength;
-        mLteRsrp = s.mLteRsrp;
-        mLteRsrq = s.mLteRsrq;
-        mLteRssnr = s.mLteRssnr;
-        mLteCqi = s.mLteCqi;
-        mTdScdmaRscp = s.mTdScdmaRscp;
-        mWcdmaSignalStrength = s.mWcdmaSignalStrength;
-        mWcdmaRscpAsu = s.mWcdmaRscpAsu;
-        mWcdmaRscp = s.mWcdmaRscp;
+        mCdma = new CellSignalStrengthCdma(s.mCdma);
+        mGsm = new CellSignalStrengthGsm(s.mGsm);
+        mWcdma = new CellSignalStrengthWcdma(s.mWcdma);
+        mTdscdma = new CellSignalStrengthTdscdma(s.mTdscdma);
+        mLte = new CellSignalStrengthLte(s.mLte);
         mLteRsrpBoost = s.mLteRsrpBoost;
-        mIsGsm = s.mIsGsm;
-        mUseOnlyRsrpForLteLevel = s.mUseOnlyRsrpForLteLevel;
-        mWcdmaDefaultSignalMeasurement = s.mWcdmaDefaultSignalMeasurement;
-        setLteRsrpThresholds(s.mLteRsrpThresholds);
-        setWcdmaRscpThresholds(s.mWcdmaRscpThresholds);
     }
 
     /**
@@ -316,56 +222,25 @@
     public SignalStrength(Parcel in) {
         if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
 
-        mGsmSignalStrength = in.readInt();
-        mGsmBitErrorRate = in.readInt();
-        mCdmaDbm = in.readInt();
-        mCdmaEcio = in.readInt();
-        mEvdoDbm = in.readInt();
-        mEvdoEcio = in.readInt();
-        mEvdoSnr = in.readInt();
-        mLteSignalStrength = in.readInt();
-        mLteRsrp = in.readInt();
-        mLteRsrq = in.readInt();
-        mLteRssnr = in.readInt();
-        mLteCqi = in.readInt();
-        mTdScdmaRscp = in.readInt();
-        mWcdmaSignalStrength = in.readInt();
-        mWcdmaRscpAsu = in.readInt();
-        mWcdmaRscp = in.readInt();
+        mCdma = in.readParcelable(CellSignalStrengthCdma.class.getClassLoader());
+        mGsm = in.readParcelable(CellSignalStrengthGsm.class.getClassLoader());
+        mWcdma = in.readParcelable(CellSignalStrengthWcdma.class.getClassLoader());
+        mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader());
+        mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
         mLteRsrpBoost = in.readInt();
-        mIsGsm = in.readBoolean();
-        mUseOnlyRsrpForLteLevel = in.readBoolean();
-        mWcdmaDefaultSignalMeasurement = in.readString();
-        in.readIntArray(mLteRsrpThresholds);
-        in.readIntArray(mWcdmaRscpThresholds);
     }
 
     /**
      * {@link Parcelable#writeToParcel}
      */
     public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mGsmSignalStrength);
-        out.writeInt(mGsmBitErrorRate);
-        out.writeInt(mCdmaDbm);
-        out.writeInt(mCdmaEcio);
-        out.writeInt(mEvdoDbm);
-        out.writeInt(mEvdoEcio);
-        out.writeInt(mEvdoSnr);
-        out.writeInt(mLteSignalStrength);
-        out.writeInt(mLteRsrp);
-        out.writeInt(mLteRsrq);
-        out.writeInt(mLteRssnr);
-        out.writeInt(mLteCqi);
-        out.writeInt(mTdScdmaRscp);
-        out.writeInt(mWcdmaSignalStrength);
-        out.writeInt(mWcdmaRscpAsu);
-        out.writeInt(mWcdmaRscp);
+        out.writeParcelable(mCdma, flags);
+        out.writeParcelable(mGsm, flags);
+        out.writeParcelable(mWcdma, flags);
+        out.writeParcelable(mTdscdma, flags);
+        out.writeParcelable(mLte, flags);
+
         out.writeInt(mLteRsrpBoost);
-        out.writeBoolean(mIsGsm);
-        out.writeBoolean(mUseOnlyRsrpForLteLevel);
-        out.writeString(mWcdmaDefaultSignalMeasurement);
-        out.writeIntArray(mLteRsrpThresholds);
-        out.writeIntArray(mWcdmaRscpThresholds);
     }
 
     /**
@@ -392,153 +267,21 @@
     };
 
     /**
-     * Validate the individual signal strength fields as per the range
-     * specified in ril.h
-     * Set to invalid any field that is not in the valid range
-     * Cdma, evdo, lte rsrp & rsrq values are sign converted
-     * when received from ril interface
+     * Get the GSM RSSI in ASU.
      *
-     * @return
-     *      Valid values for all signalstrength fields
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void validateInput() {
-        if (DBG) log("Signal before validate=" + this);
-        // TS 27.007 8.5
-        mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
-        mWcdmaSignalStrength = (mWcdmaSignalStrength >= 0) ? mWcdmaSignalStrength : 99;
-        mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
-        // BER no change;
-
-        // WCDMA RSCP valid values are -120 through -24 as defined in TS 27.007 8.69
-        // but are reported in ASU which is 0 through 96, so we do the conversion here
-        mWcdmaRscpAsu =
-                ((mWcdmaRscpAsu - 120 >= MIN_WCDMA_RSCP) && (mWcdmaRscpAsu - 120 <= MAX_WCDMA_RSCP))
-                ? mWcdmaRscpAsu : 255;
-        mWcdmaRscp = ((mWcdmaRscp >= MIN_WCDMA_RSCP) && (mWcdmaRscp <= MAX_WCDMA_RSCP))
-                ? mWcdmaRscp : INVALID;
-
-        mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
-        mCdmaEcio = (mCdmaEcio >= 0) ? -mCdmaEcio : -160;
-
-        mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
-        mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -160;
-        mEvdoSnr = ((mEvdoSnr >= 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
-
-        // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
-        mLteRsrp = ((-mLteRsrp >= MIN_LTE_RSRP) && (-mLteRsrp <= MAX_LTE_RSRP)) ? -mLteRsrp
-                                : SignalStrength.INVALID;
-        mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
-        mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
-                : SignalStrength.INVALID;
-
-        mTdScdmaRscp = ((mTdScdmaRscp >= 0) && (mTdScdmaRscp <= 96))
-                ? (mTdScdmaRscp - 120) : SignalStrength.INVALID;
-        // Cqi no change
-        if (DBG) log("Signal after validate=" + this);
-    }
-
-    /**
-     * Fix {@link #mIsGsm} based on the signal strength data.
+     * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
      *
-     * @hide
-     */
-    public void fixType() {
-        mIsGsm = getCdmaRelatedSignalStrength() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-    }
-
-    /**
-     * @param true - Gsm, Lte phones
-     *        false - Cdma phones
-     *
-     * Used by voice phone to set the mIsGsm
-     *        flag
-     * @hide
-     */
-    public void setGsm(boolean gsmFlag) {
-        mIsGsm = gsmFlag;
-    }
-
-    /**
-     * @param useOnlyRsrpForLteLevel true if it uses only RSRP for the number of LTE signal bar,
-     * otherwise false.
-     *
-     * Used by phone to use only RSRP or not for the number of LTE signal bar.
-     * @hide
-     */
-    public void setUseOnlyRsrpForLteLevel(boolean useOnlyRsrpForLteLevel) {
-        mUseOnlyRsrpForLteLevel = useOnlyRsrpForLteLevel;
-    }
-
-    /**
-     * @param defaultMeasurement sets the type of WCDMA default signal measurement
-     *
-     * Used by phone to determine default measurement type for calculation WCDMA signal level.
-     * @hide
-     */
-    public void setWcdmaDefaultSignalMeasurement(String defaultMeasurement) {
-        mWcdmaDefaultSignalMeasurement = defaultMeasurement;
-    }
-
-    /**
-     * @param lteRsrpBoost - signal strength offset
-     *
-     * Used by phone to set the lte signal strength offset which will be
-     * reduced from rsrp threshold while calculating signal strength level
-     *
-     * @hide
-     */
-    public void setLteRsrpBoost(int lteRsrpBoost) {
-        mLteRsrpBoost = lteRsrpBoost;
-    }
-
-    /**
-     * Sets the threshold array for determining the display level of LTE signal bar.
-     *
-     * @param lteRsrpThresholds int array for determining the display level.
-     *
-     * @hide
-     */
-    public void setLteRsrpThresholds(int[] lteRsrpThresholds) {
-        if ((lteRsrpThresholds == null)
-                || (lteRsrpThresholds.length != LTE_RSRP_THRESHOLDS_NUM)) {
-            Log.wtf(LOG_TAG, "setLteRsrpThresholds - lteRsrpThresholds is invalid.");
-            return;
-        }
-        System.arraycopy(lteRsrpThresholds, 0, mLteRsrpThresholds, 0, LTE_RSRP_THRESHOLDS_NUM);
-    }
-
-    /**
-     * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS
-     * 27.007 8.5
+     * @return RSSI in ASU 0..31, 99, or UNAVAILABLE
      */
     public int getGsmSignalStrength() {
-        return this.mGsmSignalStrength;
+        return mGsm.getAsuLevel();
     }
 
     /**
      * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5
      */
     public int getGsmBitErrorRate() {
-        return this.mGsmBitErrorRate;
-    }
-
-    /**
-     * Sets the threshold array for determining the display level of WCDMA signal bar.
-     *
-     * @param wcdmaRscpThresholds int array for determining the display level.
-     *
-     * @hide
-     */
-    public void setWcdmaRscpThresholds(int[] wcdmaRscpThresholds) {
-        if ((wcdmaRscpThresholds == null)
-                || (wcdmaRscpThresholds.length != WCDMA_RSCP_THRESHOLDS_NUM)) {
-            Log.wtf(LOG_TAG, "setWcdmaRscpThresholds - wcdmaRscpThresholds is invalid.");
-            return;
-        }
-        System.arraycopy(wcdmaRscpThresholds, 0, mWcdmaRscpThresholds, 0,
-                WCDMA_RSCP_THRESHOLDS_NUM);
+        return mGsm.getBitErrorRate();
     }
 
     /**
@@ -547,14 +290,14 @@
      * @return the CDMA RSSI value or {@link #INVALID} if invalid
      */
     public int getCdmaDbm() {
-        return this.mCdmaDbm;
+        return mCdma.getCdmaDbm();
     }
 
     /**
      * Get the CDMA Ec/Io value in dB*10
      */
     public int getCdmaEcio() {
-        return this.mCdmaEcio;
+        return mCdma.getCdmaEcio();
     }
 
     /**
@@ -563,51 +306,51 @@
      * @return the EVDO RSSI value or {@link #INVALID} if invalid
      */
     public int getEvdoDbm() {
-        return this.mEvdoDbm;
+        return mCdma.getEvdoDbm();
     }
 
     /**
      * Get the EVDO Ec/Io value in dB*10
      */
     public int getEvdoEcio() {
-        return this.mEvdoEcio;
+        return mCdma.getEvdoEcio();
     }
 
     /**
      * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
      */
     public int getEvdoSnr() {
-        return this.mEvdoSnr;
+        return mCdma.getEvdoSnr();
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public int getLteSignalStrength() {
-        return mLteSignalStrength;
+        return mLte.getRssi();
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public int getLteRsrp() {
-        return mLteRsrp;
+        return mLte.getRsrp();
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public int getLteRsrq() {
-        return mLteRsrq;
+        return mLte.getRsrq();
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public int getLteRssnr() {
-        return mLteRssnr;
+        return mLte.getRssnr();
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public int getLteCqi() {
-        return mLteCqi;
+        return mLte.getCqi();
     }
 
     /** @hide */
@@ -624,9 +367,12 @@
      *     while 4 represents a very strong signal strength.
      */
     public int getLevel() {
-        int level = mIsGsm ? getGsmRelatedSignalStrength() : getCdmaRelatedSignalStrength();
-        if (DBG) log("getLevel=" + level);
-        return level;
+        int level = getPrimary().getLevel();
+        if (level < SIGNAL_STRENGTH_NONE_OR_UNKNOWN || level > SIGNAL_STRENGTH_GREAT) {
+            log("Invalid Level " + level + ", this=" + this);
+            return SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+        }
+        return getPrimary().getLevel();
     }
 
     /**
@@ -636,33 +382,7 @@
      */
     @UnsupportedAppUsage
     public int getAsuLevel() {
-        int asuLevel = 0;
-        if (mIsGsm) {
-            if (mLteRsrp != SignalStrength.INVALID) {
-                asuLevel = getLteAsuLevel();
-            } else if (mTdScdmaRscp != SignalStrength.INVALID) {
-                asuLevel = getTdScdmaAsuLevel();
-            } else if (mWcdmaRscp != SignalStrength.INVALID) {
-                asuLevel = getWcdmaAsuLevel();
-            } else {
-                asuLevel = getGsmAsuLevel();
-            }
-        } else {
-            int cdmaAsuLevel = getCdmaAsuLevel();
-            int evdoAsuLevel = getEvdoAsuLevel();
-            if (evdoAsuLevel == 0) {
-                /* We don't know evdo use, cdma */
-                asuLevel = cdmaAsuLevel;
-            } else if (cdmaAsuLevel == 0) {
-                /* We don't know cdma use, evdo */
-                asuLevel = evdoAsuLevel;
-            } else {
-                /* We know both, use the lowest level */
-                asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel;
-            }
-        }
-        if (DBG) log("getAsuLevel=" + asuLevel);
-        return asuLevel;
+        return getPrimary().getAsuLevel();
     }
 
     /**
@@ -672,30 +392,7 @@
      */
     @UnsupportedAppUsage
     public int getDbm() {
-        int dBm = INVALID;
-
-        if(isGsm()) {
-            dBm = getLteDbm();
-            if (dBm == INVALID) {
-                if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                    if (getWcdmaDbm() == INVALID) {
-                        dBm = getGsmDbm();
-                    } else {
-                        dBm = getWcdmaDbm();
-                    }
-                } else {
-                    dBm = getTdScdmaDbm();
-                }
-            }
-        } else {
-            int cdmaDbm = getCdmaDbm();
-            int evdoDbm = getEvdoDbm();
-
-            return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm
-                    : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm));
-        }
-        if (DBG) log("getDbm=" + dBm);
-        return dBm;
+        return getPrimary().getDbm();
     }
 
     /**
@@ -705,17 +402,7 @@
      */
     @UnsupportedAppUsage
     public int getGsmDbm() {
-        int dBm;
-
-        int gsmSignalStrength = getGsmSignalStrength();
-        int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
-        if (asu != -1) {
-            dBm = -113 + (2 * asu);
-        } else {
-            dBm = -1;
-        }
-        if (DBG) log("getGsmDbm=" + dBm);
-        return dBm;
+        return mGsm.getDbm();
     }
 
     /**
@@ -725,20 +412,7 @@
      */
     @UnsupportedAppUsage
     public int getGsmLevel() {
-        int level;
-
-        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
-        // asu = 0 (-113dB or less) is very weak
-        // signal, its better to show 0 bars to the user in such cases.
-        // asu = 99 is a special case, where the signal strength is unknown.
-        int asu = getGsmSignalStrength();
-        if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-        else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
-        else if (asu >= 8)  level = SIGNAL_STRENGTH_GOOD;
-        else if (asu >= 5)  level = SIGNAL_STRENGTH_MODERATE;
-        else level = SIGNAL_STRENGTH_POOR;
-        if (DBG) log("getGsmLevel=" + level);
-        return level;
+        return mGsm.getLevel();
     }
 
     /**
@@ -748,13 +422,7 @@
      */
     @UnsupportedAppUsage
     public int getGsmAsuLevel() {
-        // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
-        // asu = 0 (-113dB or less) is very weak
-        // signal, its better to show 0 bars to the user in such cases.
-        // asu = 99 is a special case, where the signal strength is unknown.
-        int level = getGsmSignalStrength();
-        if (DBG) log("getGsmAsuLevel=" + level);
-        return level;
+        return mGsm.getAsuLevel();
     }
 
     /**
@@ -764,27 +432,7 @@
      */
     @UnsupportedAppUsage
     public int getCdmaLevel() {
-        final int cdmaDbm = getCdmaDbm();
-        final int cdmaEcio = getCdmaEcio();
-        int levelDbm;
-        int levelEcio;
-
-        if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
-        else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
-        else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
-        else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
-        else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
-        // Ec/Io are in dB*10
-        if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
-        else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
-        else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
-        else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
-        else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
-        int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
-        if (DBG) log("getCdmaLevel=" + level);
-        return level;
+        return mCdma.getLevel();
     }
 
     /**
@@ -794,29 +442,7 @@
      */
     @UnsupportedAppUsage
     public int getCdmaAsuLevel() {
-        final int cdmaDbm = getCdmaDbm();
-        final int cdmaEcio = getCdmaEcio();
-        int cdmaAsuLevel;
-        int ecioAsuLevel;
-
-        if (cdmaDbm >= -75) cdmaAsuLevel = 16;
-        else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
-        else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
-        else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
-        else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
-        else cdmaAsuLevel = 99;
-
-        // Ec/Io are in dB*10
-        if (cdmaEcio >= -90) ecioAsuLevel = 16;
-        else if (cdmaEcio >= -100) ecioAsuLevel = 8;
-        else if (cdmaEcio >= -115) ecioAsuLevel = 4;
-        else if (cdmaEcio >= -130) ecioAsuLevel = 2;
-        else if (cdmaEcio >= -150) ecioAsuLevel = 1;
-        else ecioAsuLevel = 99;
-
-        int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
-        if (DBG) log("getCdmaAsuLevel=" + level);
-        return level;
+        return mCdma.getAsuLevel();
     }
 
     /**
@@ -826,26 +452,7 @@
      */
     @UnsupportedAppUsage
     public int getEvdoLevel() {
-        int evdoDbm = getEvdoDbm();
-        int evdoSnr = getEvdoSnr();
-        int levelEvdoDbm;
-        int levelEvdoSnr;
-
-        if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
-        else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
-        else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
-        else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
-        else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
-        if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
-        else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
-        else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
-        else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
-        else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
-        int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
-        if (DBG) log("getEvdoLevel=" + level);
-        return level;
+        return mCdma.getEvdoLevel();
     }
 
     /**
@@ -855,28 +462,7 @@
      */
     @UnsupportedAppUsage
     public int getEvdoAsuLevel() {
-        int evdoDbm = getEvdoDbm();
-        int evdoSnr = getEvdoSnr();
-        int levelEvdoDbm;
-        int levelEvdoSnr;
-
-        if (evdoDbm >= -65) levelEvdoDbm = 16;
-        else if (evdoDbm >= -75) levelEvdoDbm = 8;
-        else if (evdoDbm >= -85) levelEvdoDbm = 4;
-        else if (evdoDbm >= -95) levelEvdoDbm = 2;
-        else if (evdoDbm >= -105) levelEvdoDbm = 1;
-        else levelEvdoDbm = 99;
-
-        if (evdoSnr >= 7) levelEvdoSnr = 16;
-        else if (evdoSnr >= 6) levelEvdoSnr = 8;
-        else if (evdoSnr >= 5) levelEvdoSnr = 4;
-        else if (evdoSnr >= 3) levelEvdoSnr = 2;
-        else if (evdoSnr >= 1) levelEvdoSnr = 1;
-        else levelEvdoSnr = 99;
-
-        int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
-        if (DBG) log("getEvdoAsuLevel=" + level);
-        return level;
+        return mCdma.getEvdoAsuLevel();
     }
 
     /**
@@ -886,7 +472,7 @@
      */
     @UnsupportedAppUsage
     public int getLteDbm() {
-        return mLteRsrp;
+        return mLte.getRsrp();
     }
 
     /**
@@ -896,83 +482,7 @@
      */
     @UnsupportedAppUsage
     public int getLteLevel() {
-        /*
-         * TS 36.214 Physical Layer Section 5.1.3
-         * TS 36.331 RRC
-         *
-         * RSSI = received signal + noise
-         * RSRP = reference signal dBm
-         * RSRQ = quality of signal dB = Number of Resource blocks*RSRP/RSSI
-         * SNR = gain = signal/noise ratio = -10log P1/P2 dB
-         */
-        int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
-
-        if (mLteRsrp > MAX_LTE_RSRP || mLteRsrp < MIN_LTE_RSRP) {
-            if (mLteRsrp != INVALID) {
-                Log.wtf(LOG_TAG, "getLteLevel - invalid lte rsrp: mLteRsrp=" + mLteRsrp);
-            }
-        } else if (mLteRsrp >= (mLteRsrpThresholds[3] - mLteRsrpBoost)) {
-            rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
-        } else if (mLteRsrp >= (mLteRsrpThresholds[2] - mLteRsrpBoost)) {
-            rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
-        } else if (mLteRsrp >= (mLteRsrpThresholds[1] - mLteRsrpBoost)) {
-            rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
-        } else if (mLteRsrp >= (mLteRsrpThresholds[0] - mLteRsrpBoost)) {
-            rsrpIconLevel = SIGNAL_STRENGTH_POOR;
-        } else {
-            rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-        }
-
-        if (useOnlyRsrpForLteLevel()) {
-            log("getLTELevel - rsrp = " + rsrpIconLevel);
-            if (rsrpIconLevel != -1) {
-                return rsrpIconLevel;
-            }
-        }
-
-        /*
-         * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
-         * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
-         * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
-         * Icon Only
-         */
-        if (mLteRssnr > 300) snrIconLevel = -1;
-        else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
-        else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
-        else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
-        else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
-        else if (mLteRssnr >= -200)
-            snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
-        if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
-                + rsrpIconLevel + " snrIconLevel:" + snrIconLevel
-                + " lteRsrpBoost:" + mLteRsrpBoost);
-
-        /* Choose a measurement type to use for notification */
-        if (snrIconLevel != -1 && rsrpIconLevel != -1) {
-            /*
-             * The number of bars displayed shall be the smaller of the bars
-             * associated with LTE RSRP and the bars associated with the LTE
-             * RS_SNR
-             */
-            return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
-        }
-
-        if (snrIconLevel != -1) return snrIconLevel;
-
-        if (rsrpIconLevel != -1) return rsrpIconLevel;
-
-        /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
-        if (mLteSignalStrength > 31) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-        else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
-        else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
-        else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
-        else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
-
-        if (DBG) log("getLteLevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
-                + rssiIconLevel);
-        return rssiIconLevel;
-
+        return mLte.getLevel();
     }
 
     /**
@@ -983,41 +493,14 @@
      */
     @UnsupportedAppUsage
     public int getLteAsuLevel() {
-        int lteAsuLevel = 99;
-        int lteDbm = getLteDbm();
-        /*
-         * 3GPP 27.007 (Ver 10.3.0) Sec 8.69
-         * 0   -140 dBm or less
-         * 1   -139 dBm
-         * 2...96  -138... -44 dBm
-         * 97  -43 dBm or greater
-         * 255 not known or not detectable
-         */
-        /*
-         * validateInput will always give a valid range between -140 t0 -44 as
-         * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255
-         * and not 97 or 0
-         */
-        if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255;
-        else lteAsuLevel = lteDbm + 140;
-        if (DBG) log("Lte Asu level: "+lteAsuLevel);
-        return lteAsuLevel;
+        return mLte.getAsuLevel();
     }
 
     /**
      * @return true if this is for GSM
      */
     public boolean isGsm() {
-        return this.mIsGsm;
-    }
-
-    /**
-     * @return true if it uses only RSRP for the number of LTE signal bar, otherwise false.
-     *
-     * @hide
-     */
-    public boolean useOnlyRsrpForLteLevel() {
-        return this.mUseOnlyRsrpForLteLevel;
+        return !(getPrimary() instanceof CellSignalStrengthCdma);
     }
 
     /**
@@ -1027,7 +510,7 @@
      */
     @UnsupportedAppUsage
     public int getTdScdmaDbm() {
-        return this.mTdScdmaRscp;
+        return mTdscdma.getRscp();
     }
 
     /**
@@ -1040,19 +523,7 @@
      */
     @UnsupportedAppUsage
     public int getTdScdmaLevel() {
-        final int tdScdmaDbm = getTdScdmaDbm();
-        int level;
-
-        if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID))
-                level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-        else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT;
-        else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD;
-        else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE;
-        else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR;
-        else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
-        if (DBG) log("getTdScdmaLevel = " + level);
-        return level;
+        return mTdscdma.getLevel();
      }
 
     /**
@@ -1062,13 +533,7 @@
      */
     @UnsupportedAppUsage
     public int getTdScdmaAsuLevel() {
-        final int tdScdmaDbm = getTdScdmaDbm();
-        int tdScdmaAsuLevel;
-
-        if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255;
-        else tdScdmaAsuLevel = tdScdmaDbm + 120;
-        if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel);
-        return tdScdmaAsuLevel;
+        return mTdscdma.getAsuLevel();
     }
 
     /**
@@ -1077,7 +542,7 @@
      * @hide
      */
     public int getWcdmaRscp() {
-        return mWcdmaRscp;
+        return mWcdma.getRscp();
     }
 
     /**
@@ -1094,14 +559,7 @@
          * 96     -24 dBm or greater
          * 255    not known or not detectable
          */
-        final int wcdmaDbm = getWcdmaDbm();
-        int wcdmaAsuLevel = 255;
-        // validateInput will always give a valid range between -120 to -24 as per ril.h. so RSCP
-        // outside range is already set to INVALID
-        if (wcdmaDbm == SignalStrength.INVALID) wcdmaAsuLevel =  255;
-        else wcdmaAsuLevel = wcdmaDbm + 120;
-        if (DBG) log("Wcdma Asu level: " + wcdmaAsuLevel);
-        return wcdmaAsuLevel;
+        return mWcdma.getAsuLevel();
     }
 
     /**
@@ -1110,7 +568,7 @@
      * @hide
      */
     public int getWcdmaDbm() {
-        return mWcdmaRscp;
+        return mWcdma.getDbm();
     }
 
     /**
@@ -1119,55 +577,7 @@
      * @hide
      */
     public int getWcdmaLevel() {
-        int level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
-        if (mWcdmaDefaultSignalMeasurement == null) {
-            Log.wtf(LOG_TAG, "getWcdmaLevel - WCDMA default signal measurement is invalid.");
-            return level;
-        }
-
-        switch (mWcdmaDefaultSignalMeasurement) {
-            case MEASUMENT_TYPE_RSCP:
-                // RSCP valid values are (-120 through -24) as defined in TS 27.007 8.69
-                if (mWcdmaRscp < MIN_WCDMA_RSCP || mWcdmaRscp > MAX_WCDMA_RSCP) {
-                    if (mWcdmaRscp != INVALID) {
-                        Log.wtf(LOG_TAG, "getWcdmaLevel - invalid WCDMA RSCP: mWcdmaRscp="
-                                + mWcdmaRscp);
-                    }
-                } else if (mWcdmaRscp >= mWcdmaRscpThresholds[3]) {
-                    level = SIGNAL_STRENGTH_GREAT;
-                } else if (mWcdmaRscp >= mWcdmaRscpThresholds[2]) {
-                    level = SIGNAL_STRENGTH_GOOD;
-                } else if (mWcdmaRscp >= mWcdmaRscpThresholds[1]) {
-                    level = SIGNAL_STRENGTH_MODERATE;
-                } else if (mWcdmaRscp >= mWcdmaRscpThresholds[0]) {
-                    level = SIGNAL_STRENGTH_POOR;
-                }
-                if (DBG) log("getWcdmaLevel=" + level + " WcdmaRscp=" + mWcdmaRscp);
-                break;
-
-            default:
-                // RSSI valid values are (0..31) as defined in TS 27.007 8.5
-                if (mWcdmaSignalStrength < 0 || mWcdmaSignalStrength > 31) {
-                    if (mWcdmaSignalStrength != 99) {
-                        Log.wtf(LOG_TAG, "getWcdmaLevel - invalid WCDMA RSSI: mWcdmaSignalStrength="
-                                + mWcdmaSignalStrength);
-                    }
-                } else if (mWcdmaSignalStrength >= 18) {
-                    level = SIGNAL_STRENGTH_GREAT;
-                } else if (mWcdmaSignalStrength >= 13) {
-                    level = SIGNAL_STRENGTH_GOOD;
-                } else if (mWcdmaSignalStrength >= 8) {
-                    level = SIGNAL_STRENGTH_MODERATE;
-                } else if (mWcdmaSignalStrength >= 3) {
-                    level = SIGNAL_STRENGTH_POOR;
-                }
-                if (DBG) log("getWcdmaLevel=" + level + " WcdmaSignalStrength=" +
-                        mWcdmaSignalStrength);
-                break;
-
-        }
-        return level;
+        return mWcdma.getLevel();
     }
 
    /**
@@ -1175,18 +585,7 @@
      */
     @Override
     public int hashCode() {
-        int primeNum = 31;
-        return ((mGsmSignalStrength * primeNum)
-                + (mGsmBitErrorRate * primeNum)
-                + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum)
-                + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
-                + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
-                + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
-                + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum)
-                + (mWcdmaSignalStrength * primeNum) + (mWcdmaRscpAsu * primeNum)
-                + (mWcdmaRscp * primeNum) + (mIsGsm ? 1 : 0) + (mUseOnlyRsrpForLteLevel ? 1 : 0)
-                + (Objects.hashCode(mWcdmaDefaultSignalMeasurement))
-                + (Arrays.hashCode(mLteRsrpThresholds)) + (Arrays.hashCode(mWcdmaRscpThresholds)));
+        return Objects.hash(mCdma, mGsm, mWcdma, mTdscdma, mLte, mLteRsrpBoost);
     }
 
     /**
@@ -1194,40 +593,16 @@
      */
     @Override
     public boolean equals (Object o) {
-        SignalStrength s;
+        if (!(o instanceof SignalStrength)) return false;
 
-        try {
-            s = (SignalStrength) o;
-        } catch (ClassCastException ex) {
-            return false;
-        }
+        SignalStrength s = (SignalStrength) o;
 
-        if (o == null) {
-            return false;
-        }
-
-        return (mGsmSignalStrength == s.mGsmSignalStrength
-                && mGsmBitErrorRate == s.mGsmBitErrorRate
-                && mCdmaDbm == s.mCdmaDbm
-                && mCdmaEcio == s.mCdmaEcio
-                && mEvdoDbm == s.mEvdoDbm
-                && mEvdoEcio == s.mEvdoEcio
-                && mEvdoSnr == s.mEvdoSnr
-                && mLteSignalStrength == s.mLteSignalStrength
-                && mLteRsrp == s.mLteRsrp
-                && mLteRsrq == s.mLteRsrq
-                && mLteRssnr == s.mLteRssnr
-                && mLteCqi == s.mLteCqi
-                && mLteRsrpBoost == s.mLteRsrpBoost
-                && mTdScdmaRscp == s.mTdScdmaRscp
-                && mWcdmaSignalStrength == s.mWcdmaSignalStrength
-                && mWcdmaRscpAsu == s.mWcdmaRscpAsu
-                && mWcdmaRscp == s.mWcdmaRscp
-                && mIsGsm == s.mIsGsm
-                && mUseOnlyRsrpForLteLevel == s.mUseOnlyRsrpForLteLevel
-                && Objects.equals(mWcdmaDefaultSignalMeasurement, s.mWcdmaDefaultSignalMeasurement)
-                && Arrays.equals(mLteRsrpThresholds, s.mLteRsrpThresholds)
-                && Arrays.equals(mWcdmaRscpThresholds, s.mWcdmaRscpThresholds));
+        return mCdma.equals(s.mCdma)
+            && mGsm.equals(s.mGsm)
+            && mWcdma.equals(s.mWcdma)
+            && mTdscdma.equals(s.mTdscdma)
+            && mLte.equals(s.mLte)
+            && mLteRsrpBoost == s.mLteRsrpBoost;
     }
 
     /**
@@ -1235,63 +610,16 @@
      */
     @Override
     public String toString() {
-        return ("SignalStrength:"
-                + " " + mGsmSignalStrength
-                + " " + mGsmBitErrorRate
-                + " " + mCdmaDbm
-                + " " + mCdmaEcio
-                + " " + mEvdoDbm
-                + " " + mEvdoEcio
-                + " " + mEvdoSnr
-                + " " + mLteSignalStrength
-                + " " + mLteRsrp
-                + " " + mLteRsrq
-                + " " + mLteRssnr
-                + " " + mLteCqi
-                + " " + mLteRsrpBoost
-                + " " + mTdScdmaRscp
-                + " " + mWcdmaSignalStrength
-                + " " + mWcdmaRscpAsu
-                + " " + mWcdmaRscp
-                + " " + (mIsGsm ? "gsm|lte" : "cdma")
-                + " " + (mUseOnlyRsrpForLteLevel ? "use_only_rsrp_for_lte_level" :
-                         "use_rsrp_and_rssnr_for_lte_level")
-                + " " + mWcdmaDefaultSignalMeasurement
-                + " " + (Arrays.toString(mLteRsrpThresholds))
-                + " " + (Arrays.toString(mWcdmaRscpThresholds)));
-    }
-
-    /** Returns the signal strength related to GSM. */
-    private int getGsmRelatedSignalStrength() {
-        int level = getLteLevel();
-        if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-            level = getTdScdmaLevel();
-            if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                level = getWcdmaLevel();
-                if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-                    level = getGsmLevel();
-                }
-            }
-        }
-        return level;
-    }
-
-    /** Returns the signal strength related to CDMA. */
-    private int getCdmaRelatedSignalStrength() {
-        int level;
-        int cdmaLevel = getCdmaLevel();
-        int evdoLevel = getEvdoLevel();
-        if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-            /* We don't know evdo, use cdma */
-            level = cdmaLevel;
-        } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
-            /* We don't know cdma, use evdo */
-            level = evdoLevel;
-        } else {
-            /* We know both, use the lowest level */
-            level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
-        }
-        return level;
+        return new StringBuilder().append("SignalStrength:{")
+            .append("mCdma=").append(mCdma)
+            .append(",mGsm=").append(mGsm)
+            .append(",mWcdma=").append(mWcdma)
+            .append(",mTdscdma=").append(mTdscdma)
+            .append(",mLte=").append(mLte)
+            .append(",mLteRsrpBoost=").append(mLteRsrpBoost)
+            .append(",primary=").append(getPrimary().getClass().getSimpleName())
+            .append("}")
+            .toString();
     }
 
     /**
@@ -1302,34 +630,13 @@
      */
     @UnsupportedAppUsage
     private void setFromNotifierBundle(Bundle m) {
-        mGsmSignalStrength = m.getInt("GsmSignalStrength");
-        mGsmBitErrorRate = m.getInt("GsmBitErrorRate");
-        mCdmaDbm = m.getInt("CdmaDbm");
-        mCdmaEcio = m.getInt("CdmaEcio");
-        mEvdoDbm = m.getInt("EvdoDbm");
-        mEvdoEcio = m.getInt("EvdoEcio");
-        mEvdoSnr = m.getInt("EvdoSnr");
-        mLteSignalStrength = m.getInt("LteSignalStrength");
-        mLteRsrp = m.getInt("LteRsrp");
-        mLteRsrq = m.getInt("LteRsrq");
-        mLteRssnr = m.getInt("LteRssnr");
-        mLteCqi = m.getInt("LteCqi");
+        mCdma = m.getParcelable("Cdma");
+        mGsm = m.getParcelable("Gsm");
+        mWcdma = m.getParcelable("Wcdma");
+        mTdscdma = m.getParcelable("Tdscdma");
+        mLte = m.getParcelable("Lte");
+
         mLteRsrpBoost = m.getInt("LteRsrpBoost");
-        mTdScdmaRscp = m.getInt("TdScdma");
-        mWcdmaSignalStrength = m.getInt("WcdmaSignalStrength");
-        mWcdmaRscpAsu = m.getInt("WcdmaRscpAsu");
-        mWcdmaRscp = m.getInt("WcdmaRscp");
-        mIsGsm = m.getBoolean("IsGsm");
-        mUseOnlyRsrpForLteLevel = m.getBoolean("UseOnlyRsrpForLteLevel");
-        mWcdmaDefaultSignalMeasurement = m.getString("WcdmaDefaultSignalMeasurement");
-        ArrayList<Integer> lteRsrpThresholds = m.getIntegerArrayList("lteRsrpThresholds");
-        for (int i = 0; i < lteRsrpThresholds.size(); i++) {
-            mLteRsrpThresholds[i] = lteRsrpThresholds.get(i);
-        }
-        ArrayList<Integer> wcdmaRscpThresholds = m.getIntegerArrayList("wcdmaRscpThresholds");
-        for (int i = 0; i < wcdmaRscpThresholds.size(); i++) {
-            mWcdmaRscpThresholds[i] = wcdmaRscpThresholds.get(i);
-        }
     }
 
     /**
@@ -1340,56 +647,13 @@
      */
     @UnsupportedAppUsage
     public void fillInNotifierBundle(Bundle m) {
-        m.putInt("GsmSignalStrength", mGsmSignalStrength);
-        m.putInt("GsmBitErrorRate", mGsmBitErrorRate);
-        m.putInt("CdmaDbm", mCdmaDbm);
-        m.putInt("CdmaEcio", mCdmaEcio);
-        m.putInt("EvdoDbm", mEvdoDbm);
-        m.putInt("EvdoEcio", mEvdoEcio);
-        m.putInt("EvdoSnr", mEvdoSnr);
-        m.putInt("LteSignalStrength", mLteSignalStrength);
-        m.putInt("LteRsrp", mLteRsrp);
-        m.putInt("LteRsrq", mLteRsrq);
-        m.putInt("LteRssnr", mLteRssnr);
-        m.putInt("LteCqi", mLteCqi);
+        m.putParcelable("Cdma", mCdma);
+        m.putParcelable("Gsm", mGsm);
+        m.putParcelable("Wcdma", mWcdma);
+        m.putParcelable("Tdscdma", mTdscdma);
+        m.putParcelable("Lte", mLte);
+
         m.putInt("LteRsrpBoost", mLteRsrpBoost);
-        m.putInt("TdScdma", mTdScdmaRscp);
-        m.putInt("WcdmaSignalStrength", mWcdmaSignalStrength);
-        m.putInt("WcdmaRscpAsu", mWcdmaRscpAsu);
-        m.putInt("WcdmaRscp", mWcdmaRscp);
-        m.putBoolean("IsGsm", mIsGsm);
-        m.putBoolean("UseOnlyRsrpForLteLevel", mUseOnlyRsrpForLteLevel);
-        m.putString("WcdmaDefaultSignalMeasurement", mWcdmaDefaultSignalMeasurement);
-        ArrayList<Integer> lteRsrpThresholds = new ArrayList<Integer>();
-        for (int value : mLteRsrpThresholds) {
-            lteRsrpThresholds.add(value);
-        }
-        m.putIntegerArrayList("lteRsrpThresholds", lteRsrpThresholds);
-        ArrayList<Integer> wcdmaRscpThresholds = new ArrayList<Integer>();
-        for (int value : mWcdmaRscpThresholds) {
-            wcdmaRscpThresholds.add(value);
-        }
-        m.putIntegerArrayList("wcdmaRscpThresholds", wcdmaRscpThresholds);
-    }
-
-    /**
-     * Gets the default threshold array for determining the display level of LTE signal bar.
-     *
-     * @return int array for determining the display level.
-     */
-    private int[] getDefaultLteRsrpThresholds() {
-        return CarrierConfigManager.getDefaultConfig().getIntArray(
-                CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY);
-    }
-
-    /**
-     * Gets the default threshold array for determining the display level of WCDMA signal bar.
-     *
-     * @return int array for determining the display level.
-     */
-    private int[] getDefaultWcdmaRscpThresholds() {
-        return CarrierConfigManager.getDefaultConfig().getIntArray(
-                CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY);
     }
 
     /**
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index ea408bf..1b37bad 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -365,7 +365,6 @@
      *
      * @see #sendTextMessage(String, String, String, PendingIntent, PendingIntent)
      */
-    @SystemApi
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(allOf = {
             android.Manifest.permission.MODIFY_PHONE_STATE,
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index bacfe61a..0a58fa0 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -80,6 +80,12 @@
     private CharSequence mCarrierName;
 
     /**
+     * The subscription carrier id.
+     * @see TelephonyManager#getSimCarrierId()
+     */
+    private int mCarrierId;
+
+    /**
      * The source of the name, NAME_SOURCE_UNDEFINED, NAME_SOURCE_DEFAULT_SOURCE,
      * NAME_SOURCE_SIM_SOURCE or NAME_SOURCE_USER_INPUT.
      */
@@ -132,10 +138,15 @@
     private UiccAccessRule[] mAccessRules;
 
     /**
-     * The ID of the SIM card. It is the ICCID of the active profile for a UICC card and the EID
-     * for an eUICC card.
+     * The string ID of the SIM card. It is the ICCID of the active profile for a UICC card and the
+     * EID for an eUICC card.
      */
-    private String mCardId;
+    private String mCardString;
+
+    /**
+     * The card ID of the SIM card. This maps uniquely to the card string.
+     */
+    private int mCardId;
 
     /**
      * Whether the subscription is opportunistic.
@@ -155,15 +166,23 @@
     private boolean mIsMetered;
 
     /**
+     * Whether group of the subscription is disabled.
+     * This is only useful if it's a grouped opportunistic subscription. In this case, if all
+     * primary (non-opportunistic) subscriptions in the group are deactivated (unplugged pSIM
+     * or deactivated eSIM profile), we should disable this opportunistic subscription.
+     */
+    private boolean mIsGroupDisabled = false;
+
+    /**
      * @hide
      */
     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
             Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
-            @Nullable UiccAccessRule[] accessRules, String cardId) {
+            @Nullable UiccAccessRule[] accessRules, String cardString) {
         this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
-                roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardId,
-                false, null, true);
+                roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString,
+                false, null, true, TelephonyManager.UNKNOWN_CARRIER_ID);
     }
 
     /**
@@ -172,8 +191,22 @@
     public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
             CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
             Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
-            @Nullable UiccAccessRule[] accessRules, String cardId, boolean isOpportunistic,
-            @Nullable String groupUUID, boolean isMetered) {
+            @Nullable UiccAccessRule[] accessRules, String cardString, boolean isOpportunistic,
+            @Nullable String groupUUID, boolean isMetered, int carrierId) {
+        this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
+                roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString, -1,
+                isOpportunistic, groupUUID, isMetered, false, carrierId);
+    }
+
+    /**
+     * @hide
+     */
+    public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
+            CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
+            Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
+            @Nullable UiccAccessRule[] accessRules, String cardString, int cardId,
+            boolean isOpportunistic, @Nullable String groupUUID, boolean isMetered,
+            boolean isGroupDisabled, int carrierid) {
         this.mId = id;
         this.mIccId = iccId;
         this.mSimSlotIndex = simSlotIndex;
@@ -189,10 +222,13 @@
         this.mCountryIso = countryIso;
         this.mIsEmbedded = isEmbedded;
         this.mAccessRules = accessRules;
+        this.mCardString = cardString;
         this.mCardId = cardId;
         this.mIsOpportunistic = isOpportunistic;
         this.mGroupUUID = groupUUID;
         this.mIsMetered = isMetered;
+        this.mIsGroupDisabled = isGroupDisabled;
+        this.mCarrierId = carrierid;
     }
 
 
@@ -218,6 +254,14 @@
     }
 
     /**
+     * @return the carrier id of this Subscription carrier.
+     * @see TelephonyManager#getSimCarrierId()
+     */
+    public int getCarrierId() {
+        return this.mCarrierId;
+    }
+
+    /**
      * @return the name displayed to the user that identifies this subscription
      */
     public CharSequence getDisplayName() {
@@ -487,13 +531,39 @@
     }
 
     /**
-     * @return the ID of the SIM card which contains the subscription.
+     * @return the card string of the SIM card which contains the subscription. The card string is
+     * the ICCID for UICCs or the EID for eUICCs.
      * @hide
      */
-    public String getCardId() {
+    public String getCardString() {
+        return this.mCardString;
+    }
+
+    /**
+     * @return the cardId of the SIM card which contains the subscription.
+     * @hide
+     */
+    @SystemApi
+    public int getCardId() {
         return this.mCardId;
     }
 
+    /**
+     * Set whether the subscription's group is disabled.
+     * @hide
+     */
+    public void setGroupDisabled(boolean isGroupDisabled) {
+        this.mIsGroupDisabled = isGroupDisabled;
+    }
+
+    /**
+     * Return whether the subscription's group is disabled.
+     * @hide
+     */
+    public boolean isGroupDisabled() {
+        return mIsGroupDisabled;
+    }
+
     public static final Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() {
         @Override
         public SubscriptionInfo createFromParcel(Parcel source) {
@@ -512,14 +582,18 @@
             Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source);
             boolean isEmbedded = source.readBoolean();
             UiccAccessRule[] accessRules = source.createTypedArray(UiccAccessRule.CREATOR);
-            String cardId = source.readString();
+            String cardString = source.readString();
+            int cardId = source.readInt();
             boolean isOpportunistic = source.readBoolean();
             String groupUUID = source.readString();
             boolean isMetered = source.readBoolean();
+            boolean isGroupDisabled = source.readBoolean();
+            int carrierid = source.readInt();
 
             return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
                     nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
-                    isEmbedded, accessRules, cardId, isOpportunistic, groupUUID, isMetered);
+                    isEmbedded, accessRules, cardString, cardId, isOpportunistic, groupUUID,
+                    isMetered, isGroupDisabled, carrierid);
         }
 
         @Override
@@ -545,10 +619,13 @@
         mIconBitmap.writeToParcel(dest, flags);
         dest.writeBoolean(mIsEmbedded);
         dest.writeTypedArray(mAccessRules, flags);
-        dest.writeString(mCardId);
+        dest.writeString(mCardString);
+        dest.writeInt(mCardId);
         dest.writeBoolean(mIsOpportunistic);
         dest.writeString(mGroupUUID);
         dest.writeBoolean(mIsMetered);
+        dest.writeBoolean(mIsGroupDisabled);
+        dest.writeInt(mCarrierId);
     }
 
     @Override
@@ -574,22 +651,25 @@
     @Override
     public String toString() {
         String iccIdToPrint = givePrintableIccid(mIccId);
-        String cardIdToPrint = givePrintableIccid(mCardId);
+        String cardStringToPrint = givePrintableIccid(mCardString);
         return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
-                + " displayName=" + mDisplayName + " carrierName=" + mCarrierName
-                + " nameSource=" + mNameSource + " iconTint=" + mIconTint + " mNumber=" + mNumber
+                + " carrierId=" + mCarrierId + " displayName=" + mDisplayName
+                + " carrierName=" + mCarrierName + " nameSource=" + mNameSource
+                + " iconTint=" + mIconTint + " mNumber=" + mNumber
                 + " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
                 + " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded
                 + " accessRules " + Arrays.toString(mAccessRules)
-                + " cardId=" + cardIdToPrint + " isOpportunistic " + mIsOpportunistic
-                + " mGroupUUID=" + mGroupUUID + " isMetered=" + mIsMetered + "}";
+                + " cardString=" + cardStringToPrint + " cardId=" + mCardId
+                + " isOpportunistic " + mIsOpportunistic + " mGroupUUID=" + mGroupUUID
+                + " isMetered=" + mIsMetered + " mIsGroupDisabled=" + mIsGroupDisabled + "}";
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded,
                 mIsOpportunistic, mGroupUUID, mIsMetered, mIccId, mNumber, mMcc, mMnc,
-                mCountryIso, mCardId, mDisplayName, mCarrierName, mAccessRules);
+                mCountryIso, mCardString, mCardId, mDisplayName, mCarrierName, mAccessRules,
+                mIsGroupDisabled, mCarrierId);
     }
 
     @Override
@@ -611,16 +691,19 @@
                 && mDataRoaming == toCompare.mDataRoaming
                 && mIsEmbedded == toCompare.mIsEmbedded
                 && mIsOpportunistic == toCompare.mIsOpportunistic
-                && Objects.equals(mGroupUUID, toCompare.mGroupUUID)
+                && mIsGroupDisabled == toCompare.mIsGroupDisabled
+                && mCarrierId == toCompare.mCarrierId
                 && mIsMetered == toCompare.mIsMetered
+                && Objects.equals(mGroupUUID, toCompare.mGroupUUID)
                 && Objects.equals(mIccId, toCompare.mIccId)
                 && Objects.equals(mNumber, toCompare.mNumber)
                 && Objects.equals(mMcc, toCompare.mMcc)
                 && Objects.equals(mMnc, toCompare.mMnc)
                 && Objects.equals(mCountryIso, toCompare.mCountryIso)
+                && Objects.equals(mCardString, toCompare.mCardString)
                 && Objects.equals(mCardId, toCompare.mCardId)
                 && TextUtils.equals(mDisplayName, toCompare.mDisplayName)
                 && TextUtils.equals(mCarrierName, toCompare.mCarrierName)
                 && Arrays.equals(mAccessRules, toCompare.mAccessRules);
     }
-}
\ No newline at end of file
+}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index ff20fd2..b3c4b82 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -19,6 +19,7 @@
 import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED;
 import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED;
 
+import android.Manifest;
 import android.annotation.CallbackExecutor;
 import android.annotation.DurationMillisLong;
 import android.annotation.NonNull;
@@ -52,6 +53,7 @@
 import android.os.ServiceManager;
 import android.telephony.euicc.EuiccManager;
 import android.telephony.ims.ImsMmTelManager;
+import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
@@ -67,6 +69,7 @@
 import java.util.Locale;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
 
 /**
  * SubscriptionManager is the application interface to SubscriptionController
@@ -379,6 +382,14 @@
     public static final int SIM_PROVISIONED = 0;
 
     /**
+     * TelephonyProvider column name for subscription carrier id.
+     * @see TelephonyManager#getSimCarrierId()
+     * <p>Type: INTEGER (int) </p>
+     * @hide
+     */
+    public static final String CARRIER_ID = "carrier_id";
+
+    /**
      * TelephonyProvider column name for the MCC associated with a SIM, stored as a string.
      * <P>Type: TEXT (String)</P>
      * @hide
@@ -635,7 +646,6 @@
      * the user is interested in.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    @SystemApi
     public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS
             = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
 
@@ -655,7 +665,6 @@
      * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @SystemApi
     public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS
             = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
 
@@ -2043,7 +2052,6 @@
      * @throws SecurityException if the caller doesn't meet the requirements
      *             outlined above.
      */
-    @SystemApi
     public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
         try {
             SubscriptionPlan[] subscriptionPlans =
@@ -2075,7 +2083,6 @@
      * @throws SecurityException if the caller doesn't meet the requirements
      *             outlined above.
      */
-    @SystemApi
     public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
         try {
             getNetworkPolicy().setSubscriptionPlans(subId,
@@ -2117,7 +2124,6 @@
      * @throws SecurityException if the caller doesn't meet the requirements
      *             outlined above.
      */
-    @SystemApi
     public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
             @DurationMillisLong long timeoutMillis) {
         try {
@@ -2153,7 +2159,6 @@
      * @throws SecurityException if the caller doesn't meet the requirements
      *             outlined above.
      */
-    @SystemApi
     public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
             @DurationMillisLong long timeoutMillis) {
         try {
@@ -2389,16 +2394,21 @@
      * together, some of them may be invisible to the users, etc.
      *
      * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
-     * permission or can manage all subscriptions in the list, according to their
-     * acess rules.
+     * permission or had carrier privilege permission on the subscriptions:
+     * {@link TelephonyManager#hasCarrierPrivileges()} or
+     * {@link #canManageSubscription(SubscriptionInfo)}
+     *
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      *
      * @param subIdList list of subId that will be in the same group
      * @return groupUUID a UUID assigned to the subscription group. It returns
      * null if fails.
      *
      */
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-    public String setSubscriptionGroup(int[] subIdList) {
+    public @Nullable String setSubscriptionGroup(@NonNull int[] subIdList) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         if (VDBG) {
             logd("[setSubscriptionGroup]+ subIdList:" + Arrays.toString(subIdList));
@@ -2418,6 +2428,80 @@
     }
 
     /**
+     * Remove a list of subscriptions from their subscription group.
+     * See {@link #setSubscriptionGroup(int[])} for more details.
+     *
+     * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+     * permission or had carrier privilege permission on the subscriptions:
+     * {@link TelephonyManager#hasCarrierPrivileges()} or
+     * {@link #canManageSubscription(SubscriptionInfo)}
+     *
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
+     *
+     * @param subIdList list of subId that need removing from their groups.
+     * @return whether the operation succeeds.
+     *
+     */
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean removeSubscriptionsFromGroup(@NonNull int[] subIdList) {
+        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        if (VDBG) {
+            logd("[removeSubscriptionsFromGroup]+ subIdList:" + Arrays.toString(subIdList));
+        }
+
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                return iSub.removeSubscriptionsFromGroup(subIdList, pkgForDebug);
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+
+        return false;
+    }
+
+    /**
+     * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
+     * See {@link #setSubscriptionGroup(int[])} for more details.
+     *
+     * Caller will either have {@link android.Manifest.permission#READ_PHONE_STATE}
+     * permission or had carrier privilege permission on the subscription.
+     * {@link TelephonyManager#hasCarrierPrivileges()}
+     *
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
+     *
+     * @param subId of which list of subInfo from the same group will be returned.
+     * @return list of subscriptionInfo that belong to the same group, including the given
+     * subscription itself. It will return null if the subscription doesn't exist or it
+     * doesn't belong to any group.
+     *
+     */
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public @Nullable List<SubscriptionInfo> getSubscriptionsInGroup(int subId) {
+        String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+        if (VDBG) {
+            logd("[getSubscriptionsInGroup]+ subId:" + subId);
+        }
+
+        List<SubscriptionInfo> result = null;
+        try {
+            ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+            if (iSub != null) {
+                result = iSub.getSubscriptionsInGroup(subId, pkgForDebug);
+            }
+        } catch (RemoteException ex) {
+            // ignore it
+        }
+
+        return result;
+    }
+
+    /**
      * Set metered by simInfo index
      *
      * @param isMetered whether it’s a metered subscription.
@@ -2432,6 +2516,42 @@
                 (iSub)-> iSub.setMetered(isMetered, subId));
     }
 
+    /**
+     * Whether system UI should hide a subscription. If it's a bundled opportunistic
+     * subscription, it shouldn't show up in anywhere in Settings app, dialer app,
+     * or status bar.
+     *
+     * @param info the subscriptionInfo to check against.
+     * @return true if this subscription should be hidden.
+     *
+     * @hide
+     */
+    public static boolean shouldHideSubscription(SubscriptionInfo info) {
+        return (info != null && !TextUtils.isEmpty(info.getGroupUuid()) && info.isOpportunistic());
+    }
+
+    /**
+     * Return a list of subscriptions that are available and visible to the user.
+     * Used by Settings app to show a list of subscriptions for user to pick.
+     *
+     * <p>
+     * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
+     * for getSelectableSubscriptionInfoList to be invoked.
+     * @return list of user selectable subscriptions.
+     *
+     * @hide
+     */
+    public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() {
+        List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList();
+        if (availableList == null) {
+            return null;
+        } else {
+            return getAvailableSubscriptionInfoList().stream()
+                    .filter(subInfo -> !shouldHideSubscription(subInfo))
+                    .collect(Collectors.toList());
+        }
+    }
+
     private interface CallISubMethodHelper {
         int callMethod(ISub iSub) throws RemoteException;
     }
diff --git a/telephony/java/android/telephony/SubscriptionPlan.java b/telephony/java/android/telephony/SubscriptionPlan.java
index e8bbe42..d67169c 100644
--- a/telephony/java/android/telephony/SubscriptionPlan.java
+++ b/telephony/java/android/telephony/SubscriptionPlan.java
@@ -45,7 +45,6 @@
  * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List)
  * @see SubscriptionManager#getSubscriptionPlans(int)
  */
-@SystemApi
 public final class SubscriptionPlan implements Parcelable {
     /** {@hide} */
     @IntDef(prefix = "LIMIT_BEHAVIOR_", value = {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a976fe6..26d2459 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -225,6 +225,13 @@
     @SystemApi
     public static final int SRVCC_STATE_HANDOVER_CANCELED  = 3;
 
+    /**
+     * An invalid card identifier.
+     * @hide
+     */
+    @SystemApi
+    public static final int INVALID_CARD_ID = -1;
+
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(prefix = {"SRVCC_STATE_"},
@@ -618,8 +625,6 @@
      * The {@link #EXTRA_RINGING_CALL_STATE} extra indicates the ringing call state.
      * The {@link #EXTRA_FOREGROUND_CALL_STATE} extra indicates the foreground call state.
      * The {@link #EXTRA_BACKGROUND_CALL_STATE} extra indicates the background call state.
-     * The {@link #EXTRA_DISCONNECT_CAUSE} extra indicates the disconnect cause.
-     * The {@link #EXTRA_PRECISE_DISCONNECT_CAUSE} extra indicates the precise disconnect cause.
      *
      * <p class="note">
      * Requires the READ_PRECISE_PHONE_STATE permission.
@@ -627,12 +632,10 @@
      * @see #EXTRA_RINGING_CALL_STATE
      * @see #EXTRA_FOREGROUND_CALL_STATE
      * @see #EXTRA_BACKGROUND_CALL_STATE
-     * @see #EXTRA_DISCONNECT_CAUSE
-     * @see #EXTRA_PRECISE_DISCONNECT_CAUSE
      *
      * <p class="note">
      * Requires the READ_PRECISE_PHONE_STATE permission.
-     *
+     * @deprecated use {@link PhoneStateListener#LISTEN_PRECISE_CALL_STATE} instead
      * @hide
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -640,8 +643,28 @@
             "android.intent.action.PRECISE_CALL_STATE";
 
     /**
-     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
-     * for an integer containing the state of the current ringing call.
+     * Broadcast intent action indicating that call disconnect cause has changed.
+     *
+     * <p>
+     * The {@link #EXTRA_DISCONNECT_CAUSE} extra indicates the disconnect cause.
+     * The {@link #EXTRA_PRECISE_DISCONNECT_CAUSE} extra indicates the precise disconnect cause.
+     *
+     * <p class="note">
+     * Requires the READ_PRECISE_PHONE_STATE permission.
+     *
+     * @see #EXTRA_DISCONNECT_CAUSE
+     * @see #EXTRA_PRECISE_DISCONNECT_CAUSE
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_CALL_DISCONNECT_CAUSE_CHANGED =
+            "android.intent.action.CALL_DISCONNECT_CAUSE";
+
+    /**
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+     * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+     * containing the state of the current ringing call.
      *
      * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
      * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
@@ -663,8 +686,9 @@
     public static final String EXTRA_RINGING_CALL_STATE = "ringing_state";
 
     /**
-     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
-     * for an integer containing the state of the current foreground call.
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+     * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+     * containing the state of the current foreground call.
      *
      * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
      * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
@@ -686,8 +710,9 @@
     public static final String EXTRA_FOREGROUND_CALL_STATE = "foreground_state";
 
     /**
-     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
-     * for an integer containing the state of the current background call.
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+     * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+     * containing the state of the current background call.
      *
      * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
      * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
@@ -709,8 +734,9 @@
     public static final String EXTRA_BACKGROUND_CALL_STATE = "background_state";
 
     /**
-     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
-     * for an integer containing the disconnect cause.
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+     * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+     * containing the disconnect cause.
      *
      * @see DisconnectCause
      *
@@ -723,8 +749,9 @@
     public static final String EXTRA_DISCONNECT_CAUSE = "disconnect_cause";
 
     /**
-     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
-     * for an integer containing the disconnect cause provided by the RIL.
+     * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+     * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+     * containing the disconnect cause provided by the RIL.
      *
      * @see PreciseDisconnectCause
      *
@@ -1216,81 +1243,79 @@
             "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED";
 
     /**
-     * Broadcast Action: The subscription precise carrier identity has changed.
-     * Similar like {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}, this intent will be sent
-     * on the event of {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}. However, its possible
-     * that precise carrier identity changes while
-     * {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} remains the same e.g, the same
-     * subscription switches to different IMSI could potentially change its precise carrier id.
-     *
-     * The intent will have the following extra values:
-     * <ul>
-     *   <li>{@link #EXTRA_PRECISE_CARRIER_ID} The up-to-date precise carrier id of the
-     *   current subscription.
-     *   </li>
-     *   <li>{@link #EXTRA_PRECISE_CARRIER_NAME} The up-to-date carrier name of the current
-     *   subscription.
-     *   </li>
-     *   <li>{@link #EXTRA_SUBSCRIPTION_ID} The subscription id associated with the changed carrier
-     *   identity.
-     *   </li>
-     * </ul>
-     * <p class="note">This is a protected intent that can only be sent by the system.
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED =
-            "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED";
-
-    /**
      * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which indicates
-     * the updated carrier id {@link TelephonyManager#getSimCarrierId()} of
-     * the current subscription.
+     * the updated carrier id returned by {@link TelephonyManager#getSimCarrierId()}.
      * <p>Will be {@link TelephonyManager#UNKNOWN_CARRIER_ID} if the subscription is unavailable or
      * the carrier cannot be identified.
      */
     public static final String EXTRA_CARRIER_ID = "android.telephony.extra.CARRIER_ID";
 
     /**
-     * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which indicates
-     * the updated mno carrier id of the current subscription.
-     * <p>Will be {@link TelephonyManager#UNKNOWN_CARRIER_ID} if the subscription is unavailable or
-     * the carrier cannot be identified.
-     *
-     *@hide
-     */
-    public static final String EXTRA_MNO_CARRIER_ID = "android.telephony.extra.MNO_CARRIER_ID";
-
-    /**
      * An string extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which
      * indicates the updated carrier name of the current subscription.
-     * {@see TelephonyManager#getSimCarrierIdName()}
+     * @see TelephonyManager#getSimCarrierIdName()
      * <p>Carrier name is a user-facing name of the carrier id {@link #EXTRA_CARRIER_ID},
      * usually the brand name of the subsidiary (e.g. T-Mobile).
      */
     public static final String EXTRA_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME";
 
     /**
+     * Broadcast Action: The subscription precise carrier identity has changed.
+     * The precise carrier id can be used to further differentiate a carrier by different
+     * networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique
+     * carrier id returned by {@link #getSimCarrierId()} but could have multiple precise carrier id.
+     * e.g, {@link #getSimCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM,
+     * while {@link #getSimPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based
+     * on the current subscription IMSI. For carriers without any fine-grained ids, precise carrier
+     * id is same as carrier id.
+     *
+     * <p>Similar like {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}, this intent will be
+     * sent on the event of {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} while its also
+     * possible to be sent without {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} when
+     * precise carrier id changes with the same carrier id.
+     * e.g, the same subscription switches to different IMSI could potentially change its
+     * precise carrier id while carrier id remains the same.
+     * @see #getSimPreciseCarrierId()
+     * @see #getSimCarrierId()
+     *
+     * The intent will have the following extra values:
+     * <ul>
+     *   <li>{@link #EXTRA_PRECISE_CARRIER_ID} The up-to-date precise carrier id of the
+     *   current subscription.
+     *   </li>
+     *   <li>{@link #EXTRA_PRECISE_CARRIER_NAME} The up-to-date name of the precise carrier id.
+     *   </li>
+     *   <li>{@link #EXTRA_SUBSCRIPTION_ID} The subscription id associated with the changed carrier
+     *   identity.
+     *   </li>
+     * </ul>
+     * <p class="note">This is a protected intent that can only be sent by the system.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED =
+            "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED";
+
+    /**
      * An int extra used with {@link #ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED} which
-     * indicates the updated precise carrier id {@link TelephonyManager#getSimPreciseCarrierId()} of
-     * the current subscription. Note, its possible precise carrier id changes while
-     * {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} remains the same e.g, when
-     * subscription switch to different IMSI.
+     * indicates the updated precise carrier id returned by
+     * {@link TelephonyManager#getSimPreciseCarrierId()}. Note, its possible precise carrier id
+     * changes while {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} remains the same
+     * e.g, when subscription switch to different IMSIs.
      * <p>Will be {@link TelephonyManager#UNKNOWN_CARRIER_ID} if the subscription is unavailable or
      * the carrier cannot be identified.
-     * @hide
      */
     public static final String EXTRA_PRECISE_CARRIER_ID =
             "android.telephony.extra.PRECISE_CARRIER_ID";
 
     /**
      * An string extra used with {@link #ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED} which
-     * indicates the updated precise carrier name of the current subscription.
-     * {@see TelephonyManager#getSimPreciseCarrierIdName()}
-     * <p>it's a user-facing name of the precise carrier id {@link #EXTRA_PRECISE_CARRIER_ID},
-     * @hide
+     * indicates the updated precise carrier name returned by
+     * {@link TelephonyManager#getSimPreciseCarrierIdName()}.
+     * <p>it's a user-facing name of the precise carrier id {@link #EXTRA_PRECISE_CARRIER_ID}, e.g,
+     * Tracfone-AT&T.
      */
-    public static final String EXTRA_PRECISE_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME";
+    public static final String EXTRA_PRECISE_CARRIER_NAME =
+            "android.telephony.extra.PRECISE_CARRIER_NAME";
 
     /**
      * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} to indicate the
@@ -3094,6 +3119,57 @@
     }
 
     /**
+     * Get the card ID of the default eUICC card. If there is no eUICC, returns
+     * {@link #INVALID_CARD_ID}.
+     *
+     * <p>The card ID is a unique identifier associated with a UICC or eUICC card. Card IDs are
+     * unique to a device, and always refer to the same UICC or eUICC card unless the device goes
+     * through a factory reset.
+     *
+     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     *
+     * @return card ID of the default eUICC card.
+     * @hide
+     */
+    @SystemApi
+    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public int getCardIdForDefaultEuicc() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony == null) {
+                return INVALID_CARD_ID;
+            }
+            return telephony.getCardIdForDefaultEuicc(mSubId, mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            return INVALID_CARD_ID;
+        }
+    }
+
+    /**
+     * Gets information about currently inserted UICCs and eUICCs. See {@link UiccCardInfo} for more
+     * details on the kind of information available.
+     *
+     * @return UiccCardInfo an array of UiccCardInfo objects, representing information on the
+     * currently inserted UICCs and eUICCs.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public UiccCardInfo[] getUiccCardsInfo() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony == null) {
+                return null;
+            }
+            return telephony.getUiccCardsInfo();
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
      * Gets all the UICC slots. The objects in the array can be null if the slot info is not
      * available, which is possible between phone process starting and getting slot info from modem.
      *
@@ -4828,7 +4904,7 @@
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION)
     public void requestCellInfoUpdate(
-            @NonNull Executor executor, @NonNull CellInfoCallback callback) {
+            @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony == null) return;
@@ -5569,7 +5645,7 @@
         if (value == null) {
             value = "";
         }
-
+        value.replace(',', ' ');
         if (prop != null) {
             p = prop.split(",");
         }
@@ -5595,7 +5671,13 @@
             }
         }
 
-        if (propVal.length() > SystemProperties.PROP_VALUE_MAX) {
+        int propValLen = propVal.length();
+        try {
+            propValLen = propVal.getBytes("utf-8").length;
+        } catch (java.io.UnsupportedEncodingException e) {
+            Rlog.d(TAG, "setTelephonyProperty: utf-8 not supported");
+        }
+        if (propValLen > SystemProperties.PROP_VALUE_MAX) {
             Rlog.d(TAG, "setTelephonyProperty: property too long phoneId=" + phoneId +
                     " property=" + property + " value: " + value + " propVal=" + propVal);
             return;
@@ -6606,7 +6688,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.getCarrierPrivilegeStatus(mSubId) ==
+                return telephony.getCarrierPrivilegeStatus(subId) ==
                     CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
             }
         } catch (RemoteException ex) {
@@ -8492,7 +8574,7 @@
 
     /**
      * Returns carrier id name of the current subscription.
-     * <p>Carrier id name is a user-facing name of carrier id
+     * <p>Carrier id name is a user-facing name of carrier id returned by
      * {@link #getSimCarrierId()}, usually the brand name of the subsidiary
      * (e.g. T-Mobile). Each carrier could configure multiple {@link #getSimOperatorName() SPN} but
      * should have a single carrier name. Carrier name is not a canonical identity,
@@ -8502,7 +8584,7 @@
      * @return Carrier name of the current subscription. Return {@code null} if the subscription is
      * unavailable or the carrier cannot be identified.
      */
-    public CharSequence getSimCarrierIdName() {
+    public @Nullable CharSequence getSimCarrierIdName() {
         try {
             ITelephony service = getITelephony();
             if (service != null) {
@@ -8519,10 +8601,10 @@
      *
      * <p>The precise carrier id can be used to further differentiate a carrier by different
      * networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique
-     * carrier id {@link #getSimCarrierId()} but can have multiple precise carrier id. e.g,
-     * {@link #getSimCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while
-     * {@link #getSimPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the
-     * current subscription IMSI.
+     * carrier id returned by {@link #getSimCarrierId()} but could have multiple precise carrier id.
+     * e.g, {@link #getSimCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM,
+     * while {@link #getSimPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based
+     * on the current subscription IMSI.
      *
      * <p>For carriers without any fine-grained carrier ids, return {@link #getSimCarrierId()}
      * <p>Precise carrier ids are defined in the same way as carrier id
@@ -8532,8 +8614,6 @@
      * @return Returns fine-grained carrier id of the current subscription.
      * Return {@link #UNKNOWN_CARRIER_ID} if the subscription is unavailable or the carrier cannot
      * be identified.
-     *
-     * @hide
      */
     public int getSimPreciseCarrierId() {
         try {
@@ -8549,16 +8629,14 @@
 
     /**
      * Similar like {@link #getSimCarrierIdName()}, returns user-facing name of the
-     * precise carrier id {@link #getSimPreciseCarrierId()}
+     * precise carrier id returned by {@link #getSimPreciseCarrierId()}.
      *
      * <p>The returned name is unlocalized.
      *
      * @return user-facing name of the subscription precise carrier id. Return {@code null} if the
      * subscription is unavailable or the carrier cannot be identified.
-     *
-     * @hide
      */
-    public CharSequence getSimPreciseCarrierIdName() {
+    public @Nullable CharSequence getSimPreciseCarrierIdName() {
         try {
             ITelephony service = getITelephony();
             if (service != null) {
@@ -8571,6 +8649,62 @@
     }
 
     /**
+     * Returns carrier id based on sim MCCMNC (returned by {@link #getSimOperator()}) only.
+     * This is used for fallback when configurations/logic for exact carrier id
+     * {@link #getSimCarrierId()} are not found.
+     *
+     * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+     * can be updated out-of-band, its possible a MVNO (Mobile Virtual Network Operator) carrier
+     * was not fully recognized and assigned to its MNO (Mobile Network Operator) carrier id
+     * by default. After carrier id table update, a new carrier id was assigned. If apps don't
+     * take the update with the new id, it might be helpful to always fallback by using carrier
+     * id based on MCCMNC if there is no match.
+     *
+     * @return matching carrier id from sim MCCMNC. Return {@link #UNKNOWN_CARRIER_ID} if the
+     * subscription is unavailable or the carrier cannot be identified.
+     */
+    public int getCarrierIdFromSimMccMnc() {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.getCarrierIdFromMccMnc(getSlotIndex(), getSimOperator(), true);
+            }
+        } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
+        }
+        return UNKNOWN_CARRIER_ID;
+    }
+
+     /**
+      * Returns carrier id based on MCCMNC (returned by {@link #getSimOperator()}) only. This is
+      * used for fallback when configurations/logic for exact carrier id {@link #getSimCarrierId()}
+      * are not found.
+      *
+      * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+      * can be updated out-of-band, its possible a MVNO (Mobile Virtual Network Operator) carrier
+      * was not fully recognized and assigned to its MNO (Mobile Network Operator) carrier id
+      * by default. After carrier id table update, a new carrier id was assigned. If apps don't
+      * take the update with the new id, it might be helpful to always fallback by using carrier
+      * id based on MCCMNC if there is no match.
+      *
+      * @return matching carrier id from passing MCCMNC. Return {@link #UNKNOWN_CARRIER_ID} if the
+      * subscription is unavailable or the carrier cannot be identified.
+      * @hide
+      */
+     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+     public int getCarrierIdFromMccMnc(String mccmnc) {
+        try {
+            ITelephony service = getITelephony();
+            if (service != null) {
+                return service.getCarrierIdFromMccMnc(getSlotIndex(), mccmnc, false);
+            }
+        } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
+        }
+        return UNKNOWN_CARRIER_ID;
+    }
+
+    /**
      * Return a list of certs in hex string from loaded carrier privileges access rules.
      *
      * @return a list of certificate in hex string. return {@code null} if there is no certs
@@ -8594,48 +8728,6 @@
     }
 
     /**
-     * Returns MNO carrier id of the current subscription’s MCCMNC.
-     * <p>MNO carrier id can be solely identified by subscription mccmnc. This is mainly used
-     * for MNO fallback when exact carrier id {@link #getSimCarrierId()}
-     * configurations are not found.
-     *
-     * @return MNO carrier id of the current subscription. Return the value same as carrier id
-     * {@link #getSimCarrierId()}, if MNO carrier id cannot be identified.
-     * @hide
-     */
-    public int getSimMNOCarrierId() {
-        try {
-            ITelephony service = getITelephony();
-            if (service != null) {
-                return service.getSubscriptionMNOCarrierId(getSubId());
-            }
-        } catch (RemoteException ex) {
-            // This could happen if binder process crashes.
-        }
-        return UNKNOWN_CARRIER_ID;
-    }
-
-     /**
-      * Returns carrier id based on MCCMNC only. This is for fallback when exact carrier id
-      * {@link #getSimCarrierId()} configurations are not found
-      *
-      * @return matching carrier id from passing mccmnc.
-      * @hide
-      */
-     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-     public int getCarrierIdFromMccMnc(String mccmnc) {
-        try {
-            ITelephony service = getITelephony();
-            if (service != null) {
-                return service.getCarrierIdFromMccMnc(getSlotIndex(), mccmnc);
-            }
-        } catch (RemoteException ex) {
-            // This could happen if binder process crashes.
-        }
-        return UNKNOWN_CARRIER_ID;
-    }
-
-    /**
      * Return the application ID for the uicc application type like {@link #APPTYPE_CSIM}.
      * All uicc applications are uniquely identified by application ID, represented by the hex
      * string. e.g, A00000015141434C00. See ETSI 102.221 and 101.220
diff --git a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl b/telephony/java/android/telephony/UiccCardInfo.aidl
similarity index 76%
copy from telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
copy to telephony/java/android/telephony/UiccCardInfo.aidl
index 4c289ac..882c233 100644
--- a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
+++ b/telephony/java/android/telephony/UiccCardInfo.aidl
@@ -14,12 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.rcs;
+package android.telephony;
 
-interface IRcs {
-    // RcsManager APIs
-    void deleteThread(int threadId);
-
-    // RcsThread APIs
-    int getMessageCount(int rcsThreadId);
-}
\ No newline at end of file
+parcelable UiccCardInfo;
diff --git a/telephony/java/android/telephony/UiccCardInfo.java b/telephony/java/android/telephony/UiccCardInfo.java
new file mode 100644
index 0000000..45e4704
--- /dev/null
+++ b/telephony/java/android/telephony/UiccCardInfo.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * The UiccCardInfo represents information about a currently inserted UICC or embedded eUICC.
+ * @hide
+ */
+@SystemApi
+public class UiccCardInfo implements Parcelable {
+
+    private final boolean mIsEuicc;
+    private final int mCardId;
+    private final String mEid;
+    private final String mIccId;
+    private final int mSlotIndex;
+
+    public static final Creator<UiccCardInfo> CREATOR = new Creator<UiccCardInfo>() {
+        @Override
+        public UiccCardInfo createFromParcel(Parcel in) {
+            return new UiccCardInfo(in);
+        }
+
+        @Override
+        public UiccCardInfo[] newArray(int size) {
+            return new UiccCardInfo[size];
+        }
+    };
+
+    private UiccCardInfo(Parcel in) {
+        mIsEuicc = in.readByte() != 0;
+        mCardId = in.readInt();
+        mEid = in.readString();
+        mIccId = in.readString();
+        mSlotIndex = in.readInt();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeByte((byte) (mIsEuicc ? 1 : 0));
+        dest.writeInt(mCardId);
+        dest.writeString(mEid);
+        dest.writeString(mIccId);
+        dest.writeInt(mSlotIndex);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public UiccCardInfo(boolean isEuicc, int cardId, String eid, String iccId, int slotIndex) {
+        this.mIsEuicc = isEuicc;
+        this.mCardId = cardId;
+        this.mEid = eid;
+        this.mIccId = iccId;
+        this.mSlotIndex = slotIndex;
+    }
+
+    /**
+     * Return whether the UiccCardInfo is an eUICC.
+     * @return true if the UICC is an eUICC.
+     */
+    public boolean isEuicc() {
+        return mIsEuicc;
+    }
+
+    /**
+     * Get the card ID of the UICC. See {@link TelephonyManager#getCardIdForDefaultEuicc()} for more
+     * details on card ID.
+     */
+    public int getCardId() {
+        return mCardId;
+    }
+
+    /**
+     * Get the embedded ID (EID) of the eUICC. If the UiccCardInfo is not an eUICC
+     * (see {@link #isEuicc()}), returns null.
+     */
+    public String getEid() {
+        if (!mIsEuicc) {
+            return null;
+        }
+        return mEid;
+    }
+
+    /**
+     * Get the ICCID of the UICC.
+     */
+    public String getIccId() {
+        return mIccId;
+    }
+
+    /**
+     * Gets the slot index for the slot that the UICC is currently inserted in.
+     */
+    public int getSlotIndex() {
+        return mSlotIndex;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+
+        UiccCardInfo that = (UiccCardInfo) obj;
+        return ((mIsEuicc == that.mIsEuicc)
+                && (mCardId == that.mCardId)
+                && (Objects.equals(mEid, that.mEid))
+                && (Objects.equals(mIccId, that.mIccId))
+                && (mSlotIndex == that.mSlotIndex));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mIsEuicc, mCardId, mEid, mIccId, mSlotIndex);
+    }
+
+    @Override
+    public String toString() {
+        return "UiccCardInfo (mIsEuicc="
+                + mIsEuicc
+                + ", mCardId="
+                + mCardId
+                + ", mEid="
+                + mEid
+                + ", mIccId="
+                + mIccId
+                + ", mSlotIndex="
+                + mSlotIndex
+                + ")";
+    }
+}
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index b5a8758..200b540 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -969,7 +969,7 @@
      */
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("[ApnSettingV5] ")
+        sb.append("[ApnSettingV6] ")
                 .append(mEntryName)
                 .append(", ").append(mId)
                 .append(", ").append(mOperatorNumeric)
@@ -996,6 +996,7 @@
         sb.append(", ").append(mPermanentFailed);
         sb.append(", ").append(mNetworkTypeBitmask);
         sb.append(", ").append(mApnSetId);
+        sb.append(", ").append(mCarrierId);
         return sb.toString();
     }
 
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index 1db5850..74d1e83 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -16,7 +16,6 @@
 
 package android.telephony.data;
 
-import android.annotation.CallSuper;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -60,7 +59,6 @@
     private static final String TAG = DataService.class.getSimpleName();
 
     public static final String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService";
-    public static final String DATA_SERVICE_EXTRA_SLOT_ID = "android.telephony.data.extra.SLOT_ID";
 
     /** {@hide} */
     @IntDef(prefix = "REQUEST_REASON_", value = {
@@ -116,7 +114,7 @@
      * must extend this class to support data connection. Note that each instance of data service
      * provider is associated with one physical SIM slot.
      */
-    public class DataServiceProvider {
+    public abstract class DataServiceProvider implements AutoCloseable {
 
         private final int mSlotId;
 
@@ -250,12 +248,12 @@
         }
 
         /**
-         * Called when the instance of data service is destroyed (e.g. got unbind or binder died).
+         * Called when the instance of data service is destroyed (e.g. got unbind or binder died)
+         * or when the data service provider is removed. The extended class should implement this
+         * method to perform cleanup works.
          */
-        @CallSuper
-        protected void onDestroy() {
-            mDataCallListChangedCallbacks.clear();
-        }
+        @Override
+        public abstract void close();
     }
 
     private static final class SetupDataCallRequest {
@@ -345,7 +343,7 @@
                     break;
                 case DATA_SERVICE_REMOVE_DATA_SERVICE_PROVIDER:
                     if (serviceProvider != null) {
-                        serviceProvider.onDestroy();
+                        serviceProvider.close();
                         mServiceMap.remove(slotId);
                     }
                     break;
@@ -353,7 +351,7 @@
                     for (int i = 0; i < mServiceMap.size(); i++) {
                         serviceProvider = mServiceMap.get(i);
                         if (serviceProvider != null) {
-                            serviceProvider.onDestroy();
+                            serviceProvider.close();
                         }
                     }
                     mServiceMap.clear();
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index 4af31b5..bef1142 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -125,7 +125,6 @@
      *
      * @param result The result code. Must be one of the {@link ResultCode}.
      */
-    @SystemApi
     public void onSetDataProfileComplete(@ResultCode int result) {
         IDataServiceCallback callback = mCallback.get();
         if (callback != null) {
diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java
index 57d9cce..45b4849 100644
--- a/telephony/java/android/telephony/data/QualifiedNetworksService.java
+++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java
@@ -151,7 +151,7 @@
 
         /**
          * Called when the qualified networks updater is removed. The extended class should
-         * implement this method to perform clean up works.
+         * implement this method to perform cleanup works.
          */
         @Override
         public abstract void close();
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index 8fcdb6e..4d95e55 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -16,11 +16,15 @@
 
 package android.telephony.ims;
 
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * This class enables an application to get details on why a method call failed.
  *
@@ -30,158 +34,292 @@
 public final class ImsReasonInfo implements Parcelable {
 
     /**
-     * Specific code of each types
+     * The Reason is unspecified.
      */
     public static final int CODE_UNSPECIFIED = 0;
 
-    /**
-     * LOCAL
-     */
+
+    // LOCAL
+
     // IMS -> Telephony
-    // The passed argument is an invalid
+    /**
+     * The passed argument is invalid.
+     */
     public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101;
-    // The operation is invoked in invalid call state
+    /**
+     * The operation was invoked while in an invalid call state.
+     */
     public static final int CODE_LOCAL_ILLEGAL_STATE = 102;
-    // IMS service internal error
+    /**
+     * IMS service internal error
+     */
     public static final int CODE_LOCAL_INTERNAL_ERROR = 103;
-    // IMS service goes down (service connection is lost)
+    /**
+     * ImsService has crashed (service connection is lost).
+     */
     public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106;
-    // No pending incoming call exists
+    /**
+     * No pending incoming call exists
+     */
     public static final int CODE_LOCAL_NO_PENDING_CALL = 107;
-    // IMS Call ended during conference merge process
+    /**
+     * IMS Call ended during conference merge process
+     */
     public static final int CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE = 108;
 
     // IMS -> Telephony
-    // Service unavailable; by power off
+    /**
+     * Service unavailable; radio power off
+     */
     public static final int CODE_LOCAL_POWER_OFF = 111;
-    // Service unavailable; by low battery
+    /**
+     * Service unavailable; low battery
+     */
     public static final int CODE_LOCAL_LOW_BATTERY = 112;
-    // Service unavailable; by out of service (data service state)
+    /**
+     * Service unavailable; out of service (data service state)
+     */
     public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121;
-    // Service unavailable; by no LTE coverage
-    // (VoLTE is not supported even though IMS is registered)
+    /**
+     * Service unavailable; no LTE coverage
+     * (VoLTE is not supported even though IMS is registered)
+     */
     public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122;
-    // Service unavailable; by located in roaming area
+    /**
+     * Service unavailable; located in roaming area
+     */
     public static final int CODE_LOCAL_NETWORK_ROAMING = 123;
-    // Service unavailable; by IP changed
+    /**
+     * Service unavailable; IP changed
+     */
     public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124;
-    // Service unavailable; other
+    /**
+     * Service unavailable; for an unspecified reason
+     */
     public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131;
-    // Service unavailable; IMS connection is lost (IMS is not registered)
+    /**
+     * Service unavailable; IMS is not registered
+     */
     public static final int CODE_LOCAL_NOT_REGISTERED = 132;
 
     // IMS <-> Telephony
-    // Max call exceeded
+    /**
+     * Maximum number of simultaneous calls exceeded
+     */
     public static final int CODE_LOCAL_CALL_EXCEEDED = 141;
     // IMS <- Telephony
-    // Call busy
+    /**
+     * The call is busy.
+     */
     public static final int CODE_LOCAL_CALL_BUSY = 142;
-    // Call decline
+    /**
+     * The Call has been declined locally on this device.
+     */
     public static final int CODE_LOCAL_CALL_DECLINE = 143;
     // IMS -> Telephony
-    // SRVCC is in progress
+    /**
+     * Can not complete call; an SRVCC is in progress.
+     */
     public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144;
-    // Resource reservation is failed (QoS precondition)
+    /**
+     * Can not complete call; resource reservation is failed (QoS precondition)
+     */
     public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145;
-    // Retry CS call; VoLTE service can't be provided by the network or remote end
-    // Resolve the extra code(EXTRA_CODE_CALL_RETRY_*) if the below code is set
+    /**
+     * VoLTE service can't be provided by the network or remote end, retry the call.
+     * Resolve the extra code provided in (EXTRA_CODE_CALL_RETRY_*) if the below code is set
+     */
     public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146;
-    // Retry VoLTE call; VoLTE service can't be provided by the network temporarily
+    /**
+     * VoLTE service can't be provided by the network temporarily, retry the call.
+     */
     public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147;
-    // IMS call is already terminated (in TERMINATED state)
+    /**
+     * IMS call is already terminated (in TERMINATED state).
+     */
     public static final int CODE_LOCAL_CALL_TERMINATED = 148;
-    // Handover not feasible
+    /**
+     * Call was disconnected because a handover is not feasible due to network conditions.
+     */
     public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149;
 
-    /**
+    /*
      * TIMEOUT (IMS -> Telephony)
      */
-    // 1xx waiting timer is expired after sending INVITE request (MO only)
+    /**
+     * 1xx waiting timer is expired after sending INVITE request (MO calls only)
+     */
     public static final int CODE_TIMEOUT_1XX_WAITING = 201;
-    // User no answer during call setup operation (MO/MT)
-    // MO : 200 OK to INVITE request is not received,
-    // MT : No action from user after alerting the call
+    /**
+     * User didn't answer during call setup operation (MO/MT)
+     * MO : 200 OK to INVITE request is not received,
+     * MT : No action from user after alerting the call
+     */
     public static final int CODE_TIMEOUT_NO_ANSWER = 202;
-    // User no answer during call update operation (MO/MT)
-    // MO : 200 OK to re-INVITE request is not received,
-    // MT : No action from user after alerting the call
+    /**
+     * User no answer during call update operation (MO/MT)
+     * MO : 200 OK to re-INVITE request is not received,
+     * MT : No action from user after alerting the call
+     */
     public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203;
 
-    //Call was blocked by call barring
+    /**
+     * The call was blocked by call barring configuration.
+     */
     public static final int CODE_CALL_BARRED = 240;
 
-    //Call failures for FDN
+    /**
+     * The operation is restricted to fixed dialing numbers only.
+     */
     public static final int CODE_FDN_BLOCKED = 241;
 
-    // Network does not accept the emergency call request because IMEI was used as identification
-    // and this capability is not supported by the network.
+    /**
+     * Network rejected the emergency call request because IMEI was used as identification
+     * and this capability is not supported by the network.
+     */
     public static final int CODE_IMEI_NOT_ACCEPTED = 243;
 
     //STK CC errors
+    /**
+     * Stk Call Control modified DIAL request to USSD request.
+     */
     public static final int CODE_DIAL_MODIFIED_TO_USSD = 244;
+    /**
+     * Stk Call Control modified DIAL request to SS request.
+     */
     public static final int CODE_DIAL_MODIFIED_TO_SS = 245;
+    /**
+     * Stk Call Control modified DIAL request to DIAL with modified data.
+     */
     public static final int CODE_DIAL_MODIFIED_TO_DIAL = 246;
+    /**
+     * Stk Call Control modified DIAL request to Video DIAL request.
+     */
     public static final int CODE_DIAL_MODIFIED_TO_DIAL_VIDEO = 247;
+    /**
+     * Stk Call Control modified Video DIAL request to DIAL request.
+     */
     public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL = 248;
+    /**
+     * Stk Call Control modified Video DIAL request to Video DIAL request.
+     */
     public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 249;
+    /**
+     * Stk Call Control modified Video DIAL request to SS request.
+     */
     public static final int CODE_DIAL_VIDEO_MODIFIED_TO_SS = 250;
+    /**
+     * Stk Call Control modified Video DIAL request to USSD request.
+     */
     public static final int CODE_DIAL_VIDEO_MODIFIED_TO_USSD = 251;
 
-    /**
+    /*
      * STATUSCODE (SIP response code) (IMS -> Telephony)
      */
     // 3xx responses
-    // SIP request is redirected
+    /**
+     * SIP 3xx response: SIP request is redirected
+     */
     public static final int CODE_SIP_REDIRECTED = 321;
     // 4xx responses
-    // 400 : Bad Request
+    /**
+     * Sip 400 response : Bad Request
+     */
     public static final int CODE_SIP_BAD_REQUEST = 331;
-    // 403 : Forbidden
+    /**
+     * Sip 403 response : Forbidden
+     */
     public static final int CODE_SIP_FORBIDDEN = 332;
-    // 404 : Not Found
+    /**
+     * Sip 404 response : Not Found
+     */
     public static final int CODE_SIP_NOT_FOUND = 333;
-    // 415 : Unsupported Media Type
-    // 416 : Unsupported URI Scheme
-    // 420 : Bad Extension
+    /**
+     * Not supported, because of one of the following:
+     * SIP response 415 : Unsupported Media Type,
+     * SIP response 416 : Unsupported URI Scheme,
+     * SIP response 420 : Bad Extension
+     */
     public static final int CODE_SIP_NOT_SUPPORTED = 334;
-    // 408 : Request Timeout
+    /**
+     * SIP response 408 : Request Timeout.
+     */
     public static final int CODE_SIP_REQUEST_TIMEOUT = 335;
-    // 480 : Temporarily Unavailable
+    /**
+     * SIP response 480 : Temporarily Unavailable
+     */
     public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336;
-    // 484 : Address Incomplete
+    /**
+     * SIP response 484 : Address Incomplete
+     */
     public static final int CODE_SIP_BAD_ADDRESS = 337;
-    // 486 : Busy Here
-    // 600 : Busy Everywhere
+    /**
+     * Returned a busy response, may be one of the following:
+     * SIP response 486 : Busy Here,
+     * SIP response 600 : Busy Everywhere
+     */
     public static final int CODE_SIP_BUSY = 338;
-    // 487 : Request Terminated
+    /**
+     * SIP response 487 : Request Terminated
+     */
     public static final int CODE_SIP_REQUEST_CANCELLED = 339;
-    // 406 : Not Acceptable
-    // 488 : Not Acceptable Here
-    // 606 : Not Acceptable
+    /**
+     * Received a not acceptable response, will be one of the following:
+     * SIP response 406 : Not Acceptable
+     * SIP response 488 : Not Acceptable Here
+     * SIP response 606 : Not Acceptable
+     */
     public static final int CODE_SIP_NOT_ACCEPTABLE = 340;
-    // 410 : Gone
-    // 604 : Does Not Exist Anywhere
+    /**
+     * Received a not acceptable response, will be one of the following:
+     * SIP response 410 : Gone
+     * SIP response 604 : Does Not Exist Anywhere
+     */
     public static final int CODE_SIP_NOT_REACHABLE = 341;
-    // Others
+    /**
+     * Received another unspecified error SIP response from the client.
+     */
     public static final int CODE_SIP_CLIENT_ERROR = 342;
-    // 481 Transaction Does Not Exist
+    /**
+     * SIP response 481: Transaction Does Not Exist
+     */
     public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343;
     // 5xx responses
-    // 501 : Server Internal Error
+    /**
+     * SIP response 501 : Server Internal Error
+     */
     public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351;
-    // 503 : Service Unavailable
+    /**
+     * SIP response 503 : Service Unavailable
+     */
     public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352;
-    // 504 : Server Time-out
+    /**
+     * SIP response 504 : Server Time-out
+     */
     public static final int CODE_SIP_SERVER_TIMEOUT = 353;
-    // Others
+    /**
+     * Received an unspecified SIP server error response.
+     */
     public static final int CODE_SIP_SERVER_ERROR = 354;
     // 6xx responses
-    // 603 : Decline
+    /**
+     * 603 : Decline
+     */
     public static final int CODE_SIP_USER_REJECTED = 361;
-    // Others
+    /**
+     * Unspecified 6xx error.
+     */
     public static final int CODE_SIP_GLOBAL_ERROR = 362;
-    // Emergency failure
+
+    /**
+     * Emergency call failed in the modem with a temporary fail cause and should be redialed on this
+     * slot.
+     */
     public static final int CODE_EMERGENCY_TEMP_FAILURE = 363;
+    /**
+     * Emergency call failed in the modem with a permanent fail cause and should not be redialed on
+     * this slot. If there are any other slots available for emergency calling, try those.
+     */
     public static final int CODE_EMERGENCY_PERM_FAILURE = 364;
 
     /**
@@ -194,81 +332,239 @@
     public static final int CODE_SIP_USER_MARKED_UNWANTED = 365;
 
     /**
-     * MEDIA (IMS -> Telephony)
+     * SIP Response : 405
+     * Method not allowed for the address in the Request URI
      */
-    // Media resource initialization failed
-    public static final int CODE_MEDIA_INIT_FAILED = 401;
-    // RTP timeout (no audio / video traffic in the session)
-    public static final int CODE_MEDIA_NO_DATA = 402;
-    // Media is not supported; so dropped the call
-    public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403;
-    // Unknown media related errors
-    public static final int CODE_MEDIA_UNSPECIFIED = 404;
+    public static final int CODE_SIP_METHOD_NOT_ALLOWED = 366;
 
     /**
+     * SIP Response : 407
+     * The request requires user authentication
+     */
+    public static final int CODE_SIP_PROXY_AUTHENTICATION_REQUIRED = 367;
+
+    /**
+     * SIP Response : 413
+     * Request body too large
+     */
+    public static final int CODE_SIP_REQUEST_ENTITY_TOO_LARGE = 368;
+
+    /**
+     * SIP Response : 414
+     * Request-URI too large
+     */
+    public static final int CODE_SIP_REQUEST_URI_TOO_LARGE = 369;
+
+    /**
+     * SIP Response : 421
+     * Specific extension is required, which is not present in the HEADER
+     */
+    public static final int CODE_SIP_EXTENSION_REQUIRED = 370;
+
+    /**
+     * SIP Response : 422
+     * The session expiration field too small
+     */
+    public static final int CODE_SIP_INTERVAL_TOO_BRIEF = 371;
+
+    /**
+     * SIP Response : 481
+     * Request received by the server does not match any dialog or transaction
+     */
+    public static final int CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST = 372;
+
+    /**
+     * SIP Response : 482
+     * Server has detected a loop
+     */
+    public static final int CODE_SIP_LOOP_DETECTED = 373;
+
+    /**
+     * SIP Response : 483
+     * Max-Forwards value reached
+     */
+    public static final int CODE_SIP_TOO_MANY_HOPS = 374;
+
+    /**
+     * SIP Response : 485
+     * Request-URI is ambiguous
+     *
+     */
+    public static final int CODE_SIP_AMBIGUOUS = 376;
+
+    /**
+     * SIP Response : 491
+     * Server has pending request for same dialog
+     */
+    public static final int CODE_SIP_REQUEST_PENDING = 377;
+
+    /**
+     * SIP Response : 493
+     * The request cannot be decrypted by recipient
+     */
+    public static final int CODE_SIP_UNDECIPHERABLE = 378;
+
+    /**
+     * MEDIA (IMS -> Telephony)
+     */
+    /**
+     * Media resource initialization failed
+     */
+    public static final int CODE_MEDIA_INIT_FAILED = 401;
+    /**
+     * RTP timeout (no audio / video traffic in the session)
+     */
+    public static final int CODE_MEDIA_NO_DATA = 402;
+    /**
+     * Media is not supported; so dropped the call
+     */
+    public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403;
+    /**
+     * Unspecified media related error.
+     */
+    public static final int CODE_MEDIA_UNSPECIFIED = 404;
+
+    /*
      * USER
      */
     // Telephony -> IMS
-    // User triggers the call end
+    /**
+     * User triggers the call to be terminated.
+     */
     public static final int CODE_USER_TERMINATED = 501;
-    // No action while an incoming call is ringing
+    /**
+     * No action was taken while an incoming call was ringing.
+     */
     public static final int CODE_USER_NOANSWER = 502;
-    // User ignores an incoming call
+    /**
+     * User ignored an incoming call.
+     */
     public static final int CODE_USER_IGNORE = 503;
-    // User declines an incoming call
+    /**
+     * User declined an incoming call.
+     */
     public static final int CODE_USER_DECLINE = 504;
-    // Device declines/ends a call due to low battery
+    /**
+     * Device declined/ended a call due to a low battery condition.
+     */
     public static final int CODE_LOW_BATTERY = 505;
-    // Device declines call due to blacklisted call ID
+    /**
+     * Device declined a call due to a blacklisted caller ID.
+     */
     public static final int CODE_BLACKLISTED_CALL_ID = 506;
     // IMS -> Telephony
-    // The call is terminated by the network or remote user
-    public static final int CODE_USER_TERMINATED_BY_REMOTE = 510;
-
     /**
-     * Extra codes for the specific code value
-     * This value can be referred when the code is CODE_LOCAL_CALL_CS_RETRY_REQUIRED.
+     * The call has been terminated by the network or remote user.
      */
-    // Try to connect CS call; normal
-    public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1;
-    // Try to connect CS call without the notification to user
-    public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2;
-    // Try to connect CS call by the settings of the menu
-    public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3;
+    public static final int CODE_USER_TERMINATED_BY_REMOTE = 510;
+    /**
+    * Upgrade Downgrade request rejected by
+    * Remote user if the request is MO initiated
+    * Local user if the request is MT initiated
+    */
+    public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511;
 
     /**
+    * Upgrade Downgrade request cacncelled by the user who initiated it
+    */
+    public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512;
+
+    /**
+     * UPGRADE DOWNGRADE operation failed
+     * This can happen due to failure from SIP/RTP/SDP generation or a Call end is
+     * triggered/received while Reinvite is in progress.
+     */
+    public static final int CODE_SESSION_MODIFICATION_FAILED = 1517;
+
+    /*
      * UT
      */
+    /**
+     * UT is currently not supported on this device.
+     */
     public static final int CODE_UT_NOT_SUPPORTED = 801;
+    /**
+     * UT services are currently not available on this device.
+     */
     public static final int CODE_UT_SERVICE_UNAVAILABLE = 802;
+    /**
+     * The requested UT operation is not allowed.
+     */
     public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803;
+    /**
+     * The UT request resulted in a network error.
+     */
     public static final int CODE_UT_NETWORK_ERROR = 804;
+    /**
+     * The password entered for UT operations does not match the stored password.
+     */
     public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821;
     //STK CC errors
+    /**
+     * Sim Toolkit Call Control modified the UT operation to a dial command.
+     */
     public static final int CODE_UT_SS_MODIFIED_TO_DIAL = 822;
+    /**
+     * Sim Toolkit Call Control modified the UT operation to a USSD command.
+     */
     public static final int CODE_UT_SS_MODIFIED_TO_USSD = 823;
+    /**
+     * Sim Toolkit Call Control modified the UT operation to another supplementary service command.
+     */
     public static final int CODE_UT_SS_MODIFIED_TO_SS = 824;
+    /**
+     * Sim Toolkit Call Control modified the UT operation to a video call dial command.
+     */
     public static final int CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO = 825;
 
+    /**@hide*/
+    @IntDef(value = {
+            CODE_UT_NOT_SUPPORTED,
+            CODE_UT_SERVICE_UNAVAILABLE,
+            CODE_UT_OPERATION_NOT_ALLOWED,
+            CODE_UT_NETWORK_ERROR,
+            CODE_UT_CB_PASSWORD_MISMATCH,
+            CODE_UT_SS_MODIFIED_TO_DIAL,
+            CODE_UT_SS_MODIFIED_TO_USSD,
+            CODE_UT_SS_MODIFIED_TO_SS,
+            CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO
+    }, prefix = "CODE_UT_")
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface UtReason {}
+
     /**
-     * ECBM
+     * Emergency callback mode is not supported.
      */
     public static final int CODE_ECBM_NOT_SUPPORTED = 901;
 
     /**
-     * Fail code used to indicate that Multi-endpoint is not supported by the Ims framework.
+     * Fail code used to indicate that Multi-endpoint is not supported by the IMS framework.
      */
     public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902;
 
     /**
-     * Ims Registration error code
+     * IMS Registration error code
      */
     public static final int CODE_REGISTRATION_ERROR = 1000;
 
-    /**
+    /*
      * CALL DROP error codes (Call could drop because of many reasons like Network not available,
      *  handover, failed, etc)
      */
+    /**
+     * MT call has ended due to a release from the network because the call was answered elsewhere.
+     */
+    public static final int CODE_ANSWERED_ELSEWHERE = 1014;
+
+    /**
+     * For MultiEndpoint - Call Pull request has failed.
+     */
+    public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015;
+
+    /**
+     * For MultiEndpoint - Call has been pulled from primary to secondary.
+     */
+    public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016;
 
     /**
      * CALL DROP error code for the case when a device is ePDG capable and when the user is on an
@@ -279,46 +575,45 @@
     public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100;
 
     /**
-     * MT call has ended due to a release from the network
-     * because the call was answered elsewhere
+     * For MultiEndPoint - Call was rejected elsewhere
      */
-    public static final int CODE_ANSWERED_ELSEWHERE = 1014;
-
-    /**
-     * For MultiEndpoint - Call Pull request has failed
-     */
-    public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015;
-
-    /**
-     * For MultiEndpoint - Call has been pulled from primary to secondary
-     */
-    public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016;
+    public static final int CODE_REJECTED_ELSEWHERE = 1017;
 
     /**
      * Supplementary services (HOLD/RESUME) failure error codes.
      * Values for Supplemetary services failure - Failed, Cancelled and Re-Invite collision.
      */
+
+    /**
+     * Supplementary Services (HOLD/RESUME) - the command failed.
+     */
     public static final int CODE_SUPP_SVC_FAILED = 1201;
+    /**
+     * Supplementary Services (HOLD/RESUME) - the command was cancelled.
+     */
     public static final int CODE_SUPP_SVC_CANCELLED = 1202;
+    /**
+     * Supplementary Services (HOLD/RESUME) - the command resulted in a re-invite collision.
+     */
     public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203;
 
     /**
-     * DPD Procedure received no response or send failed
+     * DPD Procedure received no response or send failed.
      */
     public static final int CODE_IWLAN_DPD_FAILURE = 1300;
 
     /**
-     * Establishment of the ePDG Tunnel Failed
+     * Establishment of the ePDG Tunnel Failed.
      */
     public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400;
 
     /**
-     * Re-keying of the ePDG Tunnel Failed; may not always result in teardown
+     * Re-keying of the ePDG Tunnel Failed; may not always result in teardown.
      */
     public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401;
 
     /**
-     * Connection to the packet gateway is lost
+     * Connection to the packet gateway is lost.
      */
     public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402;
 
@@ -571,8 +866,10 @@
      */
     public static final int CODE_REJECT_ONGOING_CS_CALL = 1621;
 
-    /* OEM specific error codes. To be used by OEMs when they don't want to
-   reveal error code which would be replaced by ERROR_UNSPECIFIED */
+    /*
+     * OEM specific error codes. To be used by OEMs when they don't want to reveal error code which
+     * would be replaced by ERROR_UNSPECIFIED.
+     */
     public static final int CODE_OEM_CAUSE_1 = 0xf001;
     public static final int CODE_OEM_CAUSE_2 = 0xf002;
     public static final int CODE_OEM_CAUSE_3 = 0xf003;
@@ -597,6 +894,33 @@
             = "Forbidden. Not Authorized for Service";
 
 
+    /*
+     * Extra codes for the specific code value
+     * This value can be referred when the code is CODE_LOCAL_CALL_CS_RETRY_REQUIRED.
+     */
+    /**
+     * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+     * been returned.
+     * <p>
+     * Try to connect the call using CS
+     */
+    public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1;
+    /**
+     * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+     * been returned.
+     * <p>
+     * Try to connect the call using CS and do not notify the user.
+     */
+    public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2;
+    /**
+     * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has
+     * been returned.
+     * <p>
+     * Try to connect the call using CS by using the settings.
+     */
+    public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3;
+
+
     // For main reason code
     /** @hide */
     @UnsupportedAppUsage
@@ -638,29 +962,28 @@
     }
 
     /**
-     *
+     * @return an integer representing more information about the completion of an operation.
      */
     public int getCode() {
         return mCode;
     }
 
     /**
-     *
+     * @return an optional OEM specified code that provides extra information.
      */
     public int getExtraCode() {
         return mExtraCode;
     }
 
     /**
-     *
+     * @return an optional OEM specified string that provides extra information about the operation
+     * result.
      */
     public String getExtraMessage() {
         return mExtraMessage;
     }
 
     /**
-     * Returns the string format of {@link ImsReasonInfo}
-     *
      * @return the string format of {@link ImsReasonInfo}
      */
     public String toString() {
diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java
index db5ba47..3a82517 100644
--- a/telephony/java/android/telephony/ims/ImsSsData.java
+++ b/telephony/java/android/telephony/ims/ImsSsData.java
@@ -65,6 +65,17 @@
     public static final int SS_INCOMING_BARRING_DN = 21;
     public static final int SS_INCOMING_BARRING_ANONYMOUS = 22;
 
+
+    /**@hide*/
+    @IntDef(flag = true, prefix = {"SS_"}, value = {
+            SS_ACTIVATION,
+            SS_DEACTIVATION,
+            SS_INTERROGATION,
+            SS_REGISTRATION,
+            SS_ERASURE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RequestType{}
+
     //Supplementary Service Request Types
     public static final int SS_ACTIVATION = 0;
     public static final int SS_DEACTIVATION = 1;
@@ -72,6 +83,17 @@
     public static final int SS_REGISTRATION = 3;
     public static final int SS_ERASURE = 4;
 
+    /**@hide*/
+    @IntDef(flag = true, prefix = {"SS_"}, value = {
+            SS_ALL_TELE_AND_BEARER_SERVICES,
+            SS_ALL_TELESEVICES,
+            SS_TELEPHONY,
+            SS_ALL_DATA_TELESERVICES,
+            SS_SMS_SERVICES,
+            SS_ALL_TELESERVICES_EXCEPT_SMS})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TeleserviceType{}
+
     // Supplementary Service Teleservice Type
     public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0;
     public static final int SS_ALL_TELESEVICES = 1;
@@ -191,21 +213,6 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface ServiceType{}
 
-    /** @hide */
-    @IntDef(flag = true, prefix = { "SERVICE_CLASS" }, value = {
-            SERVICE_CLASS_NONE,
-            SERVICE_CLASS_VOICE,
-            SERVICE_CLASS_DATA,
-            SERVICE_CLASS_FAX,
-            SERVICE_CLASS_SMS,
-            SERVICE_CLASS_DATA_CIRCUIT_SYNC,
-            SERVICE_CLASS_DATA_CIRCUIT_ASYNC,
-            SERVICE_CLASS_DATA_PACKET_ACCESS,
-            SERVICE_CLASS_DATA_PAD
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface ServiceClass{}
-
     /**
      * The Service type of this Supplementary service.
      * @hide
@@ -221,7 +228,7 @@
      *     {@link #SS_ERASURE}
      * @hide
      */
-    public final int requestType;
+    public final @RequestType int requestType;
 
     /**
      * Supplementary Service teleservice type:
@@ -234,14 +241,14 @@
      *
      * @hide
      */
-    public final int teleserviceType;
+    public final @TeleserviceType int teleserviceType;
 
     /**
      * Supplementary Service service class.
      *
      * @hide
      */
-    public final @ServiceClass int serviceClass;
+    public final @ServiceClassFlags int serviceClass;
 
     /**
      * Result of Supplementary Service operation. Valid values are:
@@ -285,7 +292,7 @@
          * @see #build()
          */
         public Builder(@ServiceType int serviceType, int requestType, int teleserviceType,
-                @ServiceClass int serviceClass, int result) {
+                @ServiceClassFlags int serviceClass, int result) {
             mImsSsData = new ImsSsData(serviceType, requestType, teleserviceType, serviceClass,
                     result);
         }
@@ -294,7 +301,7 @@
          * Set the array of {@link ImsSsInfo}s that are associated with this supplementary service
          * data.
          */
-        public Builder setSuppServiceInfo(@NonNull ImsSsInfo[] imsSsInfos) {
+        public @NonNull Builder setSuppServiceInfo(@NonNull ImsSsInfo[] imsSsInfos) {
             mImsSsData.mImsSsInfo = imsSsInfos;
             return this;
         }
@@ -303,7 +310,8 @@
          * Set the array of {@link ImsCallForwardInfo}s that are associated with this supplementary
          * service data.
          */
-        public Builder setCallForwardingInfo(@NonNull ImsCallForwardInfo[] imsCallForwardInfos) {
+        public @NonNull Builder setCallForwardingInfo(
+                @NonNull ImsCallForwardInfo[] imsCallForwardInfos) {
             mImsSsData.mCfInfo = imsCallForwardInfos;
             return this;
         }
@@ -311,7 +319,7 @@
         /**
          * @return an {@link ImsSsData} containing optional parameters.
          */
-        public ImsSsData build() {
+        public @NonNull ImsSsData build() {
             return mImsSsData;
         }
     }
@@ -337,7 +345,7 @@
      *               success, or ImsReasonInfo code if the result is a failure.
      */
     public ImsSsData(@ServiceType int serviceType, int requestType, int teleserviceType,
-            @ServiceClass int serviceClass, int result) {
+            @ServiceClassFlags int serviceClass, int result) {
         this.serviceType = serviceType;
         this.requestType = requestType;
         this.teleserviceType = teleserviceType;
@@ -449,14 +457,9 @@
     }
 
     /**
-     * Supplementary Service request Type:
-     *     {@link #SS_ACTIVATION),
-     *     {@link #SS_DEACTIVATION},
-     *     {@link #SS_INTERROGATION},
-     *     {@link #SS_REGISTRATION},
-     *     {@link #SS_ERASURE}
+     * Supplementary Service request Type.
      */
-    public int getRequestType() {
+    public @RequestType int getRequestType() {
         return requestType;
     }
 
@@ -468,31 +471,25 @@
     }
 
     /**
-     * Supplementary Service teleservice type:
-     *     {@link #SS_ALL_TELE_AND_BEARER_SERVICES},
-     *     {@link #SS_ALL_TELESEVICES},
-     *     {@link #SS_TELEPHONY},
-     *     {@link #SS_ALL_DATA_TELESERVICES},
-     *     {@link #SS_SMS_SERVICES},
-     *     {@link #SS_ALL_TELESERVICES_EXCEPT_SMS}
+     * Supplementary Service teleservice type.
      */
-    public int getTeleserviceType() {
+    public @TeleserviceType int getTeleserviceType() {
         return teleserviceType;
     }
 
     /**
      * Supplementary Service service class.
      */
-    public @ServiceClass int getServiceClass() {
+    public @ServiceClassFlags int getServiceClass() {
         return serviceClass;
     }
 
     /**
      * Result of Supplementary Service operation. Valid values are:
      *     {@link #RESULT_SUCCESS} if the result is success, or
-     *     {@link ImsReasonInfo} CODE_* code if the result is a failure.
+     *     {@link ImsReasonInfo.UtReason} code if the result is a failure.
      */
-    public int getResult() {
+    public @ImsReasonInfo.UtReason int getResult() {
         return result;
     }
 
diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java
index 0af6e62..031f9e1 100644
--- a/telephony/java/android/telephony/ims/ImsSsInfo.java
+++ b/telephony/java/android/telephony/ims/ImsSsInfo.java
@@ -82,6 +82,7 @@
      */
     public static final int SERVICE_PROVISIONED = 1;
 
+    /**@hide*/
     @IntDef(value = {
             CLIR_OUTGOING_DEFAULT,
             CLIR_OUTGOING_INVOCATION,
@@ -141,6 +142,7 @@
      */
     public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4;
 
+    /**@hide*/
     @IntDef(value = {
             CLIR_STATUS_NOT_PROVISIONED,
             CLIR_STATUS_PROVISIONED_PERMANENT,
@@ -184,7 +186,7 @@
          * Set the ICB number for IMS call barring.
          * @param number The number in E.164 international format.
          */
-        public Builder setIncomingCommunicationBarringNumber(@NonNull String number) {
+        public @NonNull Builder setIncomingCommunicationBarringNumber(@NonNull String number) {
             mImsSsInfo.mIcbNum = number;
             return this;
         }
@@ -192,7 +194,7 @@
         /**
          * Set the provisioning status for a Supplementary Service interrogation response.
          */
-        public Builder setProvisionStatus(@ServiceProvisionStatus int provisionStatus) {
+        public @NonNull Builder setProvisionStatus(@ServiceProvisionStatus int provisionStatus) {
             mImsSsInfo.mProvisionStatus = provisionStatus;
             return this;
         }
@@ -201,7 +203,7 @@
          * Set the Calling Line Identification Restriction (CLIR) status for a supplementary service
          * interrogation response.
          */
-        public Builder setClirInterrogationStatus(@ClirInterrogationStatus int status) {
+        public @NonNull Builder setClirInterrogationStatus(@ClirInterrogationStatus int status) {
             mImsSsInfo.mClirInterrogationStatus = status;
             return this;
         }
@@ -209,7 +211,7 @@
         /**
          * Set the Calling line identification Restriction (CLIR) state for outgoing calls.
          */
-        public Builder setClirOutgoingState(@ClirOutgoingState int state) {
+        public @NonNull Builder setClirOutgoingState(@ClirOutgoingState int state) {
             mImsSsInfo.mClirOutgoingState = state;
             return this;
         }
@@ -217,7 +219,7 @@
         /**
          * @return a built {@link ImsSsInfo} containing optional the parameters that were set.
          */
-        public ImsSsInfo build() {
+        public @NonNull ImsSsInfo build() {
             return mImsSsInfo;
         }
     }
diff --git a/telephony/java/android/telephony/ims/RcsManager.java b/telephony/java/android/telephony/ims/RcsManager.java
new file mode 100644
index 0000000..d50b516
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RcsManager.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.telephony.ims;
+
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * The manager class for RCS related utilities.
+ * @hide
+ */
+@SystemService(Context.TELEPHONY_RCS_SERVICE)
+public class RcsManager {
+
+    private static final RcsMessageStore sRcsMessageStoreInstance = new RcsMessageStore();
+
+    /**
+     * Returns an instance of RcsMessageStore.
+     */
+    public RcsMessageStore getRcsMessageStore() {
+        return sRcsMessageStoreInstance;
+    }
+}
diff --git a/telephony/java/android/telephony/rcs/RcsManager.java b/telephony/java/android/telephony/ims/RcsMessageStore.java
similarity index 78%
rename from telephony/java/android/telephony/rcs/RcsManager.java
rename to telephony/java/android/telephony/ims/RcsMessageStore.java
index 0ef4e15..c89c0be 100644
--- a/telephony/java/android/telephony/rcs/RcsManager.java
+++ b/telephony/java/android/telephony/ims/RcsMessageStore.java
@@ -14,24 +14,20 @@
  * limitations under the License.
  */
 
-package android.telephony.rcs;
+package android.telephony.ims;
 
-import android.annotation.SystemService;
-import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.telephony.Rlog;
-
-import com.android.internal.telephony.rcs.IRcs;
+import android.telephony.ims.aidl.IRcs;
 
 /**
- * RcsManager is the application interface to RcsProvider and provides access methods to
+ * RcsMessageStore is the application interface to RcsProvider and provides access methods to
  * RCS related database tables.
  * @hide - TODO make this public
  */
-@SystemService(Context.TELEPHONY_RCS_SERVICE)
-public class RcsManager {
-    private static final String TAG = "RcsManager";
+public class RcsMessageStore {
+    private static final String TAG = "RcsMessageStore";
     private static final boolean VDBG = false;
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl b/telephony/java/android/telephony/ims/RcsThread.aidl
similarity index 63%
copy from telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
copy to telephony/java/android/telephony/ims/RcsThread.aidl
index 4c289ac..79d4732 100644
--- a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
+++ b/telephony/java/android/telephony/ims/RcsThread.aidl
@@ -1,11 +1,12 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Copyright 2018, 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
+ *     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,
@@ -14,12 +15,6 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.rcs;
+package android.telephony;
 
-interface IRcs {
-    // RcsManager APIs
-    void deleteThread(int threadId);
-
-    // RcsThread APIs
-    int getMessageCount(int rcsThreadId);
-}
\ No newline at end of file
+parcelable RcsThread;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/rcs/RcsThread.java b/telephony/java/android/telephony/ims/RcsThread.java
similarity index 96%
rename from telephony/java/android/telephony/rcs/RcsThread.java
rename to telephony/java/android/telephony/ims/RcsThread.java
index 83eb973..b7f440d 100644
--- a/telephony/java/android/telephony/rcs/RcsThread.java
+++ b/telephony/java/android/telephony/ims/RcsThread.java
@@ -14,14 +14,13 @@
  * limitations under the License.
  */
 
-package android.telephony.rcs;
+package android.telephony.ims;
 
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-
-import com.android.internal.telephony.rcs.IRcs;
+import android.telephony.ims.aidl.IRcs;
 
 /**
  * RcsThread represents a single RCS conversation thread. It holds messages that were sent and
diff --git a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl b/telephony/java/android/telephony/ims/aidl/IRcs.aidl
similarity index 83%
rename from telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
rename to telephony/java/android/telephony/ims/aidl/IRcs.aidl
index 4c289ac..b2e2fad 100644
--- a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IRcs.aidl
@@ -14,10 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.rcs;
+package android.telephony.ims.aidl;
 
+/**
+ * RPC definition between RCS storage APIs and phone process.
+ * {@hide}
+ */
 interface IRcs {
-    // RcsManager APIs
+    // RcsMessageStore APIs
     void deleteThread(int threadId);
 
     // RcsThread APIs
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 0abe45c..13539b8 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -17,6 +17,7 @@
 package com.android.internal.telephony;
 
 import android.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.Cursor;
@@ -32,15 +33,15 @@
 import android.provider.ContactsContract.RawContacts;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
 import com.android.i18n.phonenumbers.NumberParseException;
 import com.android.i18n.phonenumbers.PhoneNumberUtil;
 import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
-import android.telephony.SubscriptionManager;
+import com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
 
 import java.util.Locale;
 
@@ -112,6 +113,9 @@
     public Uri contactRefUri;
     public String lookupKey;
 
+    public ComponentName preferredPhoneAccountComponent;
+    public String preferredPhoneAccountId;
+
     public long userType;
 
     /**
@@ -264,6 +268,17 @@
                     info.contactDisplayPhotoUri = null;
                 }
 
+                columnIndex = cursor.getColumnIndex(Data.PREFERRED_PHONE_ACCOUNT_COMPONENT_NAME);
+                if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) {
+                    info.preferredPhoneAccountComponent =
+                            ComponentName.unflattenFromString(cursor.getString(columnIndex));
+                }
+
+                columnIndex = cursor.getColumnIndex(Data.PREFERRED_PHONE_ACCOUNT_ID);
+                if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) {
+                    info.preferredPhoneAccountId = cursor.getString(columnIndex);
+                }
+
                 // look for the custom ringtone, create from the string stored
                 // in the database.
                 // An empty string ("") in the database indicates a silent ringtone,
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index b0c875e..0fdca5d 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -79,10 +79,7 @@
     public static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23;
     public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24;
     public static final int EVENT_RESTART_RADIO = BASE + 26;
-    public static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27;
     public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 29;
-    public static final int CMD_SET_USER_DATA_ENABLE = BASE + 30;
-    public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32;
     public static final int EVENT_ICC_CHANGED = BASE + 33;
     public static final int EVENT_DISCONNECT_DC_RETRYING = BASE + 34;
     public static final int EVENT_DATA_SETUP_COMPLETE_ERROR = BASE + 35;
@@ -93,14 +90,12 @@
     public static final int CMD_NET_STAT_POLL = BASE + 40;
     public static final int EVENT_DATA_RAT_CHANGED = BASE + 41;
     public static final int CMD_CLEAR_PROVISIONING_SPINNER = BASE + 42;
-    public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 43;
     public static final int EVENT_REDIRECTION_DETECTED = BASE + 44;
     public static final int EVENT_PCO_DATA_RECEIVED = BASE + 45;
-    public static final int EVENT_SET_CARRIER_DATA_ENABLED = BASE + 46;
+    public static final int EVENT_DATA_ENABLED_CHANGED = BASE + 46;
     public static final int EVENT_DATA_RECONNECT = BASE + 47;
     public static final int EVENT_ROAMING_SETTING_CHANGE = BASE + 48;
     public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49;
-    public static final int EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE = BASE + 50;
 
     /***** Constants *****/
 
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 442fc34..40c7a9a 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -53,5 +53,6 @@
     void onPhoneCapabilityChanged(in PhoneCapability capability);
     void onRadioPowerStateChanged(in int state);
     void onPreferredDataSubIdChanged(in int subId);
+    void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause);
 }
 
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index f9db4b0..65d1a920 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -210,6 +210,10 @@
      */
     List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage);
 
+    boolean removeSubscriptionsFromGroup(in int[] subIdList, String callingPackage);
+
+    List<SubscriptionInfo> getSubscriptionsInGroup(int subId, String callingPackage);
+
     int getSlotIndex(int subId);
 
     int[] getSubId(int slotIndex);
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 8a1fb7b..99d362a 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -56,6 +56,7 @@
 import java.util.List;
 import java.util.Map;
 
+import android.telephony.UiccCardInfo;
 import android.telephony.UiccSlotInfo;
 
 /**
@@ -1337,18 +1338,6 @@
     String getSubscriptionCarrierName(int subId);
 
     /**
-     * Returns MNO carrier id of the current subscription’s MCCMNC.
-     * <p>MNO carrier id can be solely identified by subscription mccmnc. This is mainly used
-     * for MNO fallback when exact carrier id {@link #getSimCarrierId()}
-     * configurations are not found.
-     *
-     * @return MNO carrier id of the current subscription. Return the value same as carrier id
-     * {@link #getSimCarrierId()}, if MNO carrier id cannot be identified.
-     * @hide
-     */
-    int getSubscriptionMNOCarrierId(int subId);
-
-    /**
      * Returns fine-grained carrier id of the current subscription.
      *
      * <p>The precise carrier id can be used to further differentiate a carrier by different
@@ -1383,10 +1372,13 @@
      * Returns carrier id based on MCCMNC only. This will return a MNO carrier id used for fallback
      * check when exact carrier id {@link #getSimCarrierId()} configurations are not found
      *
+     * @param isSubscriptionMccMnc. If {@true} it means this is a query for subscription mccmnc
+     * {@false} otherwise.
+     *
      * @return carrier id from passing mccmnc.
      * @hide
      */
-    int getCarrierIdFromMccMnc(int slotIndex, String mccmnc);
+    int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc);
 
     /**
      * Action set from carrier signalling broadcast receivers to enable/disable metered apns
@@ -1482,6 +1474,30 @@
     SignalStrength getSignalStrength(int subId);
 
     /**
+     * Get the card ID of the default eUICC card. If there is no eUICC, returns
+     * {@link #INVALID_CARD_ID}.
+     *
+     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+     *
+     * @param subId subscription ID used for authentication
+     * @param callingPackage package making the call
+     * @return card ID of the default eUICC card.
+     * @hide
+     */
+    int getCardIdForDefaultEuicc(int subId, String callingPackage); 
+
+    /**
+     * Gets information about currently inserted UICCs and eUICCs. See {@link UiccCardInfo} for more
+     * details on the kind of information available.
+     *
+     * @return UiccCardInfo an array of UiccCardInfo objects, representing information on the
+     * currently inserted UICCs and eUICCs.
+     *
+     * @hide
+     */
+    UiccCardInfo[] getUiccCardsInfo();
+
+    /**
      * Get slot info for all the UICC slots.
      * @return UiccSlotInfo array.
      * @hide
diff --git a/test-base/Android.bp b/test-base/Android.bp
index 4d765d3..157609c 100644
--- a/test-base/Android.bp
+++ b/test-base/Android.bp
@@ -37,8 +37,6 @@
         "junit.framework",
     ],
 
-    droiddoc_options: ["-stubsourceonly"],
-    metalava_enabled: false,
     compile_dex: true,
 }
 
diff --git a/test-runner/Android.bp b/test-runner/Android.bp
index 0a0d50c..db5053e 100644
--- a/test-runner/Android.bp
+++ b/test-runner/Android.bp
@@ -40,8 +40,6 @@
         "junit.textui",
     ],
 
-    droiddoc_options: ["-stubsourceonly"],
-    metalava_enabled: false,
     compile_dex: true
 }
 
diff --git a/test-runner/api/current.txt b/test-runner/api/current.txt
index 1170eb5..4ba1b8f 100644
--- a/test-runner/api/current.txt
+++ b/test-runner/api/current.txt
@@ -125,8 +125,8 @@
     method public static void assertEquals(double[], double[]);
     method public static void assertEquals(java.lang.String, java.lang.Object[], java.lang.Object[]);
     method public static void assertEquals(java.lang.Object[], java.lang.Object[]);
-    method public static void assertEquals(java.lang.String, java.util.Set<? extends java.lang.Object>, java.util.Set<? extends java.lang.Object>);
-    method public static void assertEquals(java.util.Set<? extends java.lang.Object>, java.util.Set<? extends java.lang.Object>);
+    method public static void assertEquals(java.lang.String, java.util.Set<?>, java.util.Set<?>);
+    method public static void assertEquals(java.util.Set<?>, java.util.Set<?>);
     method public static java.util.regex.MatchResult assertMatchesRegex(java.lang.String, java.lang.String, java.lang.String);
     method public static java.util.regex.MatchResult assertMatchesRegex(java.lang.String, java.lang.String);
     method public static void assertNotContainsRegex(java.lang.String, java.lang.String, java.lang.String);
diff --git a/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java b/tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java
similarity index 83%
rename from tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java
rename to tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java
index 7f5f03e..290e04c 100644
--- a/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java
+++ b/tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java
@@ -16,17 +16,17 @@
 package com.android.tests.rcs;
 
 import android.support.test.runner.AndroidJUnit4;
-import android.telephony.rcs.RcsManager;
+import android.telephony.ims.RcsMessageStore;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
-public class RcsManagerTest {
+public class RcsMessageStoreTest {
     //TODO(sahinc): Add meaningful tests once we have more of the implementation in place
     @Test
     public void testDeleteThreadDoesntCrash() {
-        RcsManager mRcsManager = new RcsManager();
-        mRcsManager.deleteThread(0);
+        RcsMessageStore mRcsMessageStore = new RcsMessageStore();
+        mRcsMessageStore.deleteThread(0);
     }
 }
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java
index 50aef1d..84f7359 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java
@@ -474,7 +474,7 @@
                 new StringNetworkSpecifier("specs"));
         try {
             nc2.addTransportType(TRANSPORT_WIFI);
-            fail("Cannot set NetworkSpecifier on a NetworkCapability with multiple transports!");
+            fail("Cannot set a second TransportType of a network which has a NetworkSpecifier!");
         } catch (IllegalStateException expected) {
             // empty
         }
@@ -500,16 +500,23 @@
             // empty
         });
         NetworkCapabilities nc2 = new NetworkCapabilities();
+        // new TransportInfo so that object is not #equals to nc1's TransportInfo (that's where
+        // combine fails)
         nc2.setTransportInfo(new TransportInfo() {
             // empty
         });
 
         try {
             nc1.combineCapabilities(nc2);
-            fail("Should not be able to combine NetworkCaabilities which contain TransportInfos");
+            fail("Should not be able to combine NetworkCabilities which contain TransportInfos");
         } catch (IllegalStateException expected) {
             // empty
         }
+
+        // verify that can combine with identical TransportInfo objects
+        NetworkCapabilities nc3 = new NetworkCapabilities();
+        nc3.setTransportInfo(nc1.getTransportInfo());
+        nc1.combineCapabilities(nc3);
     }
 
     private void assertEqualsThroughMarshalling(NetworkCapabilities netCap) {
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index 9838020..151b559 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -46,6 +46,7 @@
 import android.system.ErrnoException;
 import android.system.Os;
 import android.text.format.DateUtils;
+import android.util.Log;
 import com.android.frameworks.tests.net.R;
 import com.android.internal.util.HexDump;
 import java.io.File;
@@ -89,6 +90,7 @@
         System.loadLibrary("frameworksnettestsjni");
     }
 
+    private static final String TAG = "ApfTest";
     // Expected return codes from APF interpreter.
     private static final int PASS = 1;
     private static final int DROP = 0;
@@ -869,6 +871,37 @@
         }
     }
 
+    /**
+     * Generate APF program, run pcap file though APF filter, then check all the packets in the file
+     * should be dropped.
+     */
+    @Test
+    public void testApfFilterPcapFile() throws Exception {
+        final byte[] MOCK_PCAP_IPV4_ADDR = {(byte) 172, 16, 7, (byte) 151};
+        String pcapFilename = stageFile(R.raw.apfPcap);
+        MockIpClientCallback ipClientCallback = new MockIpClientCallback();
+        LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_PCAP_IPV4_ADDR), 16);
+        LinkProperties lp = new LinkProperties();
+        lp.addLinkAddress(link);
+
+        ApfConfiguration config = getDefaultConfig();
+        ApfCapabilities MOCK_APF_PCAP_CAPABILITIES = new ApfCapabilities(4, 1700, ARPHRD_ETHER);
+        config.apfCapabilities = MOCK_APF_PCAP_CAPABILITIES;
+        config.multicastFilter = DROP_MULTICAST;
+        config.ieee802_3Filter = DROP_802_3_FRAMES;
+        TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog);
+        apfFilter.setLinkProperties(lp);
+        byte[] program = ipClientCallback.getApfProgram();
+        byte[] data = new byte[ApfFilter.Counter.totalSize()];
+        final boolean result;
+
+        result = dropsAllPackets(program, data, pcapFilename);
+        Log.i(TAG, "testApfFilterPcapFile(): Data counters: " + HexDump.toHexString(data, false));
+
+        assertTrue("Failed to drop all packets by filter. \nAPF counters:" +
+            HexDump.toHexString(data, false), result);
+    }
+
     private class MockIpClientCallback extends IpClient.Callback {
         private final ConditionVariable mGotApfProgram = new ConditionVariable();
         private byte[] mLastApfProgram;
@@ -1015,12 +1048,17 @@
             4,    // Protocol size: 4
             0, 2  // Opcode: reply (2)
     };
-    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24;
+    private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
+    private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
 
     private static final byte[] MOCK_IPV4_ADDR           = {10, 0, 0, 1};
     private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19
     private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1};
     private static final byte[] ANOTHER_IPV4_ADDR        = {10, 0, 0, 2};
+    private static final byte[] IPV4_SOURCE_ADDR         = {10, 0, 0, 3};
+    private static final byte[] ANOTHER_IPV4_SOURCE_ADDR = {(byte) 192, 0, 2, 1};
+    private static final byte[] BUG_PROBE_SOURCE_ADDR1   = {0, 0, 1, 2};
+    private static final byte[] BUG_PROBE_SOURCE_ADDR2   = {3, 4, 0, 0};
     private static final byte[] IPV4_ANY_HOST_ADDR       = {0, 0, 0, 0};
 
     // Helper to initialize a default apfFilter.
@@ -1366,10 +1404,16 @@
         assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR));
         assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR));
 
+        // Verify ARP reply packets from different source ip
+        assertDrop(program, arpReply(IPV4_ANY_HOST_ADDR, IPV4_ANY_HOST_ADDR));
+        assertPass(program, arpReply(ANOTHER_IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
+        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR1, IPV4_ANY_HOST_ADDR));
+        assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR2, IPV4_ANY_HOST_ADDR));
+
         // Verify unicast ARP reply packet is always accepted.
-        assertPass(program, arpReplyUnicast(MOCK_IPV4_ADDR));
-        assertPass(program, arpReplyUnicast(ANOTHER_IPV4_ADDR));
-        assertPass(program, arpReplyUnicast(IPV4_ANY_HOST_ADDR));
+        assertPass(program, arpReply(IPV4_SOURCE_ADDR, MOCK_IPV4_ADDR));
+        assertPass(program, arpReply(IPV4_SOURCE_ADDR, ANOTHER_IPV4_ADDR));
+        assertPass(program, arpReply(IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
 
         // Verify GARP reply packets are always filtered
         assertDrop(program, garpReply());
@@ -1398,19 +1442,20 @@
         apfFilter.shutdown();
     }
 
-    private static byte[] arpRequestBroadcast(byte[] tip) {
+    private static byte[] arpReply(byte[] sip, byte[] tip) {
         ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
         packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
         put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
+        put(packet, ARP_SOURCE_IP_ADDRESS_OFFSET, sip);
         put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
         return packet.array();
     }
 
-    private static byte[] arpReplyUnicast(byte[] tip) {
+    private static byte[] arpRequestBroadcast(byte[] tip) {
         ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
         packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
-        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
+        put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
+        put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REQUEST_HEADER);
         put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
         return packet.array();
     }
@@ -1706,6 +1751,14 @@
     private native static boolean compareBpfApf(String filter, String pcap_filename,
             byte[] apf_program);
 
+
+    /**
+     * Open packet capture file {@code pcapFilename} and run it through APF filter. Then
+     * checks whether all the packets are dropped and populates data[] {@code data} with
+     * the APF counters.
+     */
+    private native static boolean dropsAllPackets(byte[] program, byte[] data, String pcapFilename);
+
     @Test
     public void testBroadcastAddress() throws Exception {
         assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0));
diff --git a/tests/net/java/android/net/dhcp/DhcpServerTest.java b/tests/net/java/android/net/dhcp/DhcpServerTest.java
index df34c73..ab9bd84 100644
--- a/tests/net/java/android/net/dhcp/DhcpServerTest.java
+++ b/tests/net/java/android/net/dhcp/DhcpServerTest.java
@@ -25,7 +25,6 @@
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -48,7 +47,6 @@
 import android.net.dhcp.DhcpLeaseRepository.OutOfAddressesException;
 import android.net.dhcp.DhcpServer.Clock;
 import android.net.dhcp.DhcpServer.Dependencies;
-import android.net.util.InterfaceParams;
 import android.net.util.SharedLog;
 import android.os.test.TestLooper;
 import android.support.test.filters.SmallTest;
@@ -74,9 +72,6 @@
 public class DhcpServerTest {
     private static final String PROP_DEXMAKER_SHARE_CLASSLOADER = "dexmaker.share_classloader";
     private static final String TEST_IFACE = "testiface";
-    private static final MacAddress TEST_IFACE_MAC = MacAddress.fromString("11:22:33:44:55:66");
-    private static final InterfaceParams TEST_IFACEPARAMS =
-            new InterfaceParams(TEST_IFACE, 1, TEST_IFACE_MAC);
 
     private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
     private static final LinkAddress TEST_SERVER_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
@@ -149,7 +144,7 @@
                 .build();
 
         mLooper = new TestLooper();
-        mServer = new DhcpServer(mLooper.getLooper(), TEST_IFACEPARAMS, servingParams,
+        mServer = new DhcpServer(mLooper.getLooper(), TEST_IFACE, servingParams,
                 new SharedLog(DhcpServerTest.class.getSimpleName()), mDeps);
 
         mServer.start();
diff --git a/tests/net/java/android/net/ip/IpServerTest.java b/tests/net/java/android/net/ip/IpServerTest.java
index cff0b54..2c675c6 100644
--- a/tests/net/java/android/net/ip/IpServerTest.java
+++ b/tests/net/java/android/net/ip/IpServerTest.java
@@ -404,7 +404,7 @@
 
     private void assertDhcpStarted(IpPrefix expectedPrefix) {
         verify(mDependencies, times(1)).makeDhcpServer(
-                eq(mLooper.getLooper()), eq(TEST_IFACE_PARAMS), any(), eq(mSharedLog));
+                eq(mLooper.getLooper()), eq(IFACE_NAME), any(), eq(mSharedLog));
         verify(mDhcpServer, times(1)).start();
         final DhcpServingParams params = mDhcpParamsCaptor.getValue();
         // Last address byte is random
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 8081812..e6b43d2 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -71,7 +71,6 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
-import android.net.NetworkRequest;
 import android.net.NetworkState;
 import android.net.NetworkUtils;
 import android.net.RouteInfo;
@@ -130,10 +129,6 @@
     private static final String TEST_USB_IFNAME = "test_rndis0";
     private static final String TEST_WLAN_IFNAME = "test_wlan0";
 
-    // Actual contents of the request don't matter for this test. The lack of
-    // any specific TRANSPORT_* is sufficient to identify this request.
-    private static final NetworkRequest mDefaultRequest = new NetworkRequest.Builder().build();
-
     @Mock private ApplicationInfo mApplicationInfo;
     @Mock private Context mContext;
     @Mock private INetworkManagementService mNMService;
@@ -245,7 +240,7 @@
                 }
 
                 @Override
-                public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface,
+                public DhcpServer makeDhcpServer(Looper looper, String ifName,
                         DhcpServingParams params, SharedLog log) {
                     return mDhcpServer;
                 }
@@ -257,11 +252,6 @@
             isTetheringSupportedCalls++;
             return true;
         }
-
-        @Override
-        public NetworkRequest getDefaultNetworkRequest() {
-            return mDefaultRequest;
-        }
     }
 
     private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6,
@@ -496,7 +486,7 @@
                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
         verifyNoMoreInteractions(mWifiManager);
         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY);
-        verify(mUpstreamNetworkMonitor, times(1)).start(any(NetworkRequest.class));
+        verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
         // TODO: Figure out why this isn't exactly once, for sendTetherStateChangedBroadcast().
         assertTrue(1 <= mTetheringDependencies.isTetheringSupportedCalls);
 
@@ -730,7 +720,7 @@
                 TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED);
         verifyNoMoreInteractions(mWifiManager);
         verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER);
-        verify(mUpstreamNetworkMonitor, times(1)).start(any(NetworkRequest.class));
+        verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks();
         // In tethering mode, in the default configuration, an explicit request
         // for a mobile network is also made.
         verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest();
diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
index a22cbd4..0afd607 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
@@ -24,6 +24,7 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -53,7 +54,6 @@
 import android.net.NetworkRequest;
 import android.net.NetworkState;
 import android.net.util.SharedLog;
-
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -65,7 +65,6 @@
 import org.junit.runner.RunWith;
 import org.junit.Test;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
@@ -126,7 +125,7 @@
     }
 
     @Test
-    public void testDoesNothingBeforeStarted() {
+    public void testDoesNothingBeforeTrackDefaultAndStarted() throws Exception {
         assertTrue(mCM.hasNoCallbacks());
         assertFalse(mUNM.mobileNetworkRequested());
 
@@ -138,37 +137,40 @@
 
     @Test
     public void testDefaultNetworkIsTracked() throws Exception {
-        assertEquals(0, mCM.trackingDefault.size());
+        assertTrue(mCM.hasNoCallbacks());
+        mUNM.startTrackDefaultNetwork(mDefaultRequest);
 
-        mUNM.start(mDefaultRequest);
+        mUNM.startObserveAllNetworks();
         assertEquals(1, mCM.trackingDefault.size());
 
         mUNM.stop();
-        assertTrue(mCM.hasNoCallbacks());
+        assertTrue(mCM.onlyHasDefaultCallbacks());
     }
 
     @Test
     public void testListensForAllNetworks() throws Exception {
         assertTrue(mCM.listening.isEmpty());
 
-        mUNM.start(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startObserveAllNetworks();
         assertFalse(mCM.listening.isEmpty());
         assertTrue(mCM.isListeningForAll());
 
         mUNM.stop();
-        assertTrue(mCM.hasNoCallbacks());
+        assertTrue(mCM.onlyHasDefaultCallbacks());
     }
 
     @Test
     public void testCallbacksRegistered() {
-        mUNM.start(mDefaultRequest);
-        verify(mCM, times(1)).registerNetworkCallback(
-                any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class));
+        mUNM.startTrackDefaultNetwork(mDefaultRequest);
         verify(mCM, times(1)).requestNetwork(
                 eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class));
+        mUNM.startObserveAllNetworks();
+        verify(mCM, times(1)).registerNetworkCallback(
+                any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class));
 
         mUNM.stop();
-        verify(mCM, times(2)).unregisterNetworkCallback(any(NetworkCallback.class));
+        verify(mCM, times(1)).unregisterNetworkCallback(any(NetworkCallback.class));
     }
 
     @Test
@@ -176,7 +178,7 @@
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
-        mUNM.start(mDefaultRequest);
+        mUNM.startObserveAllNetworks();
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
@@ -199,11 +201,9 @@
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
-        mUNM.start(mDefaultRequest);
+        mUNM.startObserveAllNetworks();
         verify(mCM, times(1)).registerNetworkCallback(
                 any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class));
-        verify(mCM, times(1)).requestNetwork(
-                eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class));
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
@@ -227,7 +227,7 @@
         assertTrue(mCM.isDunRequested());
 
         mUNM.stop();
-        verify(mCM, times(3)).unregisterNetworkCallback(any(NetworkCallback.class));
+        verify(mCM, times(2)).unregisterNetworkCallback(any(NetworkCallback.class));
 
         verifyNoMoreInteractions(mCM);
     }
@@ -237,7 +237,7 @@
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
-        mUNM.start(mDefaultRequest);
+        mUNM.startObserveAllNetworks();
         assertFalse(mUNM.mobileNetworkRequested());
         assertEquals(0, mCM.requested.size());
 
@@ -257,7 +257,7 @@
 
     @Test
     public void testUpdateMobileRequiresDun() throws Exception {
-        mUNM.start(mDefaultRequest);
+        mUNM.startObserveAllNetworks();
 
         // Test going from no-DUN to DUN correctly re-registers callbacks.
         mUNM.updateMobileRequiresDun(false);
@@ -285,7 +285,8 @@
         final Collection<Integer> preferredTypes = new ArrayList<>();
         preferredTypes.add(TYPE_WIFI);
 
-        mUNM.start(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startObserveAllNetworks();
         // There are no networks, so there is nothing to select.
         assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
 
@@ -350,7 +351,8 @@
 
     @Test
     public void testGetCurrentPreferredUpstream() throws Exception {
-        mUNM.start(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startObserveAllNetworks();
         mUNM.updateMobileRequiresDun(false);
 
         // [0] Mobile connects, DUN not required -> mobile selected.
@@ -389,7 +391,8 @@
 
     @Test
     public void testLocalPrefixes() throws Exception {
-        mUNM.start(mDefaultRequest);
+        mUNM.startTrackDefaultNetwork(mDefaultRequest);
+        mUNM.startObserveAllNetworks();
 
         // [0] Test minimum set of local prefixes.
         Set<IpPrefix> local = mUNM.getLocalPrefixes();
@@ -521,11 +524,19 @@
         }
 
         boolean hasNoCallbacks() {
-            return allCallbacks.isEmpty() &&
-                   trackingDefault.isEmpty() &&
-                   listening.isEmpty() &&
-                   requested.isEmpty() &&
-                   legacyTypeMap.isEmpty();
+            return allCallbacks.isEmpty()
+                    && trackingDefault.isEmpty()
+                    && listening.isEmpty()
+                    && requested.isEmpty()
+                    && legacyTypeMap.isEmpty();
+        }
+
+        boolean onlyHasDefaultCallbacks() {
+            return (allCallbacks.size() == 1)
+                    && (trackingDefault.size() == 1)
+                    && listening.isEmpty()
+                    && requested.isEmpty()
+                    && legacyTypeMap.isEmpty();
         }
 
         boolean isListeningForAll() {
diff --git a/tests/net/jni/apf_jni.cpp b/tests/net/jni/apf_jni.cpp
index 1ea9e27..4222adf 100644
--- a/tests/net/jni/apf_jni.cpp
+++ b/tests/net/jni/apf_jni.cpp
@@ -21,37 +21,40 @@
 #include <stdlib.h>
 #include <string>
 #include <utils/Log.h>
+#include <vector>
 
 #include "apf_interpreter.h"
+#include "nativehelper/scoped_primitive_array.h"
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
 // JNI function acting as simply call-through to native APF interpreter.
 static jint com_android_server_ApfTest_apfSimulate(
-        JNIEnv* env, jclass, jbyteArray program, jbyteArray packet,
-        jbyteArray data, jint filter_age) {
-    uint8_t* program_raw = (uint8_t*)env->GetByteArrayElements(program, nullptr);
-    uint8_t* packet_raw = (uint8_t*)env->GetByteArrayElements(packet, nullptr);
-    uint8_t* data_raw = (uint8_t*)(data ? env->GetByteArrayElements(data, nullptr) : nullptr);
-    uint32_t program_len = env->GetArrayLength(program);
-    uint32_t packet_len = env->GetArrayLength(packet);
-    uint32_t data_len = data ? env->GetArrayLength(data) : 0;
+        JNIEnv* env, jclass, jbyteArray jprogram, jbyteArray jpacket,
+        jbyteArray jdata, jint filter_age) {
 
-    // Merge program and data into a single buffer.
-    uint8_t* program_and_data = (uint8_t*)malloc(program_len + data_len);
-    memcpy(program_and_data, program_raw, program_len);
-    memcpy(program_and_data + program_len, data_raw, data_len);
+    ScopedByteArrayRO packet(env, jpacket);
+    uint32_t packet_len = (uint32_t)packet.size();
+    uint32_t program_len = env->GetArrayLength(jprogram);
+    uint32_t data_len = jdata ? env->GetArrayLength(jdata) : 0;
+    std::vector<uint8_t> buf(program_len + data_len, 0);
+
+    env->GetByteArrayRegion(jprogram, 0, program_len, reinterpret_cast<jbyte*>(buf.data()));
+    if (jdata) {
+        // Merge program and data into a single buffer.
+        env->GetByteArrayRegion(jdata, 0, data_len,
+                                reinterpret_cast<jbyte*>(buf.data() + program_len));
+    }
 
     jint result =
-        accept_packet(program_and_data, program_len, program_len + data_len,
-                      packet_raw, packet_len, filter_age);
-    if (data) {
-        memcpy(data_raw, program_and_data + program_len, data_len);
-        env->ReleaseByteArrayElements(data, (jbyte*)data_raw, 0 /* copy back */);
+        accept_packet(buf.data(), program_len, program_len + data_len,
+                        reinterpret_cast<const uint8_t*>(packet.get()), packet_len, filter_age);
+
+    if (jdata) {
+        env->SetByteArrayRegion(jdata, 0, data_len,
+                                reinterpret_cast<jbyte*>(buf.data() + program_len));
     }
-    free(program_and_data);
-    env->ReleaseByteArrayElements(packet, (jbyte*)packet_raw, JNI_ABORT);
-    env->ReleaseByteArrayElements(program, (jbyte*)program_raw, JNI_ABORT);
+
     return result;
 }
 
@@ -118,8 +121,7 @@
         jstring jpcap_filename, jbyteArray japf_program) {
     ScopedUtfChars filter(env, jfilter);
     ScopedUtfChars pcap_filename(env, jpcap_filename);
-    uint8_t* apf_program = (uint8_t*)env->GetByteArrayElements(japf_program, NULL);
-    uint32_t apf_program_len = env->GetArrayLength(japf_program);
+    ScopedByteArrayRO apf_program(env, japf_program);
 
     // Open pcap file for BPF filtering
     ScopedFILE bpf_fp(fopen(pcap_filename.c_str(), "rb"));
@@ -161,14 +163,15 @@
         do {
             apf_packet = pcap_next(apf_pcap.get(), &apf_header);
         } while (apf_packet != NULL && !accept_packet(
-                apf_program, apf_program_len, 0 /* data_len */,
+                reinterpret_cast<uint8_t*>(const_cast<int8_t*>(apf_program.get())),
+                apf_program.size(), 0 /* data_len */,
                 apf_packet, apf_header.len, 0 /* filter_age */));
 
         // Make sure both filters matched the same packet.
         if (apf_packet == NULL && bpf_packet == NULL)
-             break;
+            break;
         if (apf_packet == NULL || bpf_packet == NULL)
-             return false;
+            return false;
         if (apf_header.len != bpf_header.len ||
                 apf_header.ts.tv_sec != bpf_header.ts.tv_sec ||
                 apf_header.ts.tv_usec != bpf_header.ts.tv_usec ||
@@ -178,6 +181,48 @@
     return true;
 }
 
+static jboolean com_android_server_ApfTest_dropsAllPackets(JNIEnv* env, jclass, jbyteArray jprogram,
+        jbyteArray jdata, jstring jpcap_filename) {
+    ScopedUtfChars pcap_filename(env, jpcap_filename);
+    ScopedByteArrayRO apf_program(env, jprogram);
+    uint32_t apf_program_len = (uint32_t)apf_program.size();
+    uint32_t data_len = env->GetArrayLength(jdata);
+    pcap_pkthdr apf_header;
+    const uint8_t* apf_packet;
+    char pcap_error[PCAP_ERRBUF_SIZE];
+    std::vector<uint8_t> buf(apf_program_len + data_len, 0);
+
+    // Merge program and data into a single buffer.
+    env->GetByteArrayRegion(jprogram, 0, apf_program_len, reinterpret_cast<jbyte*>(buf.data()));
+    env->GetByteArrayRegion(jdata, 0, data_len,
+                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
+
+    // Open pcap file
+    ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb"));
+    ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error));
+
+    if (apf_pcap.get() == NULL) {
+        throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error));
+        return false;
+    }
+
+    while ((apf_packet = pcap_next(apf_pcap.get(), &apf_header)) != NULL) {
+        int result = accept_packet(buf.data(), apf_program_len,
+                                    apf_program_len + data_len, apf_packet, apf_header.len, 0);
+
+        // Return false once packet passes the filter
+        if (result) {
+            env->SetByteArrayRegion(jdata, 0, data_len,
+                                    reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
+            return false;
+         }
+    }
+
+    env->SetByteArrayRegion(jdata, 0, data_len,
+                            reinterpret_cast<jbyte*>(buf.data() + apf_program_len));
+    return true;
+}
+
 extern "C" jint JNI_OnLoad(JavaVM* vm, void*) {
     JNIEnv *env;
     if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
@@ -192,6 +237,8 @@
                     (void*)com_android_server_ApfTest_compileToBpf },
             { "compareBpfApf", "(Ljava/lang/String;Ljava/lang/String;[B)Z",
                     (void*)com_android_server_ApfTest_compareBpfApf },
+            { "dropsAllPackets", "([B[BLjava/lang/String;)Z",
+                    (void*)com_android_server_ApfTest_dropsAllPackets },
     };
 
     jniRegisterNativeMethods(env, "android/net/apf/ApfTest",
diff --git a/tests/net/res/raw/apfPcap.pcap b/tests/net/res/raw/apfPcap.pcap
new file mode 100644
index 0000000..6f69c4a
--- /dev/null
+++ b/tests/net/res/raw/apfPcap.pcap
Binary files differ
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 39ca80b..968376b 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -78,7 +78,7 @@
 
 static uint32_t ParseFormatAttribute(const StringPiece& str) {
   uint32_t mask = 0;
-  for (StringPiece part : util::Tokenize(str, '|')) {
+  for (const StringPiece& part : util::Tokenize(str, '|')) {
     StringPiece trimmed_part = util::TrimWhitespace(part);
     uint32_t type = ParseFormatType(trimmed_part);
     if (type == 0) {
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 82d9e04..99420de 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -360,7 +360,7 @@
     return util::make_unique<BinaryPrimitive>(flags);
   }
 
-  for (StringPiece part : util::Tokenize(str, '|')) {
+  for (const StringPiece& part : util::Tokenize(str, '|')) {
     StringPiece trimmed_part = util::TrimWhitespace(part);
 
     bool flag_set = false;
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 411ad74..0b43c5d 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -486,7 +486,7 @@
     }
 
     Printer r_txt_printer(&fout_text);
-    for (const auto res : xmlres->file.exported_symbols) {
+    for (const auto& res : xmlres->file.exported_symbols) {
       r_txt_printer.Print("default int id ");
       r_txt_printer.Println(res.name.entry);
     }
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index 960880a..4c23bd3 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -230,7 +230,7 @@
                                       test::ParseConfigOrDie("fr"), test::ParseConfigOrDie("de")));
   ASSERT_TRUE(a1.android_sdk);
   ASSERT_TRUE(a1.android_sdk.value().min_sdk_version);
-  EXPECT_EQ(a1.android_sdk.value().min_sdk_version, 19l);
+  EXPECT_EQ(a1.android_sdk.value().min_sdk_version, 19L);
   EXPECT_THAT(a1.textures, SizeIs(1ul));
   EXPECT_THAT(a1.features, SizeIs(1ul));
 
@@ -250,7 +250,7 @@
                           test::ParseConfigOrDie("fr-rCA")));
   ASSERT_TRUE(a2.android_sdk);
   ASSERT_TRUE(a2.android_sdk.value().min_sdk_version);
-  EXPECT_EQ(a2.android_sdk.value().min_sdk_version, 19l);
+  EXPECT_EQ(a2.android_sdk.value().min_sdk_version, 19L);
   EXPECT_THAT(a2.textures, SizeIs(1ul));
   EXPECT_THAT(a2.features, SizeIs(1ul));
 }
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp
index 8d91b00..a4610b2 100644
--- a/tools/aapt2/java/AnnotationProcessor.cpp
+++ b/tools/aapt2/java/AnnotationProcessor.cpp
@@ -113,7 +113,7 @@
 void AnnotationProcessor::Print(Printer* printer) const {
   if (has_comments_) {
     std::string result = comment_.str();
-    for (StringPiece line : util::Tokenize(result, '\n')) {
+    for (const StringPiece& line : util::Tokenize(result, '\n')) {
       printer->Println(line);
     }
     printer->Println(" */");
diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp
index 5a8ff09..a407c22 100644
--- a/tools/aapt2/util/Files.cpp
+++ b/tools/aapt2/util/Files.cpp
@@ -165,7 +165,7 @@
 
 std::string PackageToPath(const StringPiece& package) {
   std::string out_path;
-  for (StringPiece part : util::Tokenize(package, '.')) {
+  for (const StringPiece& part : util::Tokenize(package, '.')) {
     AppendPath(&out_path, part);
   }
   return out_path;
diff --git a/tools/hiddenapi/exclude.sh b/tools/hiddenapi/exclude.sh
index 2291e5a..4ffcf68 100755
--- a/tools/hiddenapi/exclude.sh
+++ b/tools/hiddenapi/exclude.sh
@@ -11,6 +11,7 @@
   android.system \
   com.android.bouncycastle \
   com.android.conscrypt \
+  com.android.i18n.phonenumbers \
   com.android.okhttp \
   com.sun \
   dalvik \
diff --git a/tools/incident_report/printer.h b/tools/incident_report/printer.h
index ed93fa1..63e276b 100644
--- a/tools/incident_report/printer.h
+++ b/tools/incident_report/printer.h
@@ -22,7 +22,7 @@
 class Out
 {
 public:
-    Out(int fd);
+    explicit Out(int fd);
     ~Out();
 
     void printf(const char* format, ...);
diff --git a/tools/localedata/extract_icu_data.py b/tools/localedata/extract_icu_data.py
index 9dceba2..6b4c346 100755
--- a/tools/localedata/extract_icu_data.py
+++ b/tools/localedata/extract_icu_data.py
@@ -155,7 +155,7 @@
     print
     print 'std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({'
     for locale in sorted(representative_locales):
-        print '    0x%08Xllu, // %s' % (
+        print '    0x%08XLLU, // %s' % (
             pack_to_uint64(locale),
             locale)
     print '});'
diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
index 1d4c435..d368136 100644
--- a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
+++ b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
@@ -28,6 +28,7 @@
 
 import java.io.IOException;
 import java.io.PrintStream;
+import java.net.URLEncoder;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
@@ -38,7 +39,9 @@
 import javax.annotation.processing.SupportedAnnotationTypes;
 import javax.lang.model.SourceVersion;
 import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
 import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
 import javax.lang.model.element.TypeElement;
 
 /**
@@ -108,10 +111,25 @@
                 "startline",
                 "startcol",
                 "endline",
-                "endcol"
+                "endcol",
+                "properties"
         );
     }
 
+    private String encodeAnnotationProperties(AnnotationMirror annotation) {
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e
+                : annotation.getElementValues().entrySet()) {
+            if (sb.length() > 0) {
+                sb.append("&");
+            }
+            sb.append(e.getKey().getSimpleName())
+                    .append("=")
+                    .append(URLEncoder.encode(e.getValue().toString()));
+        }
+        return sb.toString();
+    }
+
     /**
      * Maps an annotated element to the source position of the @UnsupportedAppUsage annotation
      * attached to it. It returns CSV in the format:
@@ -137,7 +155,8 @@
                 lines.getLineNumber(pair.fst.pos().getStartPosition()),
                 lines.getColumnNumber(pair.fst.pos().getStartPosition()),
                 lines.getLineNumber(pair.fst.pos().getEndPosition(pair.snd.endPositions)),
-                lines.getColumnNumber(pair.fst.pos().getEndPosition(pair.snd.endPositions)));
+                lines.getColumnNumber(pair.fst.pos().getEndPosition(pair.snd.endPositions)),
+                encodeAnnotationProperties(unsupportedAppUsage));
     }
 
     /**
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index 703a67b..5725f0c 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -96,6 +96,7 @@
 
 cc_library_shared {
     name: "libstatslog",
+    host_supported: true,
     generated_sources: ["statslog.cpp"],
     generated_headers: ["statslog.h"],
     cflags: [
@@ -105,8 +106,19 @@
     export_generated_headers: ["statslog.h"],
     shared_libs: [
         "liblog",
-        "libutils",
         "libcutils",
     ],
     static_libs: ["libstatssocket"],
+    target: {
+        android: {
+            shared_libs: [
+                "libutils",
+            ],
+        },
+        host: {
+            static_libs: [
+                "libutils",
+            ],
+        },
+    },
 }
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index ebdcdfd..61174d9 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -47,7 +47,8 @@
       fields(that.fields),
       primaryFields(that.primaryFields),
       exclusiveField(that.exclusiveField),
-      uidField(that.uidField) {}
+      uidField(that.uidField),
+      binaryFields(that.binaryFields) {}
 
 AtomDecl::AtomDecl(int c, const string& n, const string& m)
     :code(c),
@@ -116,6 +117,9 @@
             if (field->message_type()->full_name() ==
                 "android.os.statsd.AttributionNode") {
               return JAVA_TYPE_ATTRIBUTION_CHAIN;
+            } else if (field->options().GetExtension(os::statsd::log_mode) ==
+                       os::statsd::LogMode::MODE_BYTES) {
+                return JAVA_TYPE_BYTE_ARRAY;
             } else {
                 return JAVA_TYPE_OBJECT;
             }
@@ -185,6 +189,8 @@
   for (map<int, const FieldDescriptor *>::const_iterator it = fields.begin();
        it != fields.end(); it++) {
     const FieldDescriptor *field = it->second;
+    bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
+                         os::statsd::LogMode::MODE_BYTES;
 
     java_type_t javaType = java_type(field);
 
@@ -198,12 +204,19 @@
                   field->name().c_str());
       errorCount++;
       continue;
-    } else if (javaType == JAVA_TYPE_BYTE_ARRAY) {
+    } else if (javaType == JAVA_TYPE_BYTE_ARRAY && !isBinaryField) {
       print_error(field, "Raw bytes type not allowed for field: %s\n",
                   field->name().c_str());
       errorCount++;
       continue;
     }
+
+    if (isBinaryField && javaType != JAVA_TYPE_BYTE_ARRAY) {
+      print_error(field, "Cannot mark field %s as bytes.\n",
+                  field->name().c_str());
+      errorCount++;
+      continue;
+    }
   }
 
   // Check that if there's an attribution chain, it's at position 1.
@@ -228,12 +241,16 @@
        it != fields.end(); it++) {
     const FieldDescriptor *field = it->second;
     java_type_t javaType = java_type(field);
+    bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
+                         os::statsd::LogMode::MODE_BYTES;
 
     AtomField atField(field->name(), javaType);
     if (javaType == JAVA_TYPE_ENUM) {
       // All enums are treated as ints when it comes to function signatures.
       signature->push_back(JAVA_TYPE_INT);
       collate_enums(*field->enum_type(), &atField);
+    } else if (javaType == JAVA_TYPE_OBJECT && isBinaryField) {
+      signature->push_back(JAVA_TYPE_BYTE_ARRAY);
     } else {
       signature->push_back(javaType);
     }
@@ -275,6 +292,10 @@
             errorCount++;
         }
     }
+    // Binary field validity is already checked above.
+    if (isBinaryField) {
+        atomDecl->binaryFields.push_back(it->first);
+    }
   }
 
   return errorCount;
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index 5d2c302..a8b270c 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -86,6 +86,8 @@
 
     int uidField = 0;
 
+    vector<int> binaryFields;
+
     AtomDecl();
     AtomDecl(const AtomDecl& that);
     AtomDecl(int code, const string& name, const string& message);
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index e519909..2478b91 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -68,6 +68,8 @@
             return "double";
         case JAVA_TYPE_STRING:
             return "char const*";
+        case JAVA_TYPE_BYTE_ARRAY:
+            return "char const*";
         default:
             return "UNKNOWN";
     }
@@ -90,6 +92,8 @@
             return "double";
         case JAVA_TYPE_STRING:
             return "java.lang.String";
+        case JAVA_TYPE_BYTE_ARRAY:
+            return "byte[]";
         default:
             return "UNKNOWN";
     }
@@ -104,7 +108,9 @@
     fprintf(out, "#include <mutex>\n");
     fprintf(out, "#include <chrono>\n");
     fprintf(out, "#include <thread>\n");
+    fprintf(out, "#ifdef __ANDROID__\n");
     fprintf(out, "#include <cutils/properties.h>\n");
+    fprintf(out, "#endif\n");
     fprintf(out, "#include <stats_event_list.h>\n");
     fprintf(out, "#include <log/log.h>\n");
     fprintf(out, "#include <statslog.h>\n");
@@ -115,7 +121,11 @@
     fprintf(out, "namespace util {\n");
     fprintf(out, "// the single event tag id for all stats logs\n");
     fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
+    fprintf(out, "#ifdef __ANDROID__\n");
     fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
+    fprintf(out, "#else\n");
+    fprintf(out, "const static bool kStatsdEnabled = false;\n");
+    fprintf(out, "#endif\n");
 
     std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed",
                                              "audio_state_changed",
@@ -200,13 +210,40 @@
     }
 
     fprintf(out, "    return options;\n");
-    fprintf(out, "  }\n");
+    fprintf(out, "}\n");
 
     fprintf(out,
             "const std::map<int, StateAtomFieldOptions> "
             "AtomsInfo::kStateAtomsFieldOptions = "
             "getStateAtomFieldOptions();\n");
 
+    fprintf(out,
+            "static std::map<int, std::vector<int>> "
+            "getBinaryFieldAtoms() {\n");
+    fprintf(out, "    std::map<int, std::vector<int>> options;\n");
+    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+         atom != atoms.decls.end(); atom++) {
+        if (atom->binaryFields.size() == 0) {
+            continue;
+        }
+        fprintf(out,
+                "\n    // Adding binary fields for atom "
+                "(%d)%s\n",
+                atom->code, atom->name.c_str());
+
+        for (const auto& field : atom->binaryFields) {
+            fprintf(out, "    options[static_cast<int>(%s)].push_back(%d);\n",
+                    make_constant_name(atom->name).c_str(), field);
+        }
+    }
+
+    fprintf(out, "    return options;\n");
+    fprintf(out, "}\n");
+
+    fprintf(out,
+            "const std::map<int, std::vector<int>> "
+            "AtomsInfo::kBytesFieldAtoms = "
+            "getBinaryFieldAtoms();\n");
 
     fprintf(out, "int64_t lastRetryTimestampNs = -1;\n");
     fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n");
@@ -235,6 +272,9 @@
                                  chainField.name.c_str(), chainField.name.c_str());
                     }
                 }
+            } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+                fprintf(out, ", %s arg%d, size_t arg%d_length",
+                        cpp_type_name(*arg), argIndex, argIndex);
             } else {
                 fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
             }
@@ -277,6 +317,10 @@
                 fprintf(out, "        event.end();\n");
                 fprintf(out, "    }\n");
                 fprintf(out, "    event.end();\n\n");
+            } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+                fprintf(out,
+                        "    event.AppendCharArray(arg%d, arg%d_length);\n",
+                        argIndex, argIndex);
             } else {
                 if (*arg == JAVA_TYPE_STRING) {
                     fprintf(out, "    if (arg%d == NULL) {\n", argIndex);
@@ -317,6 +361,9 @@
                                 chainField.name.c_str(), chainField.name.c_str());
                    }
                }
+           } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+               fprintf(out, ", %s arg%d, size_t arg%d_length",
+                       cpp_type_name(*arg), argIndex, argIndex);
            } else {
                fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
            }
@@ -343,6 +390,8 @@
                                 chainField.name.c_str(), chainField.name.c_str());
                    }
                }
+           } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+               fprintf(out, ", arg%d, arg%d_length", argIndex, argIndex);
            } else {
                fprintf(out, ", arg%d", argIndex);
            }
@@ -491,6 +540,10 @@
                          chainField.name.c_str(), chainField.name.c_str());
                 }
             }
+        } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) {
+            fprintf(out, ", %s %s, size_t %s_length",
+                    cpp_type_name(field->javaType), field->name.c_str(),
+                    field->name.c_str());
         } else {
             fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str());
         }
@@ -518,6 +571,9 @@
                             chainField.name.c_str(), chainField.name.c_str());
                     }
                 }
+            } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+                fprintf(out, ", %s arg%d, size_t arg%d_length",
+                        cpp_type_name(*arg), argIndex, argIndex);
             } else {
                 fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
             }
@@ -600,6 +656,9 @@
     fprintf(out,
             "  const static std::map<int, StateAtomFieldOptions> "
             "kStateAtomsFieldOptions;\n");
+    fprintf(out,
+            "  const static std::map<int, std::vector<int>> "
+            "kBytesFieldAtoms;");
     fprintf(out, "};\n");
 
     fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n",
@@ -632,6 +691,8 @@
         field != atom.fields.end(); field++) {
         if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
             fprintf(out, ", android.os.WorkSource workSource");
+        } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) {
+            fprintf(out, ", byte[] %s", field->name.c_str());
         } else {
             fprintf(out, ", %s %s", java_type_name(field->javaType), field->name.c_str());
         }
@@ -821,6 +882,8 @@
             return "jdouble";
         case JAVA_TYPE_STRING:
             return "jstring";
+        case JAVA_TYPE_BYTE_ARRAY:
+            return "jbyteArray";
         default:
             return "UNKNOWN";
     }
@@ -868,6 +931,9 @@
             case JAVA_TYPE_ATTRIBUTION_CHAIN:
               result += "_AttributionChain";
               break;
+            case JAVA_TYPE_BYTE_ARRAY:
+                result += "_bytes";
+                break;
             default:
                 result += "_UNKNOWN";
                 break;
@@ -893,6 +959,8 @@
             return "D";
         case JAVA_TYPE_STRING:
             return "Ljava/lang/String;";
+        case JAVA_TYPE_BYTE_ARRAY:
+            return "[B";
         default:
             return "UNKNOWN";
     }
@@ -960,6 +1028,32 @@
                 fprintf(out, "    } else {\n");
                 fprintf(out, "        str%d = NULL;\n", argIndex);
                 fprintf(out, "    }\n");
+            } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+                hadStringOrChain = true;
+                fprintf(out, "    jbyte* jbyte_array%d;\n", argIndex);
+                fprintf(out, "    const char* str%d;\n", argIndex);
+                fprintf(out, "    int str%d_length = 0;\n", argIndex);
+                fprintf(out,
+                        "    if (arg%d != NULL && env->GetArrayLength(arg%d) > "
+                        "0) {\n",
+                        argIndex, argIndex);
+                fprintf(out,
+                        "        jbyte_array%d = "
+                        "env->GetByteArrayElements(arg%d, NULL);\n",
+                        argIndex, argIndex);
+                fprintf(out,
+                        "        str%d_length = env->GetArrayLength(arg%d);\n",
+                        argIndex, argIndex);
+                fprintf(out,
+                        "        str%d = "
+                        "reinterpret_cast<char*>(env->GetByteArrayElements(arg%"
+                        "d, NULL));\n",
+                        argIndex, argIndex);
+                fprintf(out, "    } else {\n");
+                fprintf(out, "        jbyte_array%d = NULL;\n", argIndex);
+                fprintf(out, "        str%d = NULL;\n", argIndex);
+                fprintf(out, "    }\n");
+
             } else if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 hadStringOrChain = true;
                 for (auto chainField : attributionDecl.fields) {
@@ -1026,8 +1120,15 @@
                     }
                 }
             } else {
-                const char *argName = (*arg == JAVA_TYPE_STRING) ? "str" : "arg";
+                const char* argName = (*arg == JAVA_TYPE_STRING ||
+                                       *arg == JAVA_TYPE_BYTE_ARRAY)
+                                              ? "str"
+                                              : "arg";
                 fprintf(out, ", (%s)%s%d", cpp_type_name(*arg), argName, argIndex);
+
+                if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+                    fprintf(out, ", %s%d_length", argName, argIndex);
+                }
             }
             argIndex++;
         }
@@ -1043,6 +1144,13 @@
                 fprintf(out, "        env->ReleaseStringUTFChars(arg%d, str%d);\n",
                         argIndex, argIndex);
                 fprintf(out, "    }\n");
+            } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+                fprintf(out, "    if (str%d != NULL) { \n", argIndex);
+                fprintf(out,
+                        "        env->ReleaseByteArrayElements(arg%d, "
+                        "jbyte_array%d, 0);\n",
+                        argIndex, argIndex);
+                fprintf(out, "    }\n");
             } else if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 for (auto chainField : attributionDecl.fields) {
                     if (chainField.javaType == JAVA_TYPE_INT) {
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index 264a865..188b765 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -109,6 +109,28 @@
   oneof event { BadAttributionNodePositionAtom bad = 1; }
 }
 
+message GoodEventWithBinaryFieldAtom {
+    oneof event { GoodBinaryFieldAtom field1 = 1; }
+}
+
+message ComplexField {
+    optional string str = 1;
+}
+
+message GoodBinaryFieldAtom {
+    optional int32 field1 = 1;
+    optional ComplexField bf = 2 [(android.os.statsd.log_mode) = MODE_BYTES];
+}
+
+message BadEventWithBinaryFieldAtom {
+    oneof event { BadBinaryFieldAtom field1 = 1; }
+}
+
+message BadBinaryFieldAtom {
+    optional int32 field1 = 1;
+    optional ComplexField bf = 2;
+}
+
 message BadStateAtoms {
     oneof event {
         BadStateAtom1 bad1 = 1;
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index 1936d96..ad3bffac 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -212,5 +212,19 @@
     EXPECT_EQ(0, errorCount);
 }
 
+TEST(CollationTest, PassOnGoodBinaryFieldAtom) {
+    Atoms atoms;
+    int errorCount =
+            collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), &atoms);
+    EXPECT_EQ(0, errorCount);
+}
+
+TEST(CollationTest, FailOnBadBinaryFieldAtom) {
+    Atoms atoms;
+    int errorCount =
+            collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), &atoms);
+    EXPECT_TRUE(errorCount > 0);
+}
+
 }  // namespace stats_log_api_gen
 }  // namespace android
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index 66c1a3c..17847ea 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -954,16 +954,15 @@
      * for Hotspot 2.0 defined matching of AAA server certs per WFA HS2.0 spec, section 7.3.3.2,
      * second paragraph.
      *
-     * From wpa_supplicant documentation:
-     * Constraint for server domain name. If set, this FQDN is used as a suffix match requirement
+     * <p>From wpa_supplicant documentation:
+     * <p>Constraint for server domain name. If set, this FQDN is used as a suffix match requirement
      * for the AAAserver certificate in SubjectAltName dNSName element(s). If a matching dNSName is
-     * found, this constraint is met. If no dNSName values are present, this constraint is matched
-     * against SubjectName CN using same suffix match comparison.
-     * Suffix match here means that the host/domain name is compared one label at a time starting
+     * found, this constraint is met.
+     * <p>Suffix match here means that the host/domain name is compared one label at a time starting
      * from the top-level domain and all the labels in domain_suffix_match shall be included in the
      * certificate. The certificate may include additional sub-level labels in addition to the
      * required labels.
-     * For example, domain_suffix_match=example.com would match test.example.com but would not
+     * <p>For example, domain_suffix_match=example.com would match test.example.com but would not
      * match test-example.com.
      * @param domain The domain value
      */
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 15e092b..2aed2de0 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -1550,7 +1550,6 @@
     /**
      * @return true if this adapter supports Device-to-AP RTT
      */
-    @SystemApi
     public boolean isDeviceToApRttSupported() {
         return isFeatureSupported(WIFI_FEATURE_D2AP_RTT);
     }