Merge "API Review: ServiceState.isSearching documentation"
diff --git a/Android.bp b/Android.bp
index a211d26..feaafa3 100644
--- a/Android.bp
+++ b/Android.bp
@@ -526,7 +526,6 @@
     host_supported: true,
     srcs: [
         "core/java/android/annotation/IntDef.java",
-        "core/java/android/annotation/UnsupportedAppUsage.java",
     ],
     static_libs: [
         "art.module.api.annotations",
@@ -552,7 +551,7 @@
 genrule {
     name: "framework-statslog-gen",
     tools: ["stats-log-api-gen"],
-    cmd: "$(location stats-log-api-gen) --java $(out)",
+    cmd: "$(location stats-log-api-gen) --java $(out) --worksource",
     out: ["android/util/StatsLogInternal.java"],
 }
 
@@ -591,7 +590,6 @@
         "core/java/android/annotation/IntDef.java",
         "core/java/android/annotation/IntRange.java",
         "core/java/android/annotation/SystemApi.java",
-        "core/java/android/annotation/UnsupportedAppUsage.java",
         "core/java/com/android/internal/annotations/GuardedBy.java",
         "core/java/com/android/internal/annotations/VisibleForTesting.java",
     ],
@@ -662,6 +660,7 @@
         "core/java/android/annotation/RequiresPermission.java",
         "core/java/android/annotation/SystemApi.java",
         "core/java/android/annotation/TestApi.java",
+        "core/java/com/android/internal/annotations/GuardedBy.java",
     ],
 }
 // Build ext.jar
@@ -927,7 +926,6 @@
         "core/java/android/annotation/Nullable.java",
         "core/java/android/annotation/SystemApi.java",
         "core/java/android/annotation/TestApi.java",
-        "core/java/android/annotation/UnsupportedAppUsage.java",
         "core/java/android/os/HidlMemory.java",
         "core/java/android/os/HwBinder.java",
         "core/java/android/os/HwBlob.java",
@@ -994,7 +992,6 @@
         "core/java/android/annotation/StringDef.java",
         "core/java/android/annotation/SystemApi.java",
         "core/java/android/annotation/TestApi.java",
-        "core/java/android/annotation/UnsupportedAppUsage.java",
         "core/java/com/android/internal/annotations/GuardedBy.java",
     ],
 }
diff --git a/StubLibraries.bp b/StubLibraries.bp
index baa3c61..442df6f 100644
--- a/StubLibraries.bp
+++ b/StubLibraries.bp
@@ -336,7 +336,7 @@
 }
 
 java_library_static {
-    name: "framework_module_app_stubs_current",
+    name: "android_module_app_stubs_current",
     srcs: [
         ":module-app-api-stubs-docs",
     ],
@@ -351,7 +351,7 @@
 }
 
 java_library_static {
-    name: "framework_module_lib_stubs_current",
+    name: "android_module_lib_stubs_current",
     srcs: [
         ":module-lib-api-stubs-docs",
     ],
diff --git a/api/current.txt b/api/current.txt
index d4bba5d..ce28b95 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -37319,6 +37319,7 @@
     field public static final int FEATURES_PULLED_EXTERNALLY = 2; // 0x2
     field public static final int FEATURES_RTT = 32; // 0x20
     field public static final int FEATURES_VIDEO = 1; // 0x1
+    field public static final int FEATURES_VOLTE = 64; // 0x40
     field public static final int FEATURES_WIFI = 8; // 0x8
     field public static final String GEOCODED_LOCATION = "geocoded_location";
     field public static final int INCOMING_TYPE = 1; // 0x1
@@ -44701,6 +44702,7 @@
     field public static final String KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrp_thresholds_int_array";
     field public static final String KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY = "5g_nr_ssrsrq_thresholds_int_array";
     field public static final String KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY = "5g_nr_sssinr_thresholds_int_array";
+    field public static final String KEY_5G_WATCHDOG_TIME_MS_LONG = "5g_watchdog_time_long";
     field public static final String KEY_ADDITIONAL_CALL_SETTING_BOOL = "additional_call_setting_bool";
     field public static final String KEY_ALLOW_ADDING_APNS_BOOL = "allow_adding_apns_bool";
     field public static final String KEY_ALLOW_ADD_CALL_DURING_VIDEO_CALL_BOOL = "allow_add_call_during_video_call";
@@ -44784,6 +44786,7 @@
     field public static final String KEY_DATA_LIMIT_NOTIFICATION_BOOL = "data_limit_notification_bool";
     field public static final String KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG = "data_limit_threshold_bytes_long";
     field public static final String KEY_DATA_RAPID_NOTIFICATION_BOOL = "data_rapid_notification_bool";
+    field public static final String KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG = "data_switch_validation_timeout_long";
     field public static final String KEY_DATA_WARNING_NOTIFICATION_BOOL = "data_warning_notification_bool";
     field public static final String KEY_DATA_WARNING_THRESHOLD_BYTES_LONG = "data_warning_threshold_bytes_long";
     field public static final String KEY_DEFAULT_SIM_CALL_MANAGER_STRING = "default_sim_call_manager_string";
@@ -44866,6 +44869,8 @@
     field public static final String KEY_ONLY_AUTO_SELECT_IN_HOME_NETWORK_BOOL = "only_auto_select_in_home_network";
     field public static final String KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY = "only_single_dc_allowed_int_array";
     field public static final String KEY_OPERATOR_SELECTION_EXPAND_BOOL = "operator_selection_expand_bool";
+    field public static final String KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG = "opportunistic_network_backoff_time_long";
+    field public static final String KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG = "opportunistic_network_data_switch_exit_hysteresis_time_long";
     field public static final String KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG = "opportunistic_network_data_switch_hysteresis_time_long";
     field public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_OR_EXIT_HYSTERESIS_TIME_LONG = "opportunistic_network_entry_or_exit_hysteresis_time_long";
     field public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_BANDWIDTH_INT = "opportunistic_network_entry_threshold_bandwidth_int";
@@ -44873,6 +44878,9 @@
     field public static final String KEY_OPPORTUNISTIC_NETWORK_ENTRY_THRESHOLD_RSSNR_INT = "opportunistic_network_entry_threshold_rssnr_int";
     field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT = "opportunistic_network_exit_threshold_rsrp_int";
     field public static final String KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT = "opportunistic_network_exit_threshold_rssnr_int";
+    field public static final String KEY_OPPORTUNISTIC_NETWORK_MAX_BACKOFF_TIME_LONG = "opportunistic_network_max_backoff_time_long";
+    field public static final String KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG = "opportunistic_network_ping_pong_time_long";
+    field public static final String KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL = "ping_test_before_data_switch_bool";
     field public static final String KEY_PREFER_2G_BOOL = "prefer_2g_bool";
     field public static final String KEY_PREVENT_CLIR_ACTIVATION_AND_DEACTIVATION_CODE_BOOL = "prevent_clir_activation_and_deactivation_code_bool";
     field public static final String KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY = "radio_restart_failure_causes_int_array";
@@ -44909,6 +44917,7 @@
     field public static final String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
     field public static final String KEY_SUPPORT_TDSCDMA_BOOL = "support_tdscdma_bool";
     field public static final String KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY = "support_tdscdma_roaming_networks_string_array";
+    field public static final String KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL = "switch_data_to_primary_if_primary_is_oos_bool";
     field public static final String KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL = "treat_downgraded_video_calls_as_video_calls_bool";
     field public static final String KEY_TTY_SUPPORTED_BOOL = "tty_supported_bool";
     field public static final String KEY_UNLOGGABLE_NUMBERS_STRING_ARRAY = "unloggable_numbers_string_array";
diff --git a/api/system-current.txt b/api/system-current.txt
index ca98fc5..b60d321 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -226,6 +226,7 @@
 
   public static final class R.array {
     field public static final int config_keySystemUuidMapping = 17235973; // 0x1070005
+    field public static final int simColors = 17235974; // 0x1070006
   }
 
   public static final class R.attr {
@@ -1423,7 +1424,7 @@
   }
 
   public final class BluetoothHidDevice implements android.bluetooth.BluetoothProfile {
-    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
+    method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
   }
 
   public final class BluetoothHidHost implements android.bluetooth.BluetoothProfile {
@@ -4537,6 +4538,27 @@
     field public final int netId;
   }
 
+  public abstract class NetworkAgent {
+    method public void onAddKeepalivePacketFilter(int, @NonNull android.net.KeepalivePacketData);
+    method public void onAutomaticReconnectDisabled();
+    method public void onBandwidthUpdateRequested();
+    method public void onNetworkUnwanted();
+    method public void onRemoveKeepalivePacketFilter(int);
+    method public void onSaveAcceptUnvalidated(boolean);
+    method public void onSignalStrengthThresholdsUpdated(@NonNull int[]);
+    method public void onStartSocketKeepalive(int, int, @NonNull android.net.KeepalivePacketData);
+    method public void onStopSocketKeepalive(int);
+    method public void onValidationStatus(int, @Nullable String);
+    method public void sendLinkProperties(@NonNull android.net.LinkProperties);
+    method public void sendNetworkCapabilities(@NonNull android.net.NetworkCapabilities);
+    method public void sendNetworkScore(int);
+    method public void sendSocketKeepaliveEvent(int, int);
+    field public static final int VALIDATION_STATUS_NOT_VALID = 2; // 0x2
+    field public static final int VALIDATION_STATUS_VALID = 1; // 0x1
+    field @NonNull public final android.net.Network network;
+    field public final int providerId;
+  }
+
   public final class NetworkAgentConfig implements android.os.Parcelable {
     method public int describeContents();
     method @Nullable public String getSubscriberId();
@@ -5649,6 +5671,7 @@
   public class WifiInfo implements android.os.Parcelable {
     method public boolean isOsuAp();
     method public boolean isPasspointAp();
+    method @Nullable public static String sanitizeSsid(@Nullable String);
   }
 
   public class WifiManager {
@@ -8410,6 +8433,27 @@
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallAttributes> CREATOR;
   }
 
+  public final class CallForwardingInfo implements android.os.Parcelable {
+    ctor public CallForwardingInfo(int, int, @Nullable String, int);
+    method public int describeContents();
+    method @Nullable public String getNumber();
+    method public int getReason();
+    method public int getStatus();
+    method public int getTimeoutSeconds();
+    field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CallForwardingInfo> CREATOR;
+    field public static final int REASON_ALL = 4; // 0x4
+    field public static final int REASON_ALL_CONDITIONAL = 5; // 0x5
+    field public static final int REASON_BUSY = 1; // 0x1
+    field public static final int REASON_NOT_REACHABLE = 3; // 0x3
+    field public static final int REASON_NO_REPLY = 2; // 0x2
+    field public static final int REASON_UNCONDITIONAL = 0; // 0x0
+    field public static final int STATUS_ACTIVE = 1; // 0x1
+    field public static final int STATUS_FDN_CHECK_FAILURE = 2; // 0x2
+    field public static final int STATUS_INACTIVE = 0; // 0x0
+    field public static final int STATUS_NOT_SUPPORTED = 4; // 0x4
+    field public static final int STATUS_UNKNOWN_ERROR = 3; // 0x3
+  }
+
   public final class CallQuality implements android.os.Parcelable {
     ctor public CallQuality(int, int, int, int, int, int, int, int, int, int, int);
     method public int describeContents();
@@ -9117,9 +9161,9 @@
     field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
     field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
     field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
-    field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
     field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
-    field public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
+    field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
   }
 
   public final class PreciseCallState implements android.os.Parcelable {
@@ -9486,6 +9530,8 @@
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getAllowedNetworkTypes();
+    method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CallForwardingInfo getCallForwarding(int);
+    method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getCallWaitingStatus();
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
     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);
@@ -9556,6 +9602,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void reportDefaultNetworkStatus(boolean);
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
+    method public void requestModemActivityInfo(@NonNull android.os.ResultReceiver);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetAllCarrierActions();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
@@ -9565,12 +9612,15 @@
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setAllowedNetworkTypes(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAlwaysReportSignalStrength(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallForwarding(@NonNull android.telephony.CallForwardingInfo);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setCallWaitingStatus(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setCarrierRestrictionRules(@NonNull android.telephony.CarrierRestrictionRules);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataActivationState(int);
     method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataEnabled(int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDataRoamingEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setMultiSimCarrierRestriction(boolean);
+    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(@NonNull String, int, boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setOpportunisticNetworkState(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setPreferredNetworkTypeBitmask(long);
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setRadio(boolean);
@@ -9595,6 +9645,10 @@
     field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
     field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
     field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
+    field public static final int CALL_WAITING_STATUS_ACTIVE = 1; // 0x1
+    field public static final int CALL_WAITING_STATUS_INACTIVE = 2; // 0x2
+    field public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4; // 0x4
+    field public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3; // 0x3
     field public static final int CARD_POWER_DOWN = 0; // 0x0
     field public static final int CARD_POWER_UP = 1; // 0x1
     field public static final int CARD_POWER_UP_PASS_THROUGH = 2; // 0x2
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index d908388..88d94cc 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -75,9 +75,9 @@
     // Pushed atoms start at 2.
     oneof pushed {
         // For StatsLog reasons, 1 is illegal and will not work. Must start at 2.
-        BleScanStateChanged ble_scan_state_changed = 2;
+        BleScanStateChanged ble_scan_state_changed = 2 [(log_from_module) = "bluetooth"];
         ProcessStateChanged process_state_changed = 3;
-        BleScanResultReceived ble_scan_result_received = 4;
+        BleScanResultReceived ble_scan_result_received = 4 [(log_from_module) = "bluetooth"];
         SensorStateChanged sensor_state_changed = 5;
         GpsScanStateChanged gps_scan_state_changed = 6;
         SyncStateChanged sync_state_changed = 7;
@@ -141,7 +141,8 @@
         AppDied app_died = 65;
         ResourceConfigurationChanged resource_configuration_changed = 66;
         BluetoothEnabledStateChanged bluetooth_enabled_state_changed = 67;
-        BluetoothConnectionStateChanged bluetooth_connection_state_changed = 68;
+        BluetoothConnectionStateChanged bluetooth_connection_state_changed =
+                68 [(log_from_module) = "bluetooth"];
         GpsSignalQualityChanged gps_signal_quality_changed = 69;
         UsbConnectorStateChanged usb_connector_state_changed = 70;
         SpeakerImpedanceReported speaker_impedance_reported = 71;
@@ -216,9 +217,12 @@
         RescuePartyResetReported rescue_party_reset_reported = 122;
         SignedConfigReported signed_config_reported = 123;
         GnssNiEventReported gnss_ni_event_reported = 124;
-        BluetoothLinkLayerConnectionEvent bluetooth_link_layer_connection_event = 125;
-        BluetoothAclConnectionStateChanged bluetooth_acl_connection_state_changed = 126;
-        BluetoothScoConnectionStateChanged bluetooth_sco_connection_state_changed = 127;
+        BluetoothLinkLayerConnectionEvent bluetooth_link_layer_connection_event =
+                125 [(log_from_module) = "bluetooth"];
+        BluetoothAclConnectionStateChanged bluetooth_acl_connection_state_changed =
+                126 [(log_from_module) = "bluetooth"];
+        BluetoothScoConnectionStateChanged bluetooth_sco_connection_state_changed =
+                127 [(log_from_module) = "bluetooth"];
         AppDowngraded app_downgraded = 128;
         AppOptimizedAfterDowngraded app_optimized_after_downgraded = 129;
         LowStorageStateChanged low_storage_state_changed = 130;
@@ -242,23 +246,40 @@
         BiometricSystemHealthIssueDetected biometric_system_health_issue_detected = 148;
         BubbleUIChanged bubble_ui_changed = 149;
         ScheduledJobConstraintChanged scheduled_job_constraint_changed = 150;
-        BluetoothActiveDeviceChanged bluetooth_active_device_changed = 151;
-        BluetoothA2dpPlaybackStateChanged bluetooth_a2dp_playback_state_changed = 152;
-        BluetoothA2dpCodecConfigChanged bluetooth_a2dp_codec_config_changed = 153;
-        BluetoothA2dpCodecCapabilityChanged bluetooth_a2dp_codec_capability_changed = 154;
-        BluetoothA2dpAudioUnderrunReported bluetooth_a2dp_audio_underrun_reported = 155;
-        BluetoothA2dpAudioOverrunReported bluetooth_a2dp_audio_overrun_reported = 156;
-        BluetoothDeviceRssiReported bluetooth_device_rssi_reported = 157;
-        BluetoothDeviceFailedContactCounterReported bluetooth_device_failed_contact_counter_reported = 158;
-        BluetoothDeviceTxPowerLevelReported bluetooth_device_tx_power_level_reported = 159;
-        BluetoothHciTimeoutReported bluetooth_hci_timeout_reported = 160;
-        BluetoothQualityReportReported bluetooth_quality_report_reported = 161;
-        BluetoothDeviceInfoReported bluetooth_device_info_reported = 162;
-        BluetoothRemoteVersionInfoReported bluetooth_remote_version_info_reported = 163;
-        BluetoothSdpAttributeReported bluetooth_sdp_attribute_reported = 164;
-        BluetoothBondStateChanged bluetooth_bond_state_changed = 165;
-        BluetoothClassicPairingEventReported bluetooth_classic_pairing_event_reported = 166;
-        BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167;
+        BluetoothActiveDeviceChanged bluetooth_active_device_changed =
+                151 [(log_from_module) = "bluetooth"];
+        BluetoothA2dpPlaybackStateChanged bluetooth_a2dp_playback_state_changed =
+                152 [(log_from_module) = "bluetooth"];
+        BluetoothA2dpCodecConfigChanged bluetooth_a2dp_codec_config_changed =
+                153 [(log_from_module) = "bluetooth"];
+        BluetoothA2dpCodecCapabilityChanged bluetooth_a2dp_codec_capability_changed =
+                154 [(log_from_module) = "bluetooth"];
+        BluetoothA2dpAudioUnderrunReported bluetooth_a2dp_audio_underrun_reported =
+                155 [(log_from_module) = "bluetooth"];
+        BluetoothA2dpAudioOverrunReported bluetooth_a2dp_audio_overrun_reported =
+                156 [(log_from_module) = "bluetooth"];
+        BluetoothDeviceRssiReported bluetooth_device_rssi_reported =
+                157 [(log_from_module) = "bluetooth"];
+        BluetoothDeviceFailedContactCounterReported
+                bluetooth_device_failed_contact_counter_reported = 158 [(log_from_module) = "bluetooth"];
+        BluetoothDeviceTxPowerLevelReported bluetooth_device_tx_power_level_reported =
+                159 [(log_from_module) = "bluetooth"];
+        BluetoothHciTimeoutReported bluetooth_hci_timeout_reported =
+                160 [(log_from_module) = "bluetooth"];
+        BluetoothQualityReportReported bluetooth_quality_report_reported =
+                161 [(log_from_module) = "bluetooth"];
+        BluetoothDeviceInfoReported bluetooth_device_info_reported =
+                162 [(log_from_module) = "bluetooth"];
+        BluetoothRemoteVersionInfoReported bluetooth_remote_version_info_reported =
+                163 [(log_from_module) = "bluetooth"];
+        BluetoothSdpAttributeReported bluetooth_sdp_attribute_reported =
+                164 [(log_from_module) = "bluetooth"];
+        BluetoothBondStateChanged bluetooth_bond_state_changed =
+                165 [(log_from_module) = "bluetooth"];
+        BluetoothClassicPairingEventReported bluetooth_classic_pairing_event_reported =
+                166 [(log_from_module) = "bluetooth"];
+        BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported =
+                167 [(log_from_module) = "bluetooth"];
         ScreenTimeoutExtensionReported screen_timeout_extension_reported = 168;
         ProcessStartTime process_start_time = 169;
         PermissionGrantRequestResultReported permission_grant_request_result_reported =
@@ -280,7 +301,8 @@
         BiometricEnrolled biometric_enrolled = 184;
         SystemServerWatchdogOccurred system_server_watchdog_occurred = 185;
         TombStoneOccurred tomb_stone_occurred = 186;
-        BluetoothClassOfDeviceReported bluetooth_class_of_device_reported = 187;
+        BluetoothClassOfDeviceReported bluetooth_class_of_device_reported =
+                187 [(log_from_module) = "bluetooth"];
         IntelligenceEventReported intelligence_event_reported =
             188 [(log_from_module) = "intelligence"];
         ThermalThrottlingSeverityStateChanged thermal_throttling_severity_state_changed = 189;
@@ -6237,7 +6259,8 @@
     optional bool is_preinstalled = 3;
 
     // True if the package is privileged.
-    optional bool is_priv_app = 4;
+    // Starting from Android 11, this boolean is not set and will always be false.
+    optional bool is_priv_app = 4 [deprecated = true];
 }
 
 /**
diff --git a/core/java/android/annotation/UnsupportedAppUsage.java b/core/java/android/annotation/UnsupportedAppUsage.java
deleted file mode 100644
index 1af48cb..0000000
--- a/core/java/android/annotation/UnsupportedAppUsage.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.CLASS;
-
-import java.lang.annotation.Repeatable;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * 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.
- *
- * <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. Which apps can access
- * the member is determined by the value of {@link #maxTargetSdk()}.
- *
- * <p>For more details, see go/UnsupportedAppUsage.
- *
- * {@hide}
- */
-@Retention(CLASS)
-@Target({CONSTRUCTOR, METHOD, FIELD, TYPE})
-@Repeatable(UnsupportedAppUsage.Container.class)
-public @interface UnsupportedAppUsage {
-
-    /**
-     * Associates a bug tracking the work to add a public alternative to this API. Optional.
-     *
-     * @return ID of the associated tracking bug
-     */
-    long trackingBug() default 0;
-
-    /**
-     * Indicates that usage of this API is limited to apps based on their target SDK version.
-     *
-     * <p>Access to the API is allowed if the targetSdkVersion in the apps manifest is no greater
-     * than this value. Access checks are performed at runtime.
-     *
-     * <p>This is used to give app developers a grace period to migrate off a non-SDK interface.
-     * When making Android version N, existing APIs can have a maxTargetSdk of N-1 added to them.
-     * Developers must then migrate off the API when their app is updated in future, but it will
-     * continue working in the meantime.
-     *
-     * <p>Possible values are:
-     * <ul>
-     *     <li>
-     *         An API level like {@link android.os.Build.VERSION_CODES#O} - in which case the API is
-     *         available up to and including the specified release. Or, in other words, the API is
-     *         blacklisted (unavailable) from the next API level from the one specified.
-     *     </li>
-     *     <li>
-     *         absent (default value) - All apps can access this API, but doing so may result in
-     *         warnings in the log, UI warnings (on developer builds) and/or strictmode violations.
-     *         The API is likely to be further restricted in future.
-     *     </li>
-     *
-     * </ul>
-     *
-     * @return The maximum value for an apps targetSdkVersion in order to access this API.
-     */
-    int maxTargetSdk() default Integer.MAX_VALUE;
-
-    /**
-     * For debug use only. The expected dex signature to be generated for this API, used to verify
-     * parts of the build process.
-     *
-     * @return A dex API signature.
-     */
-    String expectedSignature() default "";
-
-    /**
-     * The signature of an implicit (not present in the source) member that forms part of the
-     * hiddenapi.
-     *
-     * <p>Allows access to non-SDK API elements that are not represented in the input source to be
-     * managed.
-     *
-     * <p>This must only be used when applying the annotation to a type, using it in any other
-     * situation is an error.
-     *
-     * @return A dex API signature.
-     */
-    String implicitMember() default "";
-
-    /**
-     * Public API alternatives to this API.
-     *
-     * <p>If non-empty, the string must be a description of the public API alternative(s) to this
-     * API. The explanation must contain at least one Javadoc link tag to public API methods or
-     * fields. e.g.:
-     * {@literal @UnsupportedAppUsage(publicAlternatives="Use {@link foo.bar.Baz#bat()} instead.")}
-     *
-     * <p>Any elements that can be deduced can be omitted, e.g.:
-     * <ul>
-     *      <li>
-     *          the class, if it's the same as for the annotated element.
-     *      </li>
-     *      <li>
-     *          the package name, if it's the same as for the annotated element.
-     *      </li>
-     *      <li>
-     *          the method parameters, if there is only one method with that name in the given
-     *          package and class.
-     *      </li>
-     * </ul>
-     * @return A Javadoc-formatted string.
-     */
-    @SuppressWarnings("JavadocReference")
-    String publicAlternatives() default "";
-
-    /**
-     * Override the default source position when generating an index of the annotations.
-     *
-     * <p>This is intended for use by tools that generate java source code, to point to the
-     * original source position of the annotation, rather than the position within the generated
-     * code. It should never be set manually.
-     *
-     * <p>The format of the value is "path/to/file:startline:startcol:endline:endcol" indicating
-     * the position of the annotation itself.
-     */
-    String overrideSourcePosition() default "";
-
-    /**
-     * Container for {@link UnsupportedAppUsage} that allows it to be applied repeatedly to types.
-     */
-    @Retention(CLASS)
-    @Target(TYPE)
-    @interface Container {
-        UnsupportedAppUsage[] value();
-    }
-}
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 2e14446..86b2c06 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -356,11 +356,9 @@
         registerService(Context.TETHERING_SERVICE, TetheringManager.class,
                 new CachedServiceFetcher<TetheringManager>() {
             @Override
-            public TetheringManager createService(ContextImpl ctx) throws ServiceNotFoundException {
-                IBinder b = ServiceManager.getService(Context.TETHERING_SERVICE);
-                if (b == null) return null;
-
-                return new TetheringManager(ctx, b);
+            public TetheringManager createService(ContextImpl ctx) {
+                return new TetheringManager(
+                        ctx, () -> ServiceManager.getService(Context.TETHERING_SERVICE));
             }});
 
 
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 8415ecd..b6d096c 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -2162,6 +2162,33 @@
     }
 
     /**
+     * Fetches a list of the most recently connected bluetooth devices ordered by how recently they
+     * were connected with most recently first and least recently last
+     *
+     * @return {@link List} of bonded {@link BluetoothDevice} ordered by how recently they were
+     * connected
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    public @NonNull List<BluetoothDevice> getMostRecentlyConnectedDevices() {
+        if (getState() != STATE_ON) {
+            return new ArrayList<>();
+        }
+        try {
+            mServiceLock.readLock().lock();
+            if (mService != null) {
+                return mService.getMostRecentlyConnectedDevices();
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "", e);
+        } finally {
+            mServiceLock.readLock().unlock();
+        }
+        return new ArrayList<>();
+    }
+
+    /**
      * Return the set of {@link BluetoothDevice} objects that are bonded
      * (paired) to the local adapter.
      * <p>If Bluetooth state is not {@link #STATE_ON}, this API
diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java
index a923be6..b5959c0 100644
--- a/core/java/android/bluetooth/BluetoothHidDevice.java
+++ b/core/java/android/bluetooth/BluetoothHidDevice.java
@@ -706,7 +706,7 @@
      * @hide
      */
     @SystemApi
-    @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
+    @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
     public boolean setConnectionPolicy(@NonNull BluetoothDevice device,
             @ConnectionPolicy int connectionPolicy) {
         log("setConnectionPolicy(" + device + ", " + connectionPolicy + ")");
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 7316dfa..aae9fd4 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -17,6 +17,8 @@
 package android.net;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
@@ -43,7 +45,12 @@
  *
  * @hide
  */
+@SystemApi
 public abstract class NetworkAgent {
+    /**
+     * The {@link Network} corresponding to this object.
+     */
+    @NonNull
     public final Network network;
 
     private final Handler mHandler;
@@ -55,9 +62,14 @@
     private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
     private volatile long mLastBwRefreshTime = 0;
     private static final long BW_REFRESH_MIN_WIN_MS = 500;
-    private boolean mPollLceScheduled = false;
-    private AtomicBoolean mPollLcePending = new AtomicBoolean(false);
-    public final int mProviderId;
+    private boolean mBandwidthUpdateScheduled = false;
+    private AtomicBoolean mBandwidthUpdatePending = new AtomicBoolean(false);
+
+    /**
+     * The ID of the {@link NetworkProvider} that created this object, or
+     * {@link NetworkProvider#ID_NONE} if unknown.
+     */
+    public final int providerId;
 
     private static final int BASE = Protocol.BASE_NETWORK_AGENT;
 
@@ -65,6 +77,7 @@
      * Sent by ConnectivityService to the NetworkAgent to inform it of
      * suspected connectivity problems on its network.  The NetworkAgent
      * should take steps to verify and correct connectivity.
+     * @hide
      */
     public static final int CMD_SUSPECT_BAD = BASE;
 
@@ -73,6 +86,7 @@
      * ConnectivityService to pass the current NetworkInfo (connection state).
      * Sent when the NetworkInfo changes, mainly due to change of state.
      * obj = NetworkInfo
+     * @hide
      */
     public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1;
 
@@ -80,6 +94,7 @@
      * Sent by the NetworkAgent to ConnectivityService to pass the current
      * NetworkCapabilties.
      * obj = NetworkCapabilities
+     * @hide
      */
     public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2;
 
@@ -87,11 +102,14 @@
      * Sent by the NetworkAgent to ConnectivityService to pass the current
      * NetworkProperties.
      * obj = NetworkProperties
+     * @hide
      */
     public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
 
-    /* centralize place where base network score, and network score scaling, will be
+    /**
+     * Centralize the place where base network score, and network score scaling, will be
      * stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE
+     * @hide
      */
     public static final int WIFI_BASE_SCORE = 60;
 
@@ -99,6 +117,7 @@
      * Sent by the NetworkAgent to ConnectivityService to pass the current
      * network score.
      * obj = network score Integer
+     * @hide
      */
     public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
 
@@ -111,12 +130,33 @@
      * obj = Bundle containing map from {@code REDIRECT_URL_KEY} to {@code String}
      *       representing URL that Internet probe was redirect to, if it was redirected,
      *       or mapping to {@code null} otherwise.
+     * @hide
      */
     public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7;
 
+
+    /**
+     * Network validation suceeded.
+     * Corresponds to {@link NetworkCapabilities.NET_CAPABILITY_VALIDATED}.
+     */
+    public static final int VALIDATION_STATUS_VALID = 1;
+
+    /**
+     * Network validation was attempted and failed. This may be received more than once as
+     * subsequent validation attempts are made.
+     */
+    public static final int VALIDATION_STATUS_NOT_VALID = 2;
+
+    // TODO: remove.
+    /** @hide */
     public static final int VALID_NETWORK = 1;
+    /** @hide */
     public static final int INVALID_NETWORK = 2;
 
+    /**
+     * The key for the redirect URL in the Bundle argument of {@code CMD_REPORT_NETWORK_STATUS}.
+     * @hide
+     */
     public static String REDIRECT_URL_KEY = "redirect URL";
 
      /**
@@ -125,6 +165,7 @@
      * CONNECTED so it can be given special treatment at that time.
      *
      * obj = boolean indicating whether to use this network even if unvalidated
+     * @hide
      */
     public static final int EVENT_SET_EXPLICITLY_SELECTED = BASE + 8;
 
@@ -135,12 +176,14 @@
      * responsibility to remember it.
      *
      * arg1 = 1 if true, 0 if false
+     * @hide
      */
     public static final int CMD_SAVE_ACCEPT_UNVALIDATED = BASE + 9;
 
     /**
      * Sent by ConnectivityService to the NetworkAgent to inform the agent to pull
      * the underlying network connection for updated bandwidth information.
+     * @hide
      */
     public static final int CMD_REQUEST_BANDWIDTH_UPDATE = BASE + 10;
 
@@ -153,6 +196,7 @@
      *   obj = KeepalivePacketData object describing the data to be sent
      *
      * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
+     * @hide
      */
     public static final int CMD_START_SOCKET_KEEPALIVE = BASE + 11;
 
@@ -162,6 +206,7 @@
      * arg1 = slot number of the keepalive to stop.
      *
      * Also used internally by ConnectivityService / KeepaliveTracker, with different semantics.
+     * @hide
      */
     public static final int CMD_STOP_SOCKET_KEEPALIVE = BASE + 12;
 
@@ -175,6 +220,7 @@
      *
      * arg1 = slot number of the keepalive
      * arg2 = error code
+     * @hide
      */
     public static final int EVENT_SOCKET_KEEPALIVE = BASE + 13;
 
@@ -183,6 +229,7 @@
      * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
      *
      *   obj = int[] describing signal strength thresholds.
+     * @hide
      */
     public static final int CMD_SET_SIGNAL_STRENGTH_THRESHOLDS = BASE + 14;
 
@@ -190,6 +237,7 @@
      * Sent by ConnectivityService to the NeworkAgent to inform the agent to avoid
      * automatically reconnecting to this network (e.g. via autojoin).  Happens
      * when user selects "No" option on the "Stay connected?" dialog box.
+     * @hide
      */
     public static final int CMD_PREVENT_AUTOMATIC_RECONNECT = BASE + 15;
 
@@ -202,6 +250,7 @@
      * This does not happen with UDP, so this message is TCP-specific.
      * arg1 = slot number of the keepalive to filter for.
      * obj = the keepalive packet to send repeatedly.
+     * @hide
      */
     public static final int CMD_ADD_KEEPALIVE_PACKET_FILTER = BASE + 16;
 
@@ -209,6 +258,7 @@
      * Sent by the KeepaliveTracker to NetworkAgent to remove a packet filter. See
      * {@link #CMD_ADD_KEEPALIVE_PACKET_FILTER}.
      * arg1 = slot number of the keepalive packet filter to remove.
+     * @hide
      */
     public static final int CMD_REMOVE_KEEPALIVE_PACKET_FILTER = BASE + 17;
 
@@ -216,27 +266,32 @@
     // of dependent changes that would conflict throughout the automerger graph. Having these
     // temporarily helps with the process of going through with all these dependent changes across
     // the entire tree.
+    /** @hide TODO: decide which of these to expose. */
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score) {
         this(looper, context, logTag, ni, nc, lp, score, null, NetworkProvider.ID_NONE);
     }
+
+    /** @hide TODO: decide which of these to expose. */
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config) {
         this(looper, context, logTag, ni, nc, lp, score, config, NetworkProvider.ID_NONE);
     }
 
+    /** @hide TODO: decide which of these to expose. */
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, int providerId) {
         this(looper, context, logTag, ni, nc, lp, score, null, providerId);
     }
 
+    /** @hide TODO: decide which of these to expose. */
     public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
             NetworkCapabilities nc, LinkProperties lp, int score, NetworkAgentConfig config,
             int providerId) {
         mHandler = new NetworkAgentHandler(looper);
         LOG_TAG = logTag;
         mContext = context;
-        mProviderId = providerId;
+        this.providerId = providerId;
         if (ni == null || nc == null || lp == null) {
             throw new IllegalArgumentException();
         }
@@ -284,7 +339,7 @@
                 case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
                     if (DBG) log("NetworkAgent channel lost");
                     // let the client know CS is done with us.
-                    unwanted();
+                    onNetworkUnwanted();
                     synchronized (mPreConnectedQueue) {
                         mAsyncChannel = null;
                     }
@@ -300,16 +355,16 @@
                         log("CMD_REQUEST_BANDWIDTH_UPDATE request received.");
                     }
                     if (currentTimeMs >= (mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS)) {
-                        mPollLceScheduled = false;
-                        if (!mPollLcePending.getAndSet(true)) {
-                            pollLceData();
+                        mBandwidthUpdateScheduled = false;
+                        if (!mBandwidthUpdatePending.getAndSet(true)) {
+                            onBandwidthUpdateRequested();
                         }
                     } else {
                         // deliver the request at a later time rather than discard it completely.
-                        if (!mPollLceScheduled) {
+                        if (!mBandwidthUpdateScheduled) {
                             long waitTime = mLastBwRefreshTime + BW_REFRESH_MIN_WIN_MS
                                     - currentTimeMs + 1;
-                            mPollLceScheduled = sendEmptyMessageDelayed(
+                            mBandwidthUpdateScheduled = sendEmptyMessageDelayed(
                                     CMD_REQUEST_BANDWIDTH_UPDATE, waitTime);
                         }
                     }
@@ -322,19 +377,20 @@
                                 + (msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ")
                                 + redirectUrl);
                     }
-                    networkStatus(msg.arg1, redirectUrl);
+                    onValidationStatus(msg.arg1 /* status */, redirectUrl);
                     break;
                 }
                 case CMD_SAVE_ACCEPT_UNVALIDATED: {
-                    saveAcceptUnvalidated(msg.arg1 != 0);
+                    onSaveAcceptUnvalidated(msg.arg1 != 0);
                     break;
                 }
                 case CMD_START_SOCKET_KEEPALIVE: {
-                    startSocketKeepalive(msg);
+                    onStartSocketKeepalive(msg.arg1 /* slot */, msg.arg2 /* interval */,
+                            (KeepalivePacketData) msg.obj /* packet */);
                     break;
                 }
                 case CMD_STOP_SOCKET_KEEPALIVE: {
-                    stopSocketKeepalive(msg);
+                    onStopSocketKeepalive(msg.arg1 /* slot */);
                     break;
                 }
 
@@ -347,19 +403,20 @@
                     for (int i = 0; i < intThresholds.length; i++) {
                         intThresholds[i] = thresholds.get(i);
                     }
-                    setSignalStrengthThresholds(intThresholds);
+                    onSignalStrengthThresholdsUpdated(intThresholds);
                     break;
                 }
                 case CMD_PREVENT_AUTOMATIC_RECONNECT: {
-                    preventAutomaticReconnect();
+                    onAutomaticReconnectDisabled();
                     break;
                 }
                 case CMD_ADD_KEEPALIVE_PACKET_FILTER: {
-                    addKeepalivePacketFilter(msg);
+                    onAddKeepalivePacketFilter(msg.arg1 /* slot */,
+                            (KeepalivePacketData) msg.obj /* packet */);
                     break;
                 }
                 case CMD_REMOVE_KEEPALIVE_PACKET_FILTER: {
-                    removeKeepalivePacketFilter(msg);
+                    onRemoveKeepalivePacketFilter(msg.arg1 /* slot */);
                     break;
                 }
             }
@@ -394,14 +451,16 @@
     }
 
     /**
-     * Called by the bearer code when it has new LinkProperties data.
+     * Must be called by the agent when the network's {@link LinkProperties} change.
+     * @param linkProperties the new LinkProperties.
      */
-    public void sendLinkProperties(LinkProperties linkProperties) {
+    public void sendLinkProperties(@NonNull LinkProperties linkProperties) {
         queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties));
     }
 
     /**
-     * Called by the bearer code when it has new NetworkInfo data.
+     * Must be called by the agent when it has a new NetworkInfo object.
+     * @hide TODO: expose something better.
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public void sendNetworkInfo(NetworkInfo networkInfo) {
@@ -409,17 +468,19 @@
     }
 
     /**
-     * Called by the bearer code when it has new NetworkCapabilities data.
+     * Must be called by the agent when the network's {@link NetworkCapabilities} change.
+     * @param networkCapabilities the new NetworkCapabilities.
      */
-    public void sendNetworkCapabilities(NetworkCapabilities networkCapabilities) {
-        mPollLcePending.set(false);
+    public void sendNetworkCapabilities(@NonNull NetworkCapabilities networkCapabilities) {
+        mBandwidthUpdatePending.set(false);
         mLastBwRefreshTime = System.currentTimeMillis();
         queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
                 new NetworkCapabilities(networkCapabilities));
     }
 
     /**
-     * Called by the bearer code when it has a new score for this network.
+     * Must be called by the agent to update the score of this network.
+     * @param score the new score.
      */
     public void sendNetworkScore(int score) {
         if (score < 0) {
@@ -431,14 +492,16 @@
     }
 
     /**
-     * Called by the bearer code when it has a new NetworkScore for this network.
+     * Must be called by the agent when it has a new {@link NetworkScore} for this network.
+     * @param ns the new score.
+     * @hide TODO: unhide the NetworkScore class, and rename to sendNetworkScore.
      */
     public void updateScore(@NonNull NetworkScore ns) {
         queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new NetworkScore(ns));
     }
 
     /**
-     * Called by the bearer to indicate this network was manually selected by the user.
+     * Must be called by the agent to indicate this network was manually selected by the user.
      * This should be called before the NetworkInfo is marked CONNECTED so that this
      * Network can be given special treatment at that time. If {@code acceptUnvalidated} is
      * {@code true}, then the system will switch to this network. If it is {@code false} and the
@@ -447,15 +510,16 @@
      * {@link #saveAcceptUnvalidated} to persist the user's choice. Thus, if the transport ever
      * calls this method with {@code acceptUnvalidated} set to {@code false}, it must also implement
      * {@link #saveAcceptUnvalidated} to respect the user's choice.
+     * @hide should move to NetworkAgentConfig.
      */
     public void explicitlySelected(boolean acceptUnvalidated) {
         explicitlySelected(true /* explicitlySelected */, acceptUnvalidated);
     }
 
     /**
-     * Called by the bearer to indicate whether the network was manually selected by the user.
-     * This should be called before the NetworkInfo is marked CONNECTED so that this
-     * Network can be given special treatment at that time.
+     * Must be called by the agent to indicate whether the network was manually selected by the
+     * user. This should be called before the network becomes connected, so it can be given
+     * special treatment when it does.
      *
      * If {@code explicitlySelected} is {@code true}, and {@code acceptUnvalidated} is {@code true},
      * then the system will switch to this network. If {@code explicitlySelected} is {@code true}
@@ -470,6 +534,7 @@
      * {@code true}, the system will interpret this as the user having accepted partial connectivity
      * on this network. Thus, the system will switch to the network and consider it validated even
      * if it only provides partial connectivity, but the network is not otherwise treated specially.
+     * @hide should move to NetworkAgentConfig.
      */
     public void explicitlySelected(boolean explicitlySelected, boolean acceptUnvalidated) {
         queueOrSendMessage(EVENT_SET_EXPLICITLY_SELECTED,
@@ -483,73 +548,126 @@
      * as well, either canceling NetworkRequests or altering their score such that this
      * network won't be immediately requested again.
      */
-    abstract protected void unwanted();
+    public void onNetworkUnwanted() {
+        unwanted();
+    }
+    /** @hide TODO delete once subclasses have moved to onNetworkUnwanted. */
+    protected void unwanted() {
+    }
 
     /**
      * Called when ConnectivityService request a bandwidth update. The parent factory
      * shall try to overwrite this method and produce a bandwidth update if capable.
      */
+    public void onBandwidthUpdateRequested() {
+        pollLceData();
+    }
+    /** @hide TODO delete once subclasses have moved to onBandwidthUpdateRequested. */
     protected void pollLceData() {
     }
 
     /**
      * Called when the system determines the usefulness of this network.
      *
-     * Networks claiming internet connectivity will have their internet
-     * connectivity verified.
+     * The system attempts to validate Internet connectivity on networks that provide the
+     * {@link NetworkCapabilities#NET_CAPABILITY_INTERNET} capability.
      *
      * Currently there are two possible values:
-     * {@code VALID_NETWORK} if the system is happy with the connection,
-     * {@code INVALID_NETWORK} if the system is not happy.
-     * TODO - add indications of captive portal-ness and related success/failure,
-     * ie, CAPTIVE_SUCCESS_NETWORK, CAPTIVE_NETWORK for successful login and detection
+     * {@code VALIDATION_STATUS_VALID} if Internet connectivity was validated,
+     * {@code VALIDATION_STATUS_NOT_VALID} if Internet connectivity was not validated.
      *
-     * This may be called multiple times as the network status changes and may
-     * generate false negatives if we lose ip connectivity before the link is torn down.
+     * This may be called multiple times as network status changes, or if there are multiple
+     * subsequent attempts to validate connectivity that fail.
      *
-     * @param status one of {@code VALID_NETWORK} or {@code INVALID_NETWORK}.
-     * @param redirectUrl If the Internet probe was redirected, this is the destination it was
-     *         redirected to, otherwise {@code null}.
+     * @param status one of {@code VALIDATION_STATUS_VALID} or {@code VALIDATION_STATUS_NOT_VALID}.
+     * @param redirectUrl If Internet connectivity is being redirected (e.g., on a captive portal),
+     *        this is the destination the probes are being redirected to, otherwise {@code null}.
      */
+    public void onValidationStatus(int status, @Nullable String redirectUrl) {
+        networkStatus(status, redirectUrl);
+    }
+    /** @hide TODO delete once subclasses have moved to onValidationStatus */
     protected void networkStatus(int status, String redirectUrl) {
     }
 
+
     /**
      * Called when the user asks to remember the choice to use this network even if unvalidated.
      * The transport is responsible for remembering the choice, and the next time the user connects
      * to the network, should explicitlySelected with {@code acceptUnvalidated} set to {@code true}.
      * This method will only be called if {@link #explicitlySelected} was called with
      * {@code acceptUnvalidated} set to {@code false}.
+     * @param accept whether the user wants to use the network even if unvalidated.
      */
+    public void onSaveAcceptUnvalidated(boolean accept) {
+        saveAcceptUnvalidated(accept);
+    }
+    /** @hide TODO delete once subclasses have moved to onSaveAcceptUnvalidated */
     protected void saveAcceptUnvalidated(boolean accept) {
     }
 
     /**
      * Requests that the network hardware send the specified packet at the specified interval.
+     *
+     * @param slot the hardware slot on which to start the keepalive.
+     * @param intervalSeconds the interval between packets
+     * @param packet the packet to send.
      */
+    public void onStartSocketKeepalive(int slot, int intervalSeconds,
+            @NonNull KeepalivePacketData packet) {
+        Message msg = mHandler.obtainMessage(CMD_START_SOCKET_KEEPALIVE, slot, intervalSeconds,
+                packet);
+        startSocketKeepalive(msg);
+        msg.recycle();
+    }
+    /** @hide TODO delete once subclasses have moved to onStartSocketKeepalive */
     protected void startSocketKeepalive(Message msg) {
         onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
     }
 
     /**
-     * Requests that the network hardware send the specified packet at the specified interval.
+     * Requests that the network hardware stop a previously-started keepalive.
+     *
+     * @param slot the hardware slot on which to stop the keepalive.
      */
+    public void onStopSocketKeepalive(int slot) {
+        Message msg = mHandler.obtainMessage(CMD_STOP_SOCKET_KEEPALIVE, slot, 0, null);
+        stopSocketKeepalive(msg);
+        msg.recycle();
+    }
+    /** @hide TODO delete once subclasses have moved to onStopSocketKeepalive */
     protected void stopSocketKeepalive(Message msg) {
         onSocketKeepaliveEvent(msg.arg1, SocketKeepalive.ERROR_UNSUPPORTED);
     }
 
     /**
-     * Called by the network when a socket keepalive event occurs.
+     * Must be called by the agent when a socket keepalive event occurs.
+     *
+     * @param slot the hardware slot on which the event occurred.
+     * @param event the event that occurred.
      */
+    public void sendSocketKeepaliveEvent(int slot, int event) {
+        queueOrSendMessage(EVENT_SOCKET_KEEPALIVE, slot, event);
+    }
+    /** @hide TODO delete once callers have moved to sendSocketKeepaliveEvent */
     public void onSocketKeepaliveEvent(int slot, int reason) {
-        queueOrSendMessage(EVENT_SOCKET_KEEPALIVE, slot, reason);
+        sendSocketKeepaliveEvent(slot, reason);
     }
 
     /**
      * Called by ConnectivityService to add specific packet filter to network hardware to block
-     * ACKs matching the sent keepalive packets. Implementations that support this feature must
-     * override this method.
+     * replies (e.g., TCP ACKs) matching the sent keepalive packets. Implementations that support
+     * this feature must override this method.
+     *
+     * @param slot the hardware slot on which the keepalive should be sent.
+     * @param packet the packet that is being sent.
      */
+    public void onAddKeepalivePacketFilter(int slot, @NonNull KeepalivePacketData packet) {
+        Message msg = mHandler.obtainMessage(CMD_ADD_KEEPALIVE_PACKET_FILTER, slot, 0, packet);
+        addKeepalivePacketFilter(msg);
+        msg.recycle();
+    }
+    /** @hide TODO delete once subclasses have moved to onAddKeepalivePacketFilter */
     protected void addKeepalivePacketFilter(Message msg) {
     }
 
@@ -557,14 +675,28 @@
      * Called by ConnectivityService to remove a packet filter installed with
      * {@link #addKeepalivePacketFilter(Message)}. Implementations that support this feature
      * must override this method.
+     *
+     * @param slot the hardware slot on which the keepalive is being sent.
      */
+    public void onRemoveKeepalivePacketFilter(int slot) {
+        Message msg = mHandler.obtainMessage(CMD_REMOVE_KEEPALIVE_PACKET_FILTER, slot, 0, null);
+        removeKeepalivePacketFilter(msg);
+        msg.recycle();
+    }
+    /** @hide TODO delete once subclasses have moved to onRemoveKeepalivePacketFilter */
     protected void removeKeepalivePacketFilter(Message msg) {
     }
 
     /**
      * Called by ConnectivityService to inform this network transport of signal strength thresholds
      * that when crossed should trigger a system wakeup and a NetworkCapabilities update.
+     *
+     * @param thresholds the array of thresholds that should trigger wakeups.
      */
+    public void onSignalStrengthThresholdsUpdated(@NonNull int[] thresholds) {
+        setSignalStrengthThresholds(thresholds);
+    }
+    /** @hide TODO delete once subclasses have moved to onSetSignalStrengthThresholds */
     protected void setSignalStrengthThresholds(int[] thresholds) {
     }
 
@@ -574,9 +706,14 @@
      * responsible for making sure the device does not automatically reconnect to the same network
      * after the {@code unwanted} call.
      */
+    public void onAutomaticReconnectDisabled() {
+        preventAutomaticReconnect();
+    }
+    /** @hide TODO delete once subclasses have moved to onAutomaticReconnectDisabled */
     protected void preventAutomaticReconnect() {
     }
 
+    /** @hide */
     protected void log(String s) {
         Log.d(LOG_TAG, "NetworkAgent: " + s);
     }
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index de962f8..d1c1329 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -367,12 +367,12 @@
     }
 
     public static String resolveNetworkId(WifiConfiguration config) {
-        return WifiInfo.removeDoubleQuotes(config.isPasspoint()
+        return WifiInfo.sanitizeSsid(config.isPasspoint()
                 ? config.providerFriendlyName : config.SSID);
     }
 
     public static String resolveNetworkId(String ssid) {
-        return WifiInfo.removeDoubleQuotes(ssid);
+        return WifiInfo.sanitizeSsid(ssid);
     }
 
     /** {@hide} */
diff --git a/core/java/android/net/NetworkTemplate.java b/core/java/android/net/NetworkTemplate.java
index 5e6c47a..5498f74 100644
--- a/core/java/android/net/NetworkTemplate.java
+++ b/core/java/android/net/NetworkTemplate.java
@@ -32,7 +32,7 @@
 import static android.net.NetworkStats.ROAMING_ALL;
 import static android.net.NetworkStats.ROAMING_NO;
 import static android.net.NetworkStats.ROAMING_YES;
-import static android.net.wifi.WifiInfo.removeDoubleQuotes;
+import static android.net.wifi.WifiInfo.sanitizeSsid;
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
@@ -401,7 +401,7 @@
         switch (ident.mType) {
             case TYPE_WIFI:
                 return Objects.equals(
-                        removeDoubleQuotes(mNetworkId), removeDoubleQuotes(ident.mNetworkId));
+                        sanitizeSsid(mNetworkId), sanitizeSsid(ident.mNetworkId));
             default:
                 return false;
         }
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index 9ffeff9..a0e92b3 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -232,6 +232,9 @@
         /** Call was on RTT at some point */
         public static final int FEATURES_RTT = 1 << 5;
 
+        /** Call was VoLTE */
+        public static final int FEATURES_VOLTE = 1 << 6;
+
         /**
          * The phone number as the user entered it.
          * <P>Type: TEXT</P>
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 03e7361..4591faf 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -168,9 +168,11 @@
     public static final int LISTEN_SIGNAL_STRENGTHS                         = 0x00000100;
 
     /**
-     * Listen for always reported changes of the network signal strengths (cellular),
+     * Listen for changes of the network signal strengths (cellular) always reported from modem,
      * even in some situations such as the screen of the device is off.
      *
+     * @see #onSignalStrengthsChanged
+     *
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
@@ -225,6 +227,9 @@
 
     /**
      * Listen for changes to the SRVCC state of the active call.
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
+     *
      * @see #onServiceStateChanged(ServiceState)
      * @hide
      */
@@ -253,6 +258,9 @@
 
     /**
      * Listen for changes to the sim voice activation state
+     *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
+     *
      * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATING
      * @see TelephonyManager#SIM_ACTIVATION_STATE_ACTIVATED
      * @see TelephonyManager#SIM_ACTIVATION_STATE_DEACTIVATED
@@ -266,6 +274,7 @@
      * @hide
      */
     @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public static final int LISTEN_VOICE_ACTIVATION_STATE                   = 0x00020000;
 
     /**
@@ -312,10 +321,13 @@
     /**
      *  Listen for changes to the radio power state.
      *
+     * <p>Requires permission {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
+     *
      *  @see #onRadioPowerStateChanged
      *  @hide
      */
     @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public static final int LISTEN_RADIO_POWER_STATE_CHANGED               = 0x00800000;
 
     /**
@@ -893,7 +905,6 @@
      * Callback invoked when phone capability changes.
      * Note, this callback triggers regardless of registered subscription.
      *
-     * Requires the READ_PRIVILEGED_PHONE_STATE permission.
      * @param capability the new phone capability
      * @hide
      */
@@ -923,7 +934,7 @@
      * subId. Otherwise, this callback applies to
      * {@link SubscriptionManager#getDefaultSubscriptionId()}.
      *
-     * Requires the READ_PRIVILEGED_PHONE_STATE permission.
+     * Requires the READ_PRECISE_PHONE_STATE permission.
      * @param callAttributes the call attributes
      * @hide
      */
diff --git a/core/java/android/timezone/CountryTimeZones.java b/core/java/android/timezone/CountryTimeZones.java
index e5bbdf4..5875761 100644
--- a/core/java/android/timezone/CountryTimeZones.java
+++ b/core/java/android/timezone/CountryTimeZones.java
@@ -56,7 +56,7 @@
          */
         @NonNull
         public String getTimeZoneId() {
-            return mDelegate.timeZoneId;
+            return mDelegate.getTimeZoneId();
         }
 
         /**
@@ -187,7 +187,7 @@
      * would be a good choice <em>generally</em> when there's no other information available.
      */
     public boolean isDefaultTimeZoneBoosted() {
-        return mDelegate.getDefaultTimeZoneBoost();
+        return mDelegate.isDefaultTimeZoneBoosted();
     }
 
     /**
@@ -220,7 +220,8 @@
                 mDelegate.lookupByOffsetWithBias(
                         totalOffsetMillis, isDst, dstOffsetMillis, whenMillis, bias);
         return delegateOffsetResult == null ? null :
-                new OffsetResult(delegateOffsetResult.mTimeZone, delegateOffsetResult.mOneMatch);
+                new OffsetResult(
+                        delegateOffsetResult.getTimeZone(), delegateOffsetResult.isOnlyMatch());
     }
 
     /**
diff --git a/core/java/android/timezone/TzDataSetVersion.java b/core/java/android/timezone/TzDataSetVersion.java
index 605155e..efe50a0 100644
--- a/core/java/android/timezone/TzDataSetVersion.java
+++ b/core/java/android/timezone/TzDataSetVersion.java
@@ -111,23 +111,23 @@
 
     /** Returns the major version number. See {@link TzDataSetVersion}. */
     public int getFormatMajorVersion() {
-        return mDelegate.formatMajorVersion;
+        return mDelegate.getFormatMajorVersion();
     }
 
     /** Returns the minor version number. See {@link TzDataSetVersion}. */
     public int getFormatMinorVersion() {
-        return mDelegate.formatMinorVersion;
+        return mDelegate.getFormatMinorVersion();
     }
 
     /** Returns the tzdb version string. See {@link TzDataSetVersion}. */
     @NonNull
     public String getRulesVersion() {
-        return mDelegate.rulesVersion;
+        return mDelegate.getRulesVersion();
     }
 
     /** Returns the Android revision. See {@link TzDataSetVersion}. */
     public int getRevision() {
-        return mDelegate.revision;
+        return mDelegate.getRevision();
     }
 
     @Override
diff --git a/core/java/android/util/TimeUtils.java b/core/java/android/util/TimeUtils.java
index a8a579c..de5b027f 100644
--- a/core/java/android/util/TimeUtils.java
+++ b/core/java/android/util/TimeUtils.java
@@ -80,7 +80,7 @@
         }
         CountryTimeZones.OffsetResult offsetResult = countryTimeZones.lookupByOffsetWithBias(
                 offsetMillis, isDst, null /* dstOffsetMillis */, whenMillis, bias);
-        return offsetResult != null ? offsetResult.mTimeZone : null;
+        return offsetResult != null ? offsetResult.getTimeZone() : null;
     }
 
     /**
@@ -108,8 +108,8 @@
 
         List<String> timeZoneIds = new ArrayList<>();
         for (TimeZoneMapping timeZoneMapping : countryTimeZones.getTimeZoneMappings()) {
-            if (timeZoneMapping.showInPicker) {
-                timeZoneIds.add(timeZoneMapping.timeZoneId);
+            if (timeZoneMapping.isShownInPicker()) {
+                timeZoneIds.add(timeZoneMapping.getTimeZoneId());
             }
         }
         return Collections.unmodifiableList(timeZoneIds);
diff --git a/core/java/com/android/internal/util/LocationPermissionChecker.java b/core/java/com/android/internal/util/LocationPermissionChecker.java
index dc318b4..f05eb7e 100644
--- a/core/java/com/android/internal/util/LocationPermissionChecker.java
+++ b/core/java/com/android/internal/util/LocationPermissionChecker.java
@@ -17,6 +17,7 @@
 package com.android.internal.util;
 
 import android.Manifest;
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
@@ -26,11 +27,13 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 
 /**
  * The methods used for location permission and location mode checking.
@@ -41,17 +44,27 @@
 
     private static final String TAG = "LocationPermissionChecker";
 
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"LOCATION_PERMISSION_CHECK_STATUS_"}, value = {
+        SUCCEEDED,
+        ERROR_LOCATION_MODE_OFF,
+        ERROR_LOCATION_PERMISSION_MISSING,
+    })
+    public @interface LocationPermissionCheckStatus{}
+
+    // The location permission check succeeded.
+    public static final int SUCCEEDED = 0;
+    // The location mode turns off for the caller.
+    public static final int ERROR_LOCATION_MODE_OFF = 1;
+    // The location permission isn't granted for the caller.
+    public static final int ERROR_LOCATION_PERMISSION_MISSING = 2;
+
     private final Context mContext;
     private final AppOpsManager mAppOpsManager;
-    private final UserManager mUserManager;
-    private final LocationManager mLocationManager;
 
     public LocationPermissionChecker(Context context) {
         mContext = context;
         mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
-        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        mLocationManager =
-            (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
     }
 
     /**
@@ -71,12 +84,38 @@
      */
     public boolean checkLocationPermission(String pkgName, @Nullable String featureId,
             int uid, @Nullable String message) {
-        try {
-            enforceLocationPermission(pkgName, featureId, uid, message);
-            return true;
-        } catch (SecurityException e) {
-            return false;
+        return checkLocationPermissionInternal(pkgName, featureId, uid, message) == SUCCEEDED;
+    }
+
+    /**
+     * Check location permission granted by the caller.
+     *
+     * This API check if the location mode enabled for the caller and the caller has
+     * ACCESS_COARSE_LOCATION permission is targetSDK<29, otherwise, has ACCESS_FINE_LOCATION.
+     * Compared with {@link #checkLocationPermission(String, String, int, String)}, this API returns
+     * the detail information about the checking result, including the reason why it's failed and
+     * logs the error for the caller.
+     *
+     * @param pkgName package name of the application requesting access
+     * @param featureId The feature in the package
+     * @param uid The uid of the package
+     * @param message A message describing why the permission was checked. Only needed if this is
+     *                not inside of a two-way binder call from the data receiver
+     *
+     * @return {@link LocationPermissionCheckStatus} the result of the location permission check.
+     */
+    public @LocationPermissionCheckStatus int checkLocationPermissionWithDetailInfo(
+            String pkgName, @Nullable String featureId, int uid, @Nullable String message) {
+        final int result = checkLocationPermissionInternal(pkgName, featureId, uid, message);
+        switch (result) {
+            case ERROR_LOCATION_MODE_OFF:
+                Log.e(TAG, "Location mode is disabled for the device");
+                break;
+            case ERROR_LOCATION_PERMISSION_MISSING:
+                Log.e(TAG, "UID " + uid + " has no location permission");
+                break;
         }
+        return result;
     }
 
     /**
@@ -94,20 +133,32 @@
      */
     public void enforceLocationPermission(String pkgName, @Nullable String featureId, int uid,
             @Nullable String message) throws SecurityException {
+        final int result = checkLocationPermissionInternal(pkgName, featureId, uid, message);
 
+        switch (result) {
+            case ERROR_LOCATION_MODE_OFF:
+                throw new SecurityException("Location mode is disabled for the device");
+            case ERROR_LOCATION_PERMISSION_MISSING:
+                throw new SecurityException("UID " + uid + " has no location permission");
+        }
+    }
+
+    private int checkLocationPermissionInternal(String pkgName, @Nullable String featureId,
+            int uid, @Nullable String message) {
         checkPackage(uid, pkgName);
 
         // Location mode must be enabled
         if (!isLocationModeEnabled()) {
-            throw new SecurityException("Location mode is disabled for the device");
+            return ERROR_LOCATION_MODE_OFF;
         }
 
         // LocationAccess by App: caller must have Coarse/Fine Location permission to have access to
         // location information.
-        if (!checkCallersLocationPermission(pkgName, featureId,
-                uid, /* coarseForTargetSdkLessThanQ */ true, message)) {
-            throw new SecurityException("UID " + uid + " has no location permission");
+        if (!checkCallersLocationPermission(pkgName, featureId, uid,
+                true /* coarseForTargetSdkLessThanQ */, message)) {
+            return ERROR_LOCATION_PERMISSION_MISSING;
         }
+        return SUCCEEDED;
     }
 
     /**
@@ -155,8 +206,10 @@
      * Retrieves a handle to LocationManager (if not already done) and check if location is enabled.
      */
     public boolean isLocationModeEnabled() {
+        final LocationManager LocationManager =
+                (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
         try {
-            return mLocationManager.isLocationEnabledForUser(UserHandle.of(
+            return LocationManager.isLocationEnabledForUser(UserHandle.of(
                     getCurrentUser()));
         } catch (Exception e) {
             Log.e(TAG, "Failure to get location mode via API, falling back to settings", e);
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 486df62..a09c0b3 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -1000,6 +1000,13 @@
 
   android_fdsan_error_level fdsan_error_level = android_fdsan_get_error_level();
 
+  // Purge unused native memory in an attempt to reduce the amount of false
+  // sharing with the child process.  By reducing the size of the libc_malloc
+  // region shared with the child process we reduce the number of pages that
+  // transition to the private-dirty state when malloc adjusts the meta-data
+  // on each of the pages it is managing after the fork.
+  mallopt(M_PURGE, 0);
+
   pid_t pid = fork();
 
   if (pid == 0) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6960aef..0c0493b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4700,19 +4700,6 @@
     <permission android:name="android.permission.ACCESS_SHARED_LIBRARIES"
                 android:protectionLevel="signature|installer" />
 
-    <!-- Allows an app to log compat change usage.
-         @hide  <p>Not for use by third-party applications.</p> -->
-    <permission android:name="android.permission.LOG_COMPAT_CHANGE"
-                android:protectionLevel="signature" />
-    <!-- Allows an app to read compat change config.
-         @hide  <p>Not for use by third-party applications.</p> -->
-    <permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"
-                android:protectionLevel="signature" />
-    <!-- Allows an app to override compat change config.
-         @hide  <p>Not for use by third-party applications.</p> -->
-    <permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG"
-                android:protectionLevel="signature" />
-
     <!-- Allows input events to be monitored. Very dangerous!  @hide -->
     <permission android:name="android.permission.MONITOR_INPUT"
                 android:protectionLevel="signature" />
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index f058985..567581e 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -165,7 +165,7 @@
         <item>中文 (繁體)</item>
     </string-array>
 
-    <array name="sim_colors">
+    <array name="simColors">
         <item>@color/Teal_700</item>
         <item>@color/Blue_700</item>
         <item>@color/Indigo_700</item>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index fb54566..8a7b515 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3021,6 +3021,10 @@
     <public-group type="color" first-id="0x0106001d">
     </public-group>
 
+    <public-group type="array" first-id="0x01070006">
+      <!-- @hide @SystemApi -->
+      <public name="simColors" />
+    </public-group>
   <!-- ===============================================================
        DO NOT ADD UN-GROUPED ITEMS HERE
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index cd43e9f..001d7c0 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1303,7 +1303,7 @@
   <java-symbol type="array" name="preloaded_color_state_lists" />
   <java-symbol type="array" name="preloaded_drawables" />
   <java-symbol type="array" name="preloaded_freeform_multi_window_drawables" />
-  <java-symbol type="array" name="sim_colors" />
+  <java-symbol type="array" name="simColors" />
   <java-symbol type="array" name="special_locale_codes" />
   <java-symbol type="array" name="special_locale_names" />
   <java-symbol type="array" name="supported_locales" />
diff --git a/core/tests/utiltests/src/com/android/internal/util/LocationPermissionCheckerTest.java b/core/tests/utiltests/src/com/android/internal/util/LocationPermissionCheckerTest.java
index 6a0a3dc..336892f 100644
--- a/core/tests/utiltests/src/com/android/internal/util/LocationPermissionCheckerTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/LocationPermissionCheckerTest.java
@@ -15,6 +15,7 @@
  */
 package com.android.internal.util;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -120,6 +121,7 @@
     private void setupTestCase() throws Exception {
         setupMocks();
         setupMockInterface();
+        mChecker = new LocationPermissionChecker(mMockContext);
     }
 
     private void initTestVars() {
@@ -135,7 +137,6 @@
         mFineLocationPermission = PackageManager.PERMISSION_DENIED;
         mAllowCoarseLocationApps = AppOpsManager.MODE_ERRORED;
         mAllowFineLocationApps = AppOpsManager.MODE_ERRORED;
-        mChecker = new LocationPermissionChecker(mMockContext);
     }
 
     private void setupMockInterface() {
@@ -179,7 +180,11 @@
         mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
         mUid = mCurrentUser;
         setupTestCase();
-        mChecker.enforceLocationPermission(TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
+
+        final int result =
+                mChecker.checkLocationPermissionWithDetailInfo(
+                        TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
+        assertEquals(LocationPermissionChecker.SUCCEEDED, result);
     }
 
     @Test
@@ -192,7 +197,11 @@
         mAllowFineLocationApps = AppOpsManager.MODE_ALLOWED;
         mWifiScanAllowApps = AppOpsManager.MODE_ALLOWED;
         setupTestCase();
-        mChecker.enforceLocationPermission(TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
+
+        final int result =
+                mChecker.checkLocationPermissionWithDetailInfo(
+                        TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
+        assertEquals(LocationPermissionChecker.SUCCEEDED, result);
     }
 
     @Test
@@ -205,7 +214,7 @@
         setupTestCase();
 
         assertThrows(SecurityException.class,
-                () -> mChecker.enforceLocationPermission(
+                () -> mChecker.checkLocationPermissionWithDetailInfo(
                         TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null));
     }
 
@@ -214,9 +223,11 @@
         mThrowSecurityException = false;
         mIsLocationEnabled = true;
         setupTestCase();
-        assertThrows(SecurityException.class,
-                () -> mChecker.enforceLocationPermission(
-                        TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null));
+
+        final int result =
+                mChecker.checkLocationPermissionWithDetailInfo(
+                        TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
+        assertEquals(LocationPermissionChecker.ERROR_LOCATION_PERMISSION_MISSING, result);
     }
 
     @Test
@@ -229,9 +240,10 @@
         mUid = MANAGED_PROFILE_UID;
         setupTestCase();
 
-        assertThrows(SecurityException.class,
-                () -> mChecker.enforceLocationPermission(
-                        TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null));
+        final int result =
+                mChecker.checkLocationPermissionWithDetailInfo(
+                        TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
+        assertEquals(LocationPermissionChecker.ERROR_LOCATION_PERMISSION_MISSING, result);
         verify(mMockAppOps, never()).noteOp(anyInt(), anyInt(), anyString());
     }
 
@@ -245,9 +257,10 @@
 
         setupTestCase();
 
-        assertThrows(SecurityException.class,
-                () -> mChecker.enforceLocationPermission(
-                        TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null));
+        final int result =
+                mChecker.checkLocationPermissionWithDetailInfo(
+                        TEST_PKG_NAME, TEST_FEATURE_ID, mUid, null);
+        assertEquals(LocationPermissionChecker.ERROR_LOCATION_MODE_OFF, result);
     }
 
     private static void assertThrows(Class<? extends Exception> exceptionClass, Runnable r) {
diff --git a/media/java/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java b/media/java/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java
index 074188e..adf4d3d 100644
--- a/media/java/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java
+++ b/media/java/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java
@@ -157,9 +157,7 @@
             Handler handler = eventHandler.handler();
             if (handler != null) {
                 Message m = handler.obtainMessage(what, arg1, arg2, obj);
-                if (what != AUDIOVOLUMEGROUP_EVENT_NEW_LISTENER) {
-                    handler.removeMessages(what);
-                }
+                // Do not remove previous messages, as we would lose notification of group changes
                 handler.sendMessage(m);
             }
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
index aac7fc3..d48aa24 100644
--- a/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/datetime/ZoneGetter.java
@@ -402,7 +402,7 @@
         private static List<String> extractTimeZoneIds(List<TimeZoneMapping> timeZoneMappings) {
             final List<String> zoneIds = new ArrayList<>(timeZoneMappings.size());
             for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
-                zoneIds.add(timeZoneMapping.timeZoneId);
+                zoneIds.add(timeZoneMapping.getTimeZoneId());
             }
             return Collections.unmodifiableList(zoneIds);
         }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 5a5a757..09eece8 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -211,6 +211,9 @@
     <!-- Permission required for CTS test - CrossProfileAppsHostSideTest -->
     <uses-permission android:name="android.permission.INTERACT_ACROSS_PROFILES"/>
 
+    <!-- permissions required for CTS test - PhoneStateListenerTest -->
+    <uses-permission android:name="android.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH" />
+
     <!-- Permission required for CTS test - UiModeManagerTest -->
     <uses-permission android:name="android.permission.ENTER_CAR_MODE_PRIORITIZED"/>
 
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 1315ed0..cf2b1f06 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -16,7 +16,7 @@
 
 java_defaults {
     name: "TetheringAndroidLibraryDefaults",
-    platform_apis: true,
+    sdk_version: "system_current",
     srcs: [
         "src/**/*.java",
         ":framework-tethering-shared-srcs",
@@ -29,6 +29,7 @@
         "netlink-client",
         "networkstack-aidl-interfaces-unstable-java",
         "android.hardware.tetheroffload.control-V1.0-java",
+        "net-utils-framework-common",
     ],
     libs: [
         "framework-tethering",
@@ -80,7 +81,7 @@
 // Common defaults for compiling the actual APK.
 java_defaults {
     name: "TetheringAppDefaults",
-    platform_apis: true,
+    sdk_version: "system_current",
     privileged: true,
     // Build system doesn't track transitive dependeicies for jni_libs, list all the dependencies
     // explicitly.
diff --git a/packages/Tethering/common/TetheringLib/jarjar-rules.txt b/packages/Tethering/common/TetheringLib/jarjar-rules.txt
index 35e0f88..1403bba 100644
--- a/packages/Tethering/common/TetheringLib/jarjar-rules.txt
+++ b/packages/Tethering/common/TetheringLib/jarjar-rules.txt
@@ -1 +1,2 @@
 rule android.annotation.** com.android.networkstack.tethering.annotation.@1
+rule com.android.internal.annotations.** com.android.networkstack.tethering.annotation.@1
\ No newline at end of file
diff --git a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
index 37ce1d57..53a358f 100644
--- a/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
+++ b/packages/Tethering/common/TetheringLib/src/android/net/TetheringManager.java
@@ -30,6 +30,9 @@
 import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -37,6 +40,7 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
+import java.util.function.Supplier;
 
 /**
  * This class provides the APIs to control the tethering service.
@@ -50,17 +54,23 @@
 public class TetheringManager {
     private static final String TAG = TetheringManager.class.getSimpleName();
     private static final int DEFAULT_TIMEOUT_MS = 60_000;
+    private static final long CONNECTOR_POLL_INTERVAL_MILLIS = 200L;
 
-    private static TetheringManager sInstance;
+    @GuardedBy("mConnectorWaitQueue")
+    @Nullable
+    private ITetheringConnector mConnector;
+    @GuardedBy("mConnectorWaitQueue")
+    @NonNull
+    private final List<ConnectorConsumer> mConnectorWaitQueue = new ArrayList<>();
+    private final Supplier<IBinder> mConnectorSupplier;
 
-    private final ITetheringConnector mConnector;
     private final TetheringCallbackInternal mCallback;
     private final Context mContext;
     private final ArrayMap<TetheringEventCallback, ITetheringEventCallback>
             mTetheringEventCallbacks = new ArrayMap<>();
 
-    private TetheringConfigurationParcel mTetheringConfiguration;
-    private TetherStatesParcel mTetherStatesParcel;
+    private volatile TetheringConfigurationParcel mTetheringConfiguration;
+    private volatile TetherStatesParcel mTetherStatesParcel;
 
     /**
      * Broadcast Action: A tetherable connection has come or gone.
@@ -162,29 +172,139 @@
     /**
      * Create a TetheringManager object for interacting with the tethering service.
      *
+     * @param context Context for the manager.
+     * @param connectorSupplier Supplier for the manager connector; may return null while the
+     *                          service is not connected.
      * {@hide}
      */
-    public TetheringManager(@NonNull final Context context, @NonNull final IBinder service) {
+    public TetheringManager(@NonNull final Context context,
+            @NonNull Supplier<IBinder> connectorSupplier) {
         mContext = context;
-        mConnector = ITetheringConnector.Stub.asInterface(service);
         mCallback = new TetheringCallbackInternal();
+        mConnectorSupplier = connectorSupplier;
 
         final String pkgName = mContext.getOpPackageName();
+
+        final IBinder connector = mConnectorSupplier.get();
+        // If the connector is available on start, do not start a polling thread. This introduces
+        // differences in the thread that sends the oneway binder calls to the service between the
+        // first few seconds after boot and later, but it avoids always having differences between
+        // the first usage of TetheringManager from a process and subsequent usages (so the
+        // difference is only on boot). On boot binder calls may be queued until the service comes
+        // up and be sent from a worker thread; later, they are always sent from the caller thread.
+        // Considering that it's just oneway binder calls, and ordering is preserved, this seems
+        // better than inconsistent behavior persisting after boot.
+        if (connector != null) {
+            mConnector = ITetheringConnector.Stub.asInterface(connector);
+        } else {
+            startPollingForConnector();
+        }
+
         Log.i(TAG, "registerTetheringEventCallback:" + pkgName);
+        getConnector(c -> c.registerTetheringEventCallback(mCallback, pkgName));
+    }
+
+    private void startPollingForConnector() {
+        new Thread(() -> {
+            while (true) {
+                try {
+                    Thread.sleep(200);
+                } catch (InterruptedException e) {
+                    // Not much to do here, the system needs to wait for the connector
+                }
+
+                final IBinder connector = mConnectorSupplier.get();
+                if (connector != null) {
+                    onTetheringConnected(ITetheringConnector.Stub.asInterface(connector));
+                    return;
+                }
+            }
+        }).start();
+    }
+
+    private interface ConnectorConsumer {
+        void onConnectorAvailable(ITetheringConnector connector) throws RemoteException;
+    }
+
+    private void onTetheringConnected(ITetheringConnector connector) {
+        // Process the connector wait queue in order, including any items that are added
+        // while processing.
+        //
+        // 1. Copy the queue to a local variable under lock.
+        // 2. Drain the local queue with the lock released (otherwise, enqueuing future commands
+        //    would block on the lock).
+        // 3. Acquire the lock again. If any new tasks were queued during step 2, goto 1.
+        //    If not, set mConnector to non-null so future tasks are run immediately, not queued.
+        //
+        // For this to work, all calls to the tethering service must use getConnector(), which
+        // ensures that tasks are added to the queue with the lock held.
+        //
+        // Once mConnector is set to non-null, it will never be null again. If the network stack
+        // process crashes, no recovery is possible.
+        // TODO: evaluate whether it is possible to recover from network stack process crashes
+        // (though in most cases the system will have crashed when the network stack process
+        // crashes).
+        do {
+            final List<ConnectorConsumer> localWaitQueue;
+            synchronized (mConnectorWaitQueue) {
+                localWaitQueue = new ArrayList<>(mConnectorWaitQueue);
+                mConnectorWaitQueue.clear();
+            }
+
+            // Allow more tasks to be added at the end without blocking while draining the queue.
+            for (ConnectorConsumer task : localWaitQueue) {
+                try {
+                    task.onConnectorAvailable(connector);
+                } catch (RemoteException e) {
+                    // Most likely the network stack process crashed, which is likely to crash the
+                    // system. Keep processing other requests but report the error loudly.
+                    Log.wtf(TAG, "Error processing request for the tethering connector", e);
+                }
+            }
+
+            synchronized (mConnectorWaitQueue) {
+                if (mConnectorWaitQueue.size() == 0) {
+                    mConnector = connector;
+                    return;
+                }
+            }
+        } while (true);
+    }
+
+    /**
+     * Asynchronously get the ITetheringConnector to execute some operation.
+     *
+     * <p>If the connector is already available, the operation will be executed on the caller's
+     * thread. Otherwise it will be queued and executed on a worker thread. The operation should be
+     * limited to performing oneway binder calls to minimize differences due to threading.
+     */
+    private void getConnector(ConnectorConsumer consumer) {
+        final ITetheringConnector connector;
+        synchronized (mConnectorWaitQueue) {
+            connector = mConnector;
+            if (connector == null) {
+                mConnectorWaitQueue.add(consumer);
+                return;
+            }
+        }
+
         try {
-            mConnector.registerTetheringEventCallback(mCallback, pkgName);
+            consumer.onConnectorAvailable(connector);
         } catch (RemoteException e) {
             throw new IllegalStateException(e);
         }
     }
 
     private interface RequestHelper {
-        void runRequest(IIntResultListener listener);
+        void runRequest(ITetheringConnector connector, IIntResultListener listener);
     }
 
+    // Used to dispatch legacy ConnectivityManager methods that expect tethering to be able to
+    // return results and perform operations synchronously.
+    // TODO: remove once there are no callers of these legacy methods.
     private class RequestDispatcher {
         private final ConditionVariable mWaiting;
-        public int mRemoteResult;
+        public volatile int mRemoteResult;
 
         private final IIntResultListener mListener = new IIntResultListener.Stub() {
                 @Override
@@ -199,7 +319,7 @@
         }
 
         int waitForResult(final RequestHelper request) {
-            request.runRequest(mListener);
+            getConnector(c -> request.runRequest(c, mListener));
             if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
                 throw new IllegalStateException("Callback timeout");
             }
@@ -222,7 +342,7 @@
     }
 
     private class TetheringCallbackInternal extends ITetheringEventCallback.Stub {
-        private int mError = TETHER_ERROR_NO_ERROR;
+        private volatile int mError = TETHER_ERROR_NO_ERROR;
         private final ConditionVariable mWaitForCallback = new ConditionVariable();
 
         @Override
@@ -280,9 +400,9 @@
         Log.i(TAG, "tether caller:" + callerPkg);
         final RequestDispatcher dispatcher = new RequestDispatcher();
 
-        return dispatcher.waitForResult(listener -> {
+        return dispatcher.waitForResult((connector, listener) -> {
             try {
-                mConnector.tether(iface, callerPkg, listener);
+                connector.tether(iface, callerPkg, listener);
             } catch (RemoteException e) {
                 throw new IllegalStateException(e);
             }
@@ -304,9 +424,9 @@
 
         final RequestDispatcher dispatcher = new RequestDispatcher();
 
-        return dispatcher.waitForResult(listener -> {
+        return dispatcher.waitForResult((connector, listener) -> {
             try {
-                mConnector.untether(iface, callerPkg, listener);
+                connector.untether(iface, callerPkg, listener);
             } catch (RemoteException e) {
                 throw new IllegalStateException(e);
             }
@@ -330,9 +450,9 @@
 
         final RequestDispatcher dispatcher = new RequestDispatcher();
 
-        return dispatcher.waitForResult(listener -> {
+        return dispatcher.waitForResult((connector, listener) -> {
             try {
-                mConnector.setUsbTethering(enable, callerPkg, listener);
+                connector.setUsbTethering(enable, callerPkg, listener);
             } catch (RemoteException e) {
                 throw new IllegalStateException(e);
             }
@@ -467,11 +587,7 @@
                 });
             }
         };
-        try {
-            mConnector.startTethering(request.getParcel(), callerPkg, listener);
-        } catch (RemoteException e) {
-            throw new IllegalStateException(e);
-        }
+        getConnector(c -> c.startTethering(request.getParcel(), callerPkg, listener));
     }
 
     /**
@@ -509,15 +625,15 @@
         final String callerPkg = mContext.getOpPackageName();
         Log.i(TAG, "stopTethering caller:" + callerPkg);
 
-        final RequestDispatcher dispatcher = new RequestDispatcher();
-
-        dispatcher.waitForResult(listener -> {
-            try {
-                mConnector.stopTethering(type, callerPkg, listener);
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
+        getConnector(c -> c.stopTethering(type, callerPkg, new IIntResultListener.Stub() {
+            @Override
+            public void onResult(int resultCode) {
+                // TODO: provide an API to obtain result
+                // This has never been possible as stopTethering has always been void and never
+                // taken a callback object. The only indication that callers have is if the call
+                // results in a TETHER_STATE_CHANGE broadcast.
             }
-        });
+        }));
     }
 
     /**
@@ -591,12 +707,8 @@
         final String callerPkg = mContext.getOpPackageName();
         Log.i(TAG, "getLatestTetheringEntitlementResult caller:" + callerPkg);
 
-        try {
-            mConnector.requestLatestTetheringEntitlementResult(type, receiver, showEntitlementUi,
-                    callerPkg);
-        } catch (RemoteException e) {
-            throw new IllegalStateException(e);
-        }
+        getConnector(c -> c.requestLatestTetheringEntitlementResult(
+                type, receiver, showEntitlementUi, callerPkg));
     }
 
     /**
@@ -832,11 +944,7 @@
                     });
                 }
             };
-            try {
-                mConnector.registerTetheringEventCallback(remoteCallback, callerPkg);
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
-            }
+            getConnector(c -> c.registerTetheringEventCallback(remoteCallback, callerPkg));
             mTetheringEventCallbacks.put(callback, remoteCallback);
         }
     }
@@ -860,11 +968,8 @@
             if (remoteCallback == null) {
                 throw new IllegalArgumentException("callback was not registered.");
             }
-            try {
-                mConnector.unregisterTetheringEventCallback(remoteCallback, callerPkg);
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
-            }
+
+            getConnector(c -> c.unregisterTetheringEventCallback(remoteCallback, callerPkg));
         }
     }
 
@@ -1002,9 +1107,9 @@
         final String callerPkg = mContext.getOpPackageName();
 
         final RequestDispatcher dispatcher = new RequestDispatcher();
-        final int ret = dispatcher.waitForResult(listener -> {
+        final int ret = dispatcher.waitForResult((connector, listener) -> {
             try {
-                mConnector.isTetheringSupported(callerPkg, listener);
+                connector.isTetheringSupported(callerPkg, listener);
             } catch (RemoteException e) {
                 throw new IllegalStateException(e);
             }
@@ -1027,13 +1132,14 @@
         final String callerPkg = mContext.getOpPackageName();
         Log.i(TAG, "stopAllTethering caller:" + callerPkg);
 
-        final RequestDispatcher dispatcher = new RequestDispatcher();
-        dispatcher.waitForResult(listener -> {
-            try {
-                mConnector.stopAllTethering(callerPkg, listener);
-            } catch (RemoteException e) {
-                throw new IllegalStateException(e);
+        getConnector(c -> c.stopAllTethering(callerPkg, new IIntResultListener.Stub() {
+            @Override
+            public void onResult(int resultCode) {
+                // TODO: add an API parameter to send result to caller.
+                // This has never been possible as stopAllTethering has always been void and never
+                // taken a callback object. The only indication that callers have is if the call
+                // results in a TETHER_STATE_CHANGE broadcast.
             }
-        });
+        }));
     }
 }
diff --git a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java
index d5cdd8a..4dd6830 100644
--- a/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/TetheringInterfaceUtils.java
@@ -22,6 +22,8 @@
 import android.net.RouteInfo;
 import android.net.util.InterfaceSet;
 
+import com.android.net.module.util.NetUtils;
+
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
@@ -85,7 +87,7 @@
 
     private static String getInterfaceForDestination(LinkProperties lp, InetAddress dst) {
         final RouteInfo ri = (lp != null)
-                ? RouteInfo.selectBestRoute(lp.getAllRoutes(), dst)
+                ? NetUtils.selectBestRoute(lp.getAllRoutes(), dst)
                 : null;
         return (ri != null) ? ri.getInterface() : null;
     }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 5eacb28..f0a3bfd 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -296,6 +296,12 @@
             PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_CALL
                     | PhoneStateListener.LISTEN_OUTGOING_EMERGENCY_SMS;
 
+    static final int READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK =
+            PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT
+                | PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED
+                | PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED
+                | PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE;
+
     private static final int MSG_USER_SWITCHED = 1;
     private static final int MSG_UPDATE_DEFAULT_SUB = 2;
 
@@ -885,6 +891,13 @@
                     if ((events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH)
                             != 0) {
                         updateReportSignalStrengthDecision(r.subId);
+                        try {
+                            if (mSignalStrength[phoneId] != null) {
+                                r.callback.onSignalStrengthsChanged(mSignalStrength[phoneId]);
+                            }
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
                     }
                     if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_INFO)) {
                         try {
@@ -1301,9 +1314,10 @@
                         log("notifySignalStrengthForPhoneId: r=" + r + " subId=" + subId
                                 + " phoneId=" + phoneId + " ss=" + signalStrength);
                     }
-                    if (r.matchPhoneStateListenerEvent(
-                                PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) &&
-                            idMatch(r.subId, subId, phoneId)) {
+                    if ((r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTHS)
+                            || r.matchPhoneStateListenerEvent(
+                                    PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH))
+                            && idMatch(r.subId, subId, phoneId)) {
                         try {
                             if (DBG) {
                                 log("notifySignalStrengthForPhoneId: callback.onSsS r=" + r
@@ -1316,7 +1330,7 @@
                         }
                     }
                     if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) &&
-                            idMatch(r.subId, subId, phoneId)){
+                            idMatch(r.subId, subId, phoneId)) {
                         try {
                             int gsmSignalStrength = signalStrength.getGsmSignalStrength();
                             int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
@@ -2453,22 +2467,7 @@
                     android.Manifest.permission.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH, null);
         }
 
-        if ((events & PhoneStateListener.LISTEN_OEM_HOOK_RAW_EVENT) != 0) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
-        }
-
-        if ((events & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
-        }
-
-        if ((events & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
-        }
-
-        if ((events & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) != 0) {
+        if ((events & READ_PRIVILEGED_PHONE_STATE_PERMISSION_MASK) != 0) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
         }
@@ -2583,7 +2582,8 @@
             }
         }
 
-        if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0) {
+        if ((events & PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) != 0
+                || (events & PhoneStateListener.LISTEN_ALWAYS_REPORTED_SIGNAL_STRENGTH) != 0) {
             try {
                 if (mSignalStrength[phoneId] != null) {
                     SignalStrength signalStrength = mSignalStrength[phoneId];
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index e48169f..029b7bc 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -16,11 +16,6 @@
 
 package com.android.server.compat;
 
-import static android.Manifest.permission.LOG_COMPAT_CHANGE;
-import static android.Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG;
-import static android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-
 import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.content.Context;
@@ -72,14 +67,12 @@
 
     @Override
     public void reportChange(long changeId, ApplicationInfo appInfo) {
-        checkCompatChangeLogPermission();
         reportChange(changeId, appInfo.uid,
                 StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
     }
 
     @Override
     public void reportChangeByPackageName(long changeId, String packageName, int userId) {
-        checkCompatChangeLogPermission();
         ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
         if (appInfo == null) {
             return;
@@ -89,13 +82,11 @@
 
     @Override
     public void reportChangeByUid(long changeId, int uid) {
-        checkCompatChangeLogPermission();
         reportChange(changeId, uid, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
     }
 
     @Override
     public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
-        checkCompatChangeReadPermission();
         if (mCompatConfig.isChangeEnabled(changeId, appInfo)) {
             reportChange(changeId, appInfo.uid,
                     StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED);
@@ -108,7 +99,6 @@
 
     @Override
     public boolean isChangeEnabledByPackageName(long changeId, String packageName, int userId) {
-        checkCompatChangeReadPermission();
         ApplicationInfo appInfo = getApplicationInfo(packageName, userId);
         if (appInfo == null) {
             return true;
@@ -118,7 +108,6 @@
 
     @Override
     public boolean isChangeEnabledByUid(long changeId, int uid) {
-        checkCompatChangeReadPermission();
         String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
         if (packages == null || packages.length == 0) {
             return true;
@@ -151,7 +140,6 @@
     @Override
     public void setOverrides(CompatibilityChangeConfig overrides, String packageName)
             throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         mCompatConfig.addOverrides(overrides, packageName);
         killPackage(packageName);
     }
@@ -159,13 +147,11 @@
     @Override
     public void setOverridesForTest(CompatibilityChangeConfig overrides, String packageName)
             throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         mCompatConfig.addOverrides(overrides, packageName);
     }
 
     @Override
     public void clearOverrides(String packageName) throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         mCompatConfig.removePackageOverrides(packageName);
         killPackage(packageName);
     }
@@ -173,14 +159,12 @@
     @Override
     public void clearOverridesForTest(String packageName)
             throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         mCompatConfig.removePackageOverrides(packageName);
     }
 
     @Override
     public boolean clearOverride(long changeId, String packageName)
             throws RemoteException, SecurityException {
-        checkCompatChangeOverridePermission();
         boolean existed = mCompatConfig.removeOverride(changeId, packageName);
         killPackage(packageName);
         return existed;
@@ -188,13 +172,11 @@
 
     @Override
     public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
-        checkCompatChangeReadPermission();
         return mCompatConfig.getAppConfig(appInfo);
     }
 
     @Override
     public CompatibilityChangeInfo[] listAllChanges() {
-        checkCompatChangeReadPermission();
         return mCompatConfig.dumpChanges();
     }
 
@@ -233,7 +215,6 @@
 
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        checkCompatChangeReadPermission();
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
         mCompatConfig.dumpConfig(pw);
     }
@@ -295,25 +276,4 @@
             Binder.restoreCallingIdentity(identity);
         }
     }
-
-    private void checkCompatChangeLogPermission() throws SecurityException {
-        if (mContext.checkCallingOrSelfPermission(LOG_COMPAT_CHANGE)
-                != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot log compat change usage");
-        }
-    }
-
-    private void checkCompatChangeReadPermission() throws SecurityException {
-        if (mContext.checkCallingOrSelfPermission(READ_COMPAT_CHANGE_CONFIG)
-                != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot read compat change");
-        }
-    }
-
-    private void checkCompatChangeOverridePermission() throws SecurityException {
-        if (mContext.checkCallingOrSelfPermission(OVERRIDE_COMPAT_CHANGE_CONFIG)
-                != PERMISSION_GRANTED) {
-            throw new SecurityException("Cannot override compat change");
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 2c41557..25c761a 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -188,14 +188,14 @@
         int icon = getIcon(transportType, notifyType);
         if (notifyType == NotificationType.NO_INTERNET && transportType == TRANSPORT_WIFI) {
             title = r.getString(R.string.wifi_no_internet,
-                    WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+                    WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
             details = r.getString(R.string.wifi_no_internet_detailed);
         } else if (notifyType == NotificationType.PRIVATE_DNS_BROKEN) {
             if (transportType == TRANSPORT_CELLULAR) {
                 title = r.getString(R.string.mobile_no_internet);
             } else if (transportType == TRANSPORT_WIFI) {
                 title = r.getString(R.string.wifi_no_internet,
-                        WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+                        WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
             } else {
                 title = r.getString(R.string.other_networks_no_internet);
             }
@@ -203,19 +203,19 @@
         } else if (notifyType == NotificationType.PARTIAL_CONNECTIVITY
                 && transportType == TRANSPORT_WIFI) {
             title = r.getString(R.string.network_partial_connectivity,
-                    WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+                    WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
             details = r.getString(R.string.network_partial_connectivity_detailed);
         } else if (notifyType == NotificationType.LOST_INTERNET &&
                 transportType == TRANSPORT_WIFI) {
             title = r.getString(R.string.wifi_no_internet,
-                    WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+                    WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
             details = r.getString(R.string.wifi_no_internet_detailed);
         } else if (notifyType == NotificationType.SIGN_IN) {
             switch (transportType) {
                 case TRANSPORT_WIFI:
                     title = r.getString(R.string.wifi_available_sign_in, 0);
                     details = r.getString(R.string.network_available_sign_in_detailed,
-                            WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID()));
+                            WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID()));
                     break;
                 case TRANSPORT_CELLULAR:
                     title = r.getString(R.string.network_available_sign_in, 0);
@@ -236,7 +236,7 @@
                     break;
             }
         } else if (notifyType == NotificationType.LOGGED_IN) {
-            title = WifiInfo.removeDoubleQuotes(nai.networkCapabilities.getSSID());
+            title = WifiInfo.sanitizeSsid(nai.networkCapabilities.getSSID());
             details = r.getString(R.string.captive_portal_logged_in_detailed);
         } else if (notifyType == NotificationType.NETWORK_SWITCH) {
             String fromTransport = getTransportName(transportType);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7e7822c..d8f5dfb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -21009,7 +21009,7 @@
         // Disable any carrier apps. We do this very early in boot to prevent the apps from being
         // disabled after already being started.
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
-                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
+                UserHandle.USER_SYSTEM, mContext);
 
         disableSkuSpecificApps();
 
diff --git a/services/core/java/com/android/server/timezone/RulesManagerService.java b/services/core/java/com/android/server/timezone/RulesManagerService.java
index cdf8ea3..bbd1ae6 100644
--- a/services/core/java/com/android/server/timezone/RulesManagerService.java
+++ b/services/core/java/com/android/server/timezone/RulesManagerService.java
@@ -198,7 +198,7 @@
                     Slog.w(TAG, "Failed to read staged distro.", e);
                 }
             }
-            return new RulesState(baseVersion.rulesVersion, DISTRO_FORMAT_VERSION_SUPPORTED,
+            return new RulesState(baseVersion.getRulesVersion(), DISTRO_FORMAT_VERSION_SUPPORTED,
                     operationInProgress, stagedOperationStatus, stagedDistroRulesVersion,
                     distroStatus, installedDistroRulesVersion);
         }
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index 78b64ca..67254b8 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -14,6 +14,12 @@
  * limitations under the License.
  */
 
+#include <dlfcn.h>
+#include <pthread.h>
+
+#include <chrono>
+#include <thread>
+
 #include <jni.h>
 #include <nativehelper/JNIHelp.h>
 
@@ -25,12 +31,17 @@
 #include <sensorservicehidl/SensorManager.h>
 
 #include <bionic/malloc.h>
+#include <bionic/reserved_signals.h>
 
+#include <android-base/properties.h>
 #include <cutils/properties.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
 #include <utils/AndroidThreads.h>
 
+using android::base::GetIntProperty;
+using namespace std::chrono_literals;
+
 namespace android {
 
 static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
@@ -68,7 +79,50 @@
 
 static void android_server_SystemServer_initZygoteChildHeapProfiling(JNIEnv* /* env */,
                                                                      jobject /* clazz */) {
-   android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0);
+    android_mallopt(M_INIT_ZYGOTE_CHILD_PROFILING, nullptr, 0);
+}
+
+static int get_current_max_fd() {
+    // Not actually guaranteed to be the max, but close enough for our purposes.
+    int fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
+    LOG_ALWAYS_FATAL_IF(fd == -1, "failed to open /dev/null: %s", strerror(errno));
+    close(fd);
+    return fd;
+}
+
+static const char kFdLeakEnableThresholdProperty[] = "persist.sys.debug.fdtrack_enable_threshold";
+static const char kFdLeakAbortThresholdProperty[] = "persist.sys.debug.fdtrack_abort_threshold";
+static const char kFdLeakCheckIntervalProperty[] = "persist.sys.debug.fdtrack_interval";
+
+static void android_server_SystemServer_spawnFdLeakCheckThread(JNIEnv*, jobject) {
+    std::thread([]() {
+        pthread_setname_np(pthread_self(), "FdLeakCheckThread");
+        bool loaded = false;
+        while (true) {
+            const int enable_threshold = GetIntProperty(kFdLeakEnableThresholdProperty, 1024);
+            const int abort_threshold = GetIntProperty(kFdLeakAbortThresholdProperty, 2048);
+            const int check_interval = GetIntProperty(kFdLeakCheckIntervalProperty, 120);
+            int max_fd = get_current_max_fd();
+            if (max_fd > enable_threshold && !loaded) {
+                loaded = true;
+                ALOGE("fd count above threshold of %d, starting fd backtraces", enable_threshold);
+                if (dlopen("libfdtrack.so", RTLD_GLOBAL) == nullptr) {
+                    ALOGE("failed to load libfdtrack.so: %s", dlerror());
+                }
+            } else if (max_fd > abort_threshold) {
+                raise(BIONIC_SIGNAL_FDTRACK);
+
+                // Wait for a bit to allow fdtrack to dump backtraces to logcat.
+                std::this_thread::sleep_for(5s);
+
+                LOG_ALWAYS_FATAL(
+                    "b/140703823: aborting due to fd leak: check logs for fd "
+                    "backtraces");
+            }
+
+            std::this_thread::sleep_for(std::chrono::seconds(check_interval));
+        }
+    }).detach();
 }
 
 /*
@@ -80,6 +134,9 @@
     { "startHidlServices", "()V", (void*) android_server_SystemServer_startHidlServices },
     { "initZygoteChildHeapProfiling", "()V",
       (void*) android_server_SystemServer_initZygoteChildHeapProfiling },
+    { "spawnFdLeakCheckThread", "()V",
+      (void*) android_server_SystemServer_spawnFdLeakCheckThread },
+
 };
 
 int register_android_server_SystemServer(JNIEnv* env)
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c566341..b93365a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -353,6 +353,12 @@
      */
     private static native void initZygoteChildHeapProfiling();
 
+
+    /**
+     * Spawn a thread that monitors for fd leaks.
+     */
+    private static native void spawnFdLeakCheckThread();
+
     /**
      * The main entry point from zygote.
      */
@@ -484,6 +490,11 @@
                 initZygoteChildHeapProfiling();
             }
 
+            // Debug builds - spawn a thread to monitor for fd leaks.
+            if (Build.IS_DEBUGGABLE) {
+                spawnFdLeakCheckThread();
+            }
+
             // Check whether we failed to shut down last time we tried.
             // This call may not return.
             performPendingShutdown();
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 1e623e0..61fe01f 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -65,8 +65,6 @@
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
     <uses-permission android:name="android.permission.SUSPEND_APPS"/>
     <uses-permission android:name="android.permission.CONTROL_KEYGUARD"/>
-    <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG"/>
-    <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE"/>
     <uses-permission android:name="android.permission.MANAGE_BIND_INSTANT_SERVICE"/>
     <uses-permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS" />
     <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
diff --git a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
index 3f5aa0f..3c1e707 100644
--- a/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/common/com/android/internal/telephony/CarrierAppUtils.java
@@ -18,16 +18,18 @@
 
 import android.annotation.Nullable;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.provider.Settings;
-import android.util.Log;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.Log;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -75,7 +77,7 @@
      */
     public static synchronized void disableCarrierAppsUntilPrivileged(String callingPackage,
             IPackageManager packageManager, TelephonyManager telephonyManager,
-            ContentResolver contentResolver, int userId) {
+            int userId, Context context) {
         if (DEBUG) {
             Log.d(TAG, "disableCarrierAppsUntilPrivileged");
         }
@@ -84,6 +86,7 @@
                 config.getDisabledUntilUsedPreinstalledCarrierApps();
         ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
                 config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+        ContentResolver contentResolver = getContentResolverForUser(context, userId);
         disableCarrierAppsUntilPrivileged(callingPackage, packageManager, telephonyManager,
                 contentResolver, userId, systemCarrierAppsDisabledUntilUsed,
                 systemCarrierAssociatedAppsDisabledUntilUsed);
@@ -101,7 +104,7 @@
      * Manager can kill it, and this can lead to crashes as the app is in an unexpected state.
      */
     public static synchronized void disableCarrierAppsUntilPrivileged(String callingPackage,
-            IPackageManager packageManager, ContentResolver contentResolver, int userId) {
+            IPackageManager packageManager, int userId, Context context) {
         if (DEBUG) {
             Log.d(TAG, "disableCarrierAppsUntilPrivileged");
         }
@@ -112,23 +115,31 @@
 
         ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
                 config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
+        ContentResolver contentResolver = getContentResolverForUser(context, userId);
         disableCarrierAppsUntilPrivileged(callingPackage, packageManager,
                 null /* telephonyManager */, contentResolver, userId,
                 systemCarrierAppsDisabledUntilUsed, systemCarrierAssociatedAppsDisabledUntilUsed);
     }
 
+    private static ContentResolver getContentResolverForUser(Context context, int userId) {
+        Context userContext = context.createContextAsUser(UserHandle.getUserHandleForUid(userId),
+                0);
+        return userContext.getContentResolver();
+    }
+
     /**
      * Disable carrier apps until they are privileged
      * Must be public b/c framework unit tests can't access package-private methods.
      */
+    // Must be public b/c framework unit tests can't access package-private methods.
     @VisibleForTesting
     public static void disableCarrierAppsUntilPrivileged(String callingPackage,
             IPackageManager packageManager, @Nullable TelephonyManager telephonyManager,
             ContentResolver contentResolver, int userId,
             ArraySet<String> systemCarrierAppsDisabledUntilUsed,
             ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed) {
-        List<ApplicationInfo> candidates = getDefaultCarrierAppCandidatesHelper(packageManager,
-                userId, systemCarrierAppsDisabledUntilUsed);
+        List<ApplicationInfo> candidates = getDefaultNotUpdatedCarrierAppCandidatesHelper(
+                packageManager, userId, systemCarrierAppsDisabledUntilUsed);
         if (candidates == null || candidates.isEmpty()) {
             return;
         }
@@ -139,9 +150,8 @@
                 systemCarrierAssociatedAppsDisabledUntilUsed);
 
         List<String> enabledCarrierPackages = new ArrayList<>();
-
-        boolean hasRunOnce = Settings.Secure.getIntForUser(
-                contentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 0, userId) == 1;
+        boolean hasRunOnce = Settings.Secure.getInt(contentResolver,
+                Settings.Secure.CARRIER_APPS_HANDLED, 0) == 1;
 
         try {
             for (ApplicationInfo ai : candidates) {
@@ -165,15 +175,16 @@
                     }
                 }
 
+                int enabledSetting = packageManager.getApplicationEnabledSetting(packageName,
+                        userId);
                 if (hasPrivileges) {
                     // Only update enabled state for the app on /system. Once it has been
                     // updated we shouldn't touch it.
-                    if (!ai.isUpdatedSystemApp()
-                            && (ai.enabledSetting
+                    if (enabledSetting
                             == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
-                            || ai.enabledSetting
+                            || enabledSetting
                             == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
-                            || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0)) {
+                            || (ai.flags & ApplicationInfo.FLAG_INSTALLED) == 0) {
                         Log.i(TAG, "Update state(" + packageName + "): ENABLED for user "
                                 + userId);
                         packageManager.setSystemAppInstallState(
@@ -191,9 +202,12 @@
                     // Also enable any associated apps for this carrier app.
                     if (associatedAppList != null) {
                         for (ApplicationInfo associatedApp : associatedAppList) {
-                            if (associatedApp.enabledSetting
+                            int associatedAppEnabledSetting =
+                                    packageManager.getApplicationEnabledSetting(
+                                    associatedApp.packageName, userId);
+                            if (associatedAppEnabledSetting
                                     == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
-                                    || associatedApp.enabledSetting
+                                    || associatedAppEnabledSetting
                                     == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
                                     || (associatedApp.flags
                                     & ApplicationInfo.FLAG_INSTALLED) == 0) {
@@ -218,8 +232,7 @@
                 } else {  // No carrier privileges
                     // Only update enabled state for the app on /system. Once it has been
                     // updated we shouldn't touch it.
-                    if (!ai.isUpdatedSystemApp()
-                            && ai.enabledSetting
+                    if (enabledSetting
                             == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                             && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
                         Log.i(TAG, "Update state(" + packageName
@@ -236,7 +249,10 @@
                     if (!hasRunOnce) {
                         if (associatedAppList != null) {
                             for (ApplicationInfo associatedApp : associatedAppList) {
-                                if (associatedApp.enabledSetting
+                                int associatedAppEnabledSetting =
+                                        packageManager.getApplicationEnabledSetting(
+                                        associatedApp.packageName, userId);
+                                if (associatedAppEnabledSetting
                                         == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                                         && (associatedApp.flags
                                         & ApplicationInfo.FLAG_INSTALLED) != 0) {
@@ -256,8 +272,7 @@
 
             // Mark the execution so we do not disable apps again.
             if (!hasRunOnce) {
-                Settings.Secure.putIntForUser(
-                        contentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 1, userId);
+                Settings.Secure.putInt(contentResolver, Settings.Secure.CARRIER_APPS_HANDLED, 1);
             }
 
             if (!enabledCarrierPackages.isEmpty()) {
@@ -348,6 +363,31 @@
         return apps;
     }
 
+    private static List<ApplicationInfo> getDefaultNotUpdatedCarrierAppCandidatesHelper(
+            IPackageManager packageManager,
+            int userId,
+            ArraySet<String> systemCarrierAppsDisabledUntilUsed) {
+        if (systemCarrierAppsDisabledUntilUsed == null) {
+            return null;
+        }
+
+        int size = systemCarrierAppsDisabledUntilUsed.size();
+        if (size == 0) {
+            return null;
+        }
+
+        List<ApplicationInfo> apps = new ArrayList<>(size);
+        for (int i = 0; i < size; i++) {
+            String packageName = systemCarrierAppsDisabledUntilUsed.valueAt(i);
+            ApplicationInfo ai =
+                    getApplicationInfoIfNotUpdatedSystemApp(packageManager, userId, packageName);
+            if (ai != null) {
+                apps.add(ai);
+            }
+        }
+        return apps;
+    }
+
     private static Map<String, List<ApplicationInfo>> getDefaultCarrierAssociatedAppsHelper(
             IPackageManager packageManager,
             int userId,
@@ -360,11 +400,11 @@
                     systemCarrierAssociatedAppsDisabledUntilUsed.valueAt(i);
             for (int j = 0; j < associatedAppPackages.size(); j++) {
                 ApplicationInfo ai =
-                        getApplicationInfoIfSystemApp(
+                        getApplicationInfoIfNotUpdatedSystemApp(
                                 packageManager, userId, associatedAppPackages.get(j));
                 // Only update enabled state for the app on /system. Once it has been updated we
                 // shouldn't touch it.
-                if (ai != null && !ai.isUpdatedSystemApp()) {
+                if (ai != null) {
                     List<ApplicationInfo> appList = associatedApps.get(carrierAppPackage);
                     if (appList == null) {
                         appList = new ArrayList<>();
@@ -378,6 +418,26 @@
     }
 
     @Nullable
+    private static ApplicationInfo getApplicationInfoIfNotUpdatedSystemApp(
+            IPackageManager packageManager,
+            int userId,
+            String packageName) {
+        try {
+            ApplicationInfo ai = packageManager.getApplicationInfo(packageName,
+                    PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                            | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
+                            | PackageManager.MATCH_SYSTEM_ONLY
+                            | PackageManager.MATCH_FACTORY_ONLY, userId);
+            if (ai != null) {
+                return ai;
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Could not reach PackageManager", e);
+        }
+        return null;
+    }
+
+    @Nullable
     private static ApplicationInfo getApplicationInfoIfSystemApp(
             IPackageManager packageManager,
             int userId,
@@ -385,8 +445,9 @@
         try {
             ApplicationInfo ai = packageManager.getApplicationInfo(packageName,
                     PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
-                    | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, userId);
-            if (ai != null && ai.isSystemApp()) {
+                    | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
+                    | PackageManager.MATCH_SYSTEM_ONLY, userId);
+            if (ai != null) {
                 return ai;
             }
         } catch (RemoteException e) {
diff --git a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
index 5beb06d..2077800 100644
--- a/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/common/com/android/internal/telephony/TelephonyPermissions.java
@@ -365,7 +365,6 @@
     private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid,
             int uid, String callingPackage, String message) {
         boolean isPreinstalled = false;
-        boolean isPrivApp = false;
         ApplicationInfo callingPackageInfo = null;
         try {
             callingPackageInfo = context.getPackageManager().getApplicationInfoAsUser(
@@ -373,9 +372,6 @@
             if (callingPackageInfo != null) {
                 if (callingPackageInfo.isSystemApp()) {
                     isPreinstalled = true;
-                    if (callingPackageInfo.isPrivilegedApp()) {
-                        isPrivApp = true;
-                    }
                 }
             }
         } catch (PackageManager.NameNotFoundException e) {
@@ -398,10 +394,10 @@
             }
             invokedMethods.add(message);
             StatsLog.write(StatsLog.DEVICE_IDENTIFIER_ACCESS_DENIED, callingPackage, message,
-                    isPreinstalled, isPrivApp);
+                    isPreinstalled, false);
         }
         Log.w(LOG_TAG, "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message
-                + ":isPreinstalled=" + isPreinstalled + ":isPrivApp=" + isPrivApp);
+                + ":isPreinstalled=" + isPreinstalled);
         // if the target SDK is pre-Q then check if the calling package would have previously
         // had access to device identifiers.
         if (callingPackageInfo != null && (
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index 0498d7c..2abcc76 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -28,6 +28,7 @@
 import android.os.SystemProperties;
 
 import java.io.PrintWriter;
+import java.util.function.Supplier;
 
 /**
  * This class provides various util functions
@@ -75,6 +76,42 @@
     }
 
     /**
+     * Convenience method for running the provided action enclosed in
+     * {@link Binder#clearCallingIdentity}/{@link Binder#restoreCallingIdentity}
+     *
+     * Any exception thrown by the given action will need to be handled by caller.
+     *
+     */
+    public static void runWithCleanCallingIdentity(
+            @NonNull Runnable action) {
+        long callingIdentity = Binder.clearCallingIdentity();
+        try {
+            action.run();
+        } finally {
+            Binder.restoreCallingIdentity(callingIdentity);
+        }
+    }
+
+
+    /**
+     * Convenience method for running the provided action enclosed in
+     * {@link Binder#clearCallingIdentity}/{@link Binder#restoreCallingIdentity} and return
+     * the result.
+     *
+     * Any exception thrown by the given action will need to be handled by caller.
+     *
+     */
+    public static <T> T runWithCleanCallingIdentity(
+            @NonNull Supplier<T> action) {
+        long callingIdentity = Binder.clearCallingIdentity();
+        try {
+            return action.get();
+        } finally {
+            Binder.restoreCallingIdentity(callingIdentity);
+        }
+    }
+
+    /**
      * Filter values in bundle to only basic types.
      */
     public static Bundle filterValues(Bundle bundle) {
diff --git a/telephony/java/android/service/carrier/CarrierIdentifier.java b/telephony/java/android/service/carrier/CarrierIdentifier.java
index 7957c25..bc0f909 100644
--- a/telephony/java/android/service/carrier/CarrierIdentifier.java
+++ b/telephony/java/android/service/carrier/CarrierIdentifier.java
@@ -20,10 +20,10 @@
 import android.annotation.Nullable;
 import android.os.Parcel;
 import android.os.Parcelable;
-import com.android.telephony.Rlog;
 import android.telephony.TelephonyManager;
 
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.telephony.Rlog;
 
 import java.util.Objects;
 
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 9e6dfef..db17a95 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -598,6 +598,48 @@
     }
 
     /**
+     * Call forwarding function status
+     */
+    @IntDef(prefix = { "STATUS_" }, value = {
+        CallForwardingInfo.STATUS_ACTIVE,
+        CallForwardingInfo.STATUS_INACTIVE,
+        CallForwardingInfo.STATUS_UNKNOWN_ERROR,
+        CallForwardingInfo.STATUS_NOT_SUPPORTED,
+        CallForwardingInfo.STATUS_FDN_CHECK_FAILURE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallForwardingStatus {
+    }
+
+    /**
+     * Call forwarding reason types
+     */
+    @IntDef(flag = true, prefix = { "REASON_" }, value = {
+        CallForwardingInfo.REASON_UNCONDITIONAL,
+        CallForwardingInfo.REASON_BUSY,
+        CallForwardingInfo.REASON_NO_REPLY,
+        CallForwardingInfo.REASON_NOT_REACHABLE,
+        CallForwardingInfo.REASON_ALL,
+        CallForwardingInfo.REASON_ALL_CONDITIONAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallForwardingReason {
+    }
+
+    /**
+     * Call waiting function status
+     */
+    @IntDef(prefix = { "CALL_WAITING_STATUS_" }, value = {
+        TelephonyManager.CALL_WAITING_STATUS_ACTIVE,
+        TelephonyManager.CALL_WAITING_STATUS_INACTIVE,
+        TelephonyManager.CALL_WAITING_STATUS_NOT_SUPPORTED,
+        TelephonyManager.CALL_WAITING_STATUS_UNKNOWN_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CallWaitingStatus {
+    }
+
+    /**
      * UICC SIM Application Types
      */
     @IntDef(prefix = { "APPTYPE_" }, value = {
diff --git a/telephony/java/android/telephony/AnomalyReporter.java b/telephony/java/android/telephony/AnomalyReporter.java
index 097041f..ffdb23f 100644
--- a/telephony/java/android/telephony/AnomalyReporter.java
+++ b/telephony/java/android/telephony/AnomalyReporter.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
 import android.content.Context;
@@ -27,6 +25,7 @@
 import android.os.ParcelUuid;
 
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
diff --git a/telephony/java/android/telephony/CallForwardingInfo.aidl b/telephony/java/android/telephony/CallForwardingInfo.aidl
new file mode 100644
index 0000000..2019e07
--- /dev/null
+++ b/telephony/java/android/telephony/CallForwardingInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2020, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+parcelable CallForwardingInfo;
\ No newline at end of file
diff --git a/telephony/java/android/telephony/CallForwardingInfo.java b/telephony/java/android/telephony/CallForwardingInfo.java
new file mode 100644
index 0000000..33ad5e8
--- /dev/null
+++ b/telephony/java/android/telephony/CallForwardingInfo.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telephony.Annotation.CallForwardingReason;
+import android.telephony.Annotation.CallForwardingStatus;
+
+import java.util.Objects;
+
+/**
+ * Defines the call forwarding information.
+ * @hide
+ */
+@SystemApi
+public final class CallForwardingInfo implements Parcelable {
+    private static final String TAG = "CallForwardingInfo";
+
+    /**
+     * Indicates the call forwarding status is inactive.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int STATUS_INACTIVE = 0;
+
+    /**
+     * Indicates the call forwarding status is active.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int STATUS_ACTIVE = 1;
+
+    /**
+     * Indicates the call forwarding could not be enabled because the recipient is not on
+     * Fixed Dialing Number (FDN) list.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int STATUS_FDN_CHECK_FAILURE = 2;
+
+    /**
+     * Indicates the call forwarding status is with an unknown error.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int STATUS_UNKNOWN_ERROR = 3;
+
+    /**
+     * Indicates the call forwarding is not supported (e.g. called via CDMA).
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int STATUS_NOT_SUPPORTED = 4;
+
+    /**
+     * Indicates the call forwarding reason is "unconditional".
+     * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
+     *            and conditions +CCFC
+     * @hide
+     */
+    @SystemApi
+    public static final int REASON_UNCONDITIONAL = 0;
+
+    /**
+     * Indicates the call forwarding status is "busy".
+     * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
+     *            and conditions +CCFC
+     * @hide
+     */
+    @SystemApi
+    public static final int REASON_BUSY = 1;
+
+    /**
+     * Indicates the call forwarding reason is "no reply".
+     * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
+     *            and conditions +CCFC
+     * @hide
+     */
+    @SystemApi
+    public static final int REASON_NO_REPLY = 2;
+
+    /**
+     * Indicates the call forwarding reason is "not reachable".
+     * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
+     *            and conditions +CCFC
+     * @hide
+     */
+    @SystemApi
+    public static final int REASON_NOT_REACHABLE = 3;
+
+    /**
+     * Indicates the call forwarding reason is "all", for setting all call forwarding reasons
+     * simultaneously (unconditional, busy, no reply, and not reachable).
+     * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
+     *            and conditions +CCFC
+     * @hide
+     */
+    @SystemApi
+    public static final int REASON_ALL = 4;
+
+    /**
+     * Indicates the call forwarding reason is "all_conditional", for setting all conditional call
+     * forwarding reasons simultaneously (busy, no reply, and not reachable).
+     * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
+     *            and conditions +CCFC
+     * @hide
+     */
+    @SystemApi
+    public static final int REASON_ALL_CONDITIONAL = 5;
+
+    /**
+     * The call forwarding status.
+     */
+    private @CallForwardingStatus int mStatus;
+
+    /**
+     * The call forwarding reason indicates the condition under which calls will be forwarded.
+     * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
+     *            and conditions +CCFC
+     */
+    private @CallForwardingReason int mReason;
+
+    /**
+     * The phone number to which calls will be forwarded.
+     * Reference: 3GPP TS 27.007 version 10.3.0 Release 10 - 7.11 Call forwarding number
+     *            and conditions +CCFC
+     */
+    private String mNumber;
+
+    /**
+     * Gets the timeout (in seconds) before the forwarding is attempted.
+     */
+    private int mTimeSeconds;
+
+    /**
+     * Construct a CallForwardingInfo.
+     *
+     * @param status the call forwarding status
+     * @param reason the call forwarding reason
+     * @param number the phone number to which calls will be forwarded
+     * @param timeSeconds the timeout (in seconds) before the forwarding is attempted
+     * @hide
+     */
+    @SystemApi
+    public CallForwardingInfo(@CallForwardingStatus int status, @CallForwardingReason int reason,
+            @Nullable String number, int timeSeconds) {
+        mStatus = status;
+        mReason = reason;
+        mNumber = number;
+        mTimeSeconds = timeSeconds;
+    }
+
+    /**
+     * Returns the call forwarding status.
+     *
+     * @return the call forwarding status.
+     *
+     * @hide
+     */
+    @SystemApi
+    public @CallForwardingStatus int getStatus() {
+        return mStatus;
+    }
+
+    /**
+     * Returns the call forwarding reason. The call forwarding reason indicates the condition
+     * under which calls will be forwarded.  For example, {@link #REASON_NO_REPLY} indicates
+     * that calls will be forward to {@link #getNumber()} when the user fails to answer the call.
+     *
+     * @return the call forwarding reason.
+     *
+     * @hide
+     */
+    @SystemApi
+    public @CallForwardingReason int getReason() {
+        return mReason;
+    }
+
+    /**
+     * Returns the phone number to which calls will be forwarded.
+     *
+     * @return the number calls will be forwarded to, or {@code null} if call forwarding
+     * is being disabled.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getNumber() {
+        return mNumber;
+    }
+
+    /**
+     * Gets the timeout (in seconds) before the forwarding is attempted. For example,
+     * if {@link #REASON_NO_REPLY} is the call forwarding reason, the device will wait this
+     * duration of time before forwarding the call to {@link #getNumber()}.
+     *
+     * Reference: 3GPP TS 27.007 version 10.3.0 Release 10
+     *            7.11 Call forwarding number and conditions +CCFC
+     *
+     * @return the timeout (in seconds) before the forwarding is attempted.
+     *
+     * @hide
+     */
+    @SystemApi
+    @SuppressLint("MethodNameUnits")
+    public int getTimeoutSeconds() {
+        return mTimeSeconds;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mNumber);
+        out.writeInt(mStatus);
+        out.writeInt(mReason);
+        out.writeInt(mTimeSeconds);
+    }
+
+    private CallForwardingInfo(Parcel in) {
+        mNumber = in.readString();
+        mStatus = in.readInt();
+        mReason = in.readInt();
+        mTimeSeconds = in.readInt();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+
+        if (!(o instanceof CallForwardingInfo)) {
+            return false;
+        }
+
+        CallForwardingInfo other = (CallForwardingInfo) o;
+        return mStatus == other.mStatus
+                && mNumber == other.mNumber
+                && mReason == other.mReason
+                && mTimeSeconds == other.mTimeSeconds;
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mStatus, mNumber, mReason, mTimeSeconds);
+    }
+
+    public static final @NonNull Parcelable.Creator<CallForwardingInfo> CREATOR =
+            new Parcelable.Creator<CallForwardingInfo>() {
+                @Override
+                public CallForwardingInfo createFromParcel(Parcel in) {
+                    return new CallForwardingInfo(in);
+                }
+
+                @Override
+                public CallForwardingInfo[] newArray(int size) {
+                    return new CallForwardingInfo[size];
+                }
+            };
+
+    /**
+     * @hide
+     */
+    @Override
+    public String toString() {
+        return "[CallForwardingInfo: status=" + mStatus
+                + ", reason= " + mReason
+                + ", timeSec= " + mTimeSeconds + " seconds"
+                + ", number=" + Rlog.pii(TAG, mNumber) + "]";
+    }
+}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 71411d5..1eed0e0 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -2973,7 +2973,6 @@
     /**
      * Controls hysteresis time in milli seconds for which OpportunisticNetworkService
      * will wait before switching data from opportunistic network to primary network.
-     * @hide
      */
     public static final String KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_EXIT_HYSTERESIS_TIME_LONG =
             "opportunistic_network_data_switch_exit_hysteresis_time_long";
@@ -2981,17 +2980,58 @@
     /**
      * Controls whether to do ping test before switching data to opportunistic network.
      * This carrier config is used to disable this feature.
-     * @hide
      */
     public static final String KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL =
             "ping_test_before_data_switch_bool";
 
     /**
      * Controls time in milliseconds until DcTracker reevaluates 5G connection state.
-     * @hide
      */
     public static final String KEY_5G_WATCHDOG_TIME_MS_LONG =
             "5g_watchdog_time_long";
+    /**
+     * Controls whether to switch data to primary from opportunistic subscription
+     * if primary is out of service. This control only affects system or 1st party app
+     * initiated data switch, but will not override data switch initiated by privileged carrier apps
+     * This carrier config is used to disable this feature.
+     */
+    public static final String KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL =
+            "switch_data_to_primary_if_primary_is_oos_bool";
+
+    /**
+     * Controls the ping pong determination of opportunistic network.
+     * If opportunistic network is determined as out of service or below
+     * #KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSRP_INT or
+     * #KEY_OPPORTUNISTIC_NETWORK_EXIT_THRESHOLD_RSSNR_INT within
+     * #KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG of switching to opportunistic network,
+     * it will be determined as ping pong situation by system app or 1st party app.
+     */
+    public static final String KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG =
+            "opportunistic_network_ping_pong_time_long";
+    /**
+     * Controls back off time in milli seconds for switching back to
+     * opportunistic subscription. This time will be added to
+     * {@link CarrierConfigManager#KEY_OPPORTUNISTIC_NETWORK_DATA_SWITCH_HYSTERESIS_TIME_LONG} to
+     * determine hysteresis time if there is ping pong situation
+     * (determined by system app or 1st party app) between primary and opportunistic
+     * subscription. Ping ping situation is defined in
+     * #KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG.
+     * If ping pong situation continuous #KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG
+     * will be added to previously determined hysteresis time.
+     */
+    public static final String KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG =
+            "opportunistic_network_backoff_time_long";
+
+    /**
+     * Controls the max back off time in milli seconds for switching back to
+     * opportunistic subscription.
+     * This time will be the max hysteresis that can be determined irrespective of there is
+     * continuous ping pong situation or not as described in
+     * #KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG and
+     * #KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG.
+     */
+    public static final String KEY_OPPORTUNISTIC_NETWORK_MAX_BACKOFF_TIME_LONG =
+            "opportunistic_network_max_backoff_time_long";
 
     /**
      * Indicates zero or more emergency number prefix(es), because some carrier requires
@@ -3035,7 +3075,6 @@
      * validation result, this value defines customized value of how long we wait for validation
      * success before we fail and revoke the switch.
      * Time out is in milliseconds.
-     * @hide
      */
     public static final String KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG =
             "data_switch_validation_timeout_long";
@@ -3816,6 +3855,13 @@
         sDefaults.putBoolean(KEY_PING_TEST_BEFORE_DATA_SWITCH_BOOL, true);
         /* Default value is 1 hour. */
         sDefaults.putLong(KEY_5G_WATCHDOG_TIME_MS_LONG, 3600000);
+        sDefaults.putBoolean(KEY_SWITCH_DATA_TO_PRIMARY_IF_PRIMARY_IS_OOS_BOOL, true);
+        /* Default value is 60 seconds. */
+        sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_PING_PONG_TIME_LONG, 60000);
+        /* Default value is 10 seconds. */
+        sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_BACKOFF_TIME_LONG, 10000);
+        /* Default value is 60 seconds. */
+        sDefaults.putLong(KEY_OPPORTUNISTIC_NETWORK_MAX_BACKOFF_TIME_LONG, 60000);
         sDefaults.putAll(Gps.getDefaults());
         sDefaults.putIntArray(KEY_CDMA_ENHANCED_ROAMING_INDICATOR_FOR_HOME_NETWORK_INT_ARRAY,
                 new int[] {
diff --git a/telephony/java/android/telephony/CbGeoUtils.java b/telephony/java/android/telephony/CbGeoUtils.java
index 719ba8d..c0ae99e 100644
--- a/telephony/java/android/telephony/CbGeoUtils.java
+++ b/telephony/java/android/telephony/CbGeoUtils.java
@@ -16,13 +16,12 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.util.TelephonyUtils;
+import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index 399b1a4..0c2f1f3 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -71,8 +69,8 @@
     protected String mAlphaShort;
 
     /** @hide */
-    protected CellIdentity(String tag, int type, String mcc, String mnc, String alphal,
-                           String alphas) {
+    protected CellIdentity(@Nullable String tag, int type, @Nullable String mcc,
+            @Nullable String mnc, @Nullable String alphal, @Nullable String alphas) {
         mTag = tag;
         mType = type;
 
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 1a6bf33..e220b07 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -17,6 +17,7 @@
 package android.telephony;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.os.Parcel;
 import android.telephony.cdma.CdmaCellLocation;
 
@@ -90,8 +91,8 @@
      *
      * @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,
+            @Nullable String alphal, @Nullable String alphas) {
         super(TAG, CellInfo.TYPE_CDMA, null, null, alphal, alphas);
         mNetworkId = inRangeOrUnavailable(nid, 0, NETWORK_ID_MAX);
         mSystemId = inRangeOrUnavailable(sid, 0, SYSTEM_ID_MAX);
@@ -108,22 +109,22 @@
     }
 
     /** @hide */
-    public CellIdentityCdma(android.hardware.radio.V1_0.CellIdentityCdma cid) {
+    public CellIdentityCdma(@NonNull 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) {
+    public CellIdentityCdma(@NonNull 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) {
+    private CellIdentityCdma(@NonNull CellIdentityCdma cid) {
         this(cid.mNetworkId, cid.mSystemId, cid.mBasestationId, cid.mLongitude, cid.mLatitude,
                 cid.mAlphaLong, cid.mAlphaShort);
     }
 
-    CellIdentityCdma copy() {
+    @NonNull CellIdentityCdma copy() {
         return new CellIdentityCdma(this);
     }
 
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index dc73cbf..9f2537c 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -23,6 +23,7 @@
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -78,26 +79,31 @@
      *
      * @hide
      */
-    public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, String mccStr,
-                            String mncStr, String alphal, String alphas,
-                            List<String> additionalPlmns) {
+    public CellIdentityGsm(int lac, int cid, int arfcn, int bsic, @Nullable String mccStr,
+            @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
+            @NonNull List<String> additionalPlmns) {
         super(TAG, CellInfo.TYPE_GSM, mccStr, mncStr, alphal, alphas);
         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
         mArfcn = inRangeOrUnavailable(arfcn, 0, MAX_ARFCN);
         mBsic = inRangeOrUnavailable(bsic, 0, MAX_BSIC);
-        mAdditionalPlmns = additionalPlmns;
+        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        for (String plmn : additionalPlmns) {
+            if (isValidPlmn(plmn)) {
+                mAdditionalPlmns.add(plmn);
+            }
+        }
     }
 
     /** @hide */
-    public CellIdentityGsm(android.hardware.radio.V1_0.CellIdentityGsm cid) {
+    public CellIdentityGsm(@NonNull 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, "", "", Collections.emptyList());
     }
 
     /** @hide */
-    public CellIdentityGsm(android.hardware.radio.V1_2.CellIdentityGsm cid) {
+    public CellIdentityGsm(@NonNull 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,
@@ -105,7 +111,7 @@
     }
 
     /** @hide */
-    public CellIdentityGsm(android.hardware.radio.V1_5.CellIdentityGsm cid) {
+    public CellIdentityGsm(@NonNull android.hardware.radio.V1_5.CellIdentityGsm cid) {
         this(cid.base.base.lac, cid.base.base.cid, cid.base.base.arfcn,
                 cid.base.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE
                         : cid.base.base.bsic, cid.base.base.mcc,
@@ -113,12 +119,12 @@
                 cid.base.operatorNames.alphaShort, cid.additionalPlmns);
     }
 
-    private CellIdentityGsm(CellIdentityGsm cid) {
+    private CellIdentityGsm(@NonNull CellIdentityGsm cid) {
         this(cid.mLac, cid.mCid, cid.mArfcn, cid.mBsic, cid.mMccStr,
                 cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns);
     }
 
-    CellIdentityGsm copy() {
+    @NonNull CellIdentityGsm copy() {
         return new CellIdentityGsm(this);
     }
 
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index cf8fe6a..a194ae3 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -24,6 +24,7 @@
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -104,34 +105,40 @@
      *
      * @hide
      */
-    public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth, String mccStr,
-            String mncStr, String alphal, String alphas, List<String> additionalPlmns,
-            ClosedSubscriberGroupInfo csgInfo) {
+    public CellIdentityLte(int ci, int pci, int tac, int earfcn, int bandwidth,
+            @Nullable String mccStr, @Nullable String mncStr, @Nullable String alphal,
+            @Nullable String alphas, @NonNull List<String> additionalPlmns,
+            @Nullable ClosedSubscriberGroupInfo csgInfo) {
         super(TAG, CellInfo.TYPE_LTE, mccStr, mncStr, alphal, alphas);
         mCi = inRangeOrUnavailable(ci, 0, MAX_CI);
         mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
         mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
         mEarfcn = inRangeOrUnavailable(earfcn, 0, MAX_EARFCN);
         mBandwidth = inRangeOrUnavailable(bandwidth, 0, MAX_BANDWIDTH);
-        mAdditionalPlmns = additionalPlmns;
+        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        for (String plmn : additionalPlmns) {
+            if (isValidPlmn(plmn)) {
+                mAdditionalPlmns.add(plmn);
+            }
+        }
         mCsgInfo = csgInfo;
     }
 
     /** @hide */
-    public CellIdentityLte(android.hardware.radio.V1_0.CellIdentityLte cid) {
+    public CellIdentityLte(@NonNull android.hardware.radio.V1_0.CellIdentityLte cid) {
         this(cid.ci, cid.pci, cid.tac, cid.earfcn,
                 CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "", Collections.emptyList(), null);
     }
 
     /** @hide */
-    public CellIdentityLte(android.hardware.radio.V1_2.CellIdentityLte cid) {
+    public CellIdentityLte(@NonNull 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, Collections.emptyList(), null);
     }
 
     /** @hide */
-    public CellIdentityLte(android.hardware.radio.V1_5.CellIdentityLte cid) {
+    public CellIdentityLte(@NonNull android.hardware.radio.V1_5.CellIdentityLte cid) {
         this(cid.base.base.ci, cid.base.base.pci, cid.base.base.tac, cid.base.base.earfcn,
                 cid.base.bandwidth, cid.base.base.mcc, cid.base.base.mnc,
                 cid.base.operatorNames.alphaLong, cid.base.operatorNames.alphaShort,
@@ -139,7 +146,7 @@
                         ? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null);
     }
 
-    private CellIdentityLte(CellIdentityLte cid) {
+    private CellIdentityLte(@NonNull CellIdentityLte cid) {
         this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBandwidth, cid.mMccStr,
                 cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
     }
@@ -152,7 +159,7 @@
                 mMccStr, mMncStr, mAlphaLong, mAlphaShort, mAdditionalPlmns, null);
     }
 
-    CellIdentityLte copy() {
+    @NonNull CellIdentityLte copy() {
         return new CellIdentityLte(this);
     }
 
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index d4f181f..a0ef5aa 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -64,26 +64,32 @@
      * @hide
      */
     public CellIdentityNr(int pci, int tac, int nrArfcn, @NgranBand List<Integer> bands,
-                          String mccStr, String mncStr, long nci, String alphal, String alphas,
-                          List<String> additionalPlmns) {
+                          @Nullable String mccStr, @Nullable String mncStr, long nci,
+                          @Nullable String alphal, @Nullable String alphas,
+                          @NonNull List<String> additionalPlmns) {
         super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas);
         mPci = inRangeOrUnavailable(pci, 0, MAX_PCI);
         mTac = inRangeOrUnavailable(tac, 0, MAX_TAC);
         mNrArfcn = inRangeOrUnavailable(nrArfcn, 0, MAX_NRARFCN);
         mBands = new ArrayList<>(bands);
         mNci = inRangeOrUnavailable(nci, 0, MAX_NCI);
-        mAdditionalPlmns = new ArrayList<>(additionalPlmns);
+        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        for (String plmn : additionalPlmns) {
+            if (isValidPlmn(plmn)) {
+                mAdditionalPlmns.add(plmn);
+            }
+        }
     }
 
     /** @hide */
-    public CellIdentityNr(android.hardware.radio.V1_4.CellIdentityNr cid) {
+    public CellIdentityNr(@NonNull android.hardware.radio.V1_4.CellIdentityNr cid) {
         this(cid.pci, cid.tac, cid.nrarfcn, Collections.emptyList(), cid.mcc, cid.mnc, cid.nci,
                 cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
                 Collections.emptyList());
     }
 
     /** @hide */
-    public CellIdentityNr(android.hardware.radio.V1_5.CellIdentityNr cid) {
+    public CellIdentityNr(@NonNull android.hardware.radio.V1_5.CellIdentityNr cid) {
         this(cid.base.pci, cid.base.tac, cid.base.nrarfcn, cid.bands, cid.base.mcc, cid.base.mnc,
                 cid.base.nci, cid.base.operatorNames.alphaLong,
                 cid.base.operatorNames.alphaShort, cid.additionalPlmns);
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 2ff351c..531487a 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -21,6 +21,7 @@
 import android.os.Parcel;
 import android.telephony.gsm.GsmCellLocation;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -82,39 +83,44 @@
      *
      * @hide
      */
-    public CellIdentityTdscdma(String mcc, String mnc, int lac, int cid, int cpid, int uarfcn,
-            String alphal, String alphas, @NonNull List<String> additionalPlmns,
-            ClosedSubscriberGroupInfo csgInfo) {
+    public CellIdentityTdscdma(@Nullable String mcc, @Nullable String mnc, int lac, int cid,
+            int cpid, int uarfcn, @Nullable String alphal, @Nullable String alphas,
+            @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
         super(TAG, CellInfo.TYPE_TDSCDMA, mcc, mnc, alphal, alphas);
         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
         mCpid = inRangeOrUnavailable(cpid, 0, MAX_CPID);
         mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
-        mAdditionalPlmns = additionalPlmns;
+        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        for (String plmn : additionalPlmns) {
+            if (isValidPlmn(plmn)) {
+                mAdditionalPlmns.add(plmn);
+            }
+        }
         mCsgInfo = csgInfo;
     }
 
-    private CellIdentityTdscdma(CellIdentityTdscdma cid) {
+    private CellIdentityTdscdma(@NonNull CellIdentityTdscdma cid) {
         this(cid.mMccStr, cid.mMncStr, cid.mLac, cid.mCid,
                 cid.mCpid, cid.mUarfcn, cid.mAlphaLong,
                 cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
     }
 
     /** @hide */
-    public CellIdentityTdscdma(android.hardware.radio.V1_0.CellIdentityTdscdma cid) {
+    public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_0.CellIdentityTdscdma cid) {
         this(cid.mcc, cid.mnc, cid.lac, cid.cid, cid.cpid, CellInfo.UNAVAILABLE, "", "",
                 Collections.emptyList(), null);
     }
 
     /** @hide */
-    public CellIdentityTdscdma(android.hardware.radio.V1_2.CellIdentityTdscdma cid) {
+    public CellIdentityTdscdma(@NonNull 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,
                 Collections.emptyList(), null);
     }
 
     /** @hide */
-    public CellIdentityTdscdma(android.hardware.radio.V1_5.CellIdentityTdscdma cid) {
+    public CellIdentityTdscdma(@NonNull android.hardware.radio.V1_5.CellIdentityTdscdma cid) {
         this(cid.base.base.mcc, cid.base.base.mnc, cid.base.base.lac, cid.base.base.cid,
                 cid.base.base.cpid, cid.base.uarfcn, cid.base.operatorNames.alphaLong,
                 cid.base.operatorNames.alphaShort,
@@ -130,7 +136,7 @@
                 mAdditionalPlmns, null);
     }
 
-    CellIdentityTdscdma copy() {
+    @NonNull CellIdentityTdscdma copy() {
         return new CellIdentityTdscdma(this);
     }
 
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 9be42a1..15e491b 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -23,6 +23,7 @@
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
 
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -83,34 +84,38 @@
      *
      * @hide
      */
-    public CellIdentityWcdma (int lac, int cid, int psc, int uarfcn,
-                              String mccStr, String mncStr, String alphal, String alphas,
-                              @NonNull List<String> additionalPlmns,
-                              @Nullable ClosedSubscriberGroupInfo csgInfo) {
+    public CellIdentityWcdma(int lac, int cid, int psc, int uarfcn, @Nullable String mccStr,
+            @Nullable String mncStr, @Nullable String alphal, @Nullable String alphas,
+            @NonNull List<String> additionalPlmns, @Nullable ClosedSubscriberGroupInfo csgInfo) {
         super(TAG, CellInfo.TYPE_WCDMA, mccStr, mncStr, alphal, alphas);
         mLac = inRangeOrUnavailable(lac, 0, MAX_LAC);
         mCid = inRangeOrUnavailable(cid, 0, MAX_CID);
         mPsc = inRangeOrUnavailable(psc, 0, MAX_PSC);
         mUarfcn = inRangeOrUnavailable(uarfcn, 0, MAX_UARFCN);
-        mAdditionalPlmns = additionalPlmns;
+        mAdditionalPlmns = new ArrayList<>(additionalPlmns.size());
+        for (String plmn : additionalPlmns) {
+            if (isValidPlmn(plmn)) {
+                mAdditionalPlmns.add(plmn);
+            }
+        }
         mCsgInfo = csgInfo;
     }
 
     /** @hide */
-    public CellIdentityWcdma(android.hardware.radio.V1_0.CellIdentityWcdma cid) {
+    public CellIdentityWcdma(@NonNull android.hardware.radio.V1_0.CellIdentityWcdma cid) {
         this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", "",
                 Collections.emptyList(), null);
     }
 
     /** @hide */
-    public CellIdentityWcdma(android.hardware.radio.V1_2.CellIdentityWcdma cid) {
+    public CellIdentityWcdma(@NonNull 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, Collections.emptyList(), null);
     }
 
     /** @hide */
-    public CellIdentityWcdma(android.hardware.radio.V1_5.CellIdentityWcdma cid) {
+    public CellIdentityWcdma(@NonNull android.hardware.radio.V1_5.CellIdentityWcdma cid) {
         this(cid.base.base.lac, cid.base.base.cid, cid.base.base.psc, cid.base.base.uarfcn,
                 cid.base.base.mcc, cid.base.base.mnc, cid.base.operatorNames.alphaLong,
                 cid.base.operatorNames.alphaShort, cid.additionalPlmns,
@@ -118,7 +123,7 @@
                         ? new ClosedSubscriberGroupInfo(cid.optionalCsgInfo.csgInfo()) : null);
     }
 
-    private CellIdentityWcdma(CellIdentityWcdma cid) {
+    private CellIdentityWcdma(@NonNull CellIdentityWcdma cid) {
         this(cid.mLac, cid.mCid, cid.mPsc, cid.mUarfcn, cid.mMccStr,
                 cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort, cid.mAdditionalPlmns, cid.mCsgInfo);
     }
@@ -131,7 +136,7 @@
                 mAlphaLong, mAlphaShort, mAdditionalPlmns, null);
     }
 
-    CellIdentityWcdma copy() {
+    @NonNull CellIdentityWcdma copy() {
         return new CellIdentityWcdma(this);
     }
 
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index acb21f4..0edb4a4 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 /**
  * A {@link CellInfo} representing a CDMA cell that provides identity and measurement info.
  */
diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java
index 79a9d44..2dddd3f 100644
--- a/telephony/java/android/telephony/CellInfoGsm.java
+++ b/telephony/java/android/telephony/CellInfoGsm.java
@@ -16,13 +16,13 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 /**
  * A {@link CellInfo} representing a GSM cell that provides identity and measurement info.
  */
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index fed3ebf..a57c7cd 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 import java.util.Objects;
 
 /**
diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java
index 58ff8c9..d2cc9c6c 100644
--- a/telephony/java/android/telephony/CellInfoTdscdma.java
+++ b/telephony/java/android/telephony/CellInfoTdscdma.java
@@ -16,12 +16,12 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 import java.util.Objects;
 
 /**
diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java
index 33f6a55..3f792d1 100644
--- a/telephony/java/android/telephony/CellInfoWcdma.java
+++ b/telephony/java/android/telephony/CellInfoWcdma.java
@@ -18,6 +18,7 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.android.telephony.Rlog;
 
 import java.util.Objects;
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index cab3b0c..1c92705b 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -20,6 +20,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
+
 import com.android.telephony.Rlog;
 
 import java.util.Objects;
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index 28052aa..76d2df9 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntRange;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -25,6 +23,8 @@
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.telephony.Rlog;
+
 import java.util.Objects;
 
 /**
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 2ef2a52..6d6eaa4 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntRange;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.telephony.Rlog;
+
 import java.util.Arrays;
 import java.util.Objects;
 
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index f4c13ff..e3d03a3 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
diff --git a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
index 3bd9d58..e96f200 100644
--- a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
 
+import com.android.telephony.Rlog;
+
 import java.util.Objects;
 
 /**
diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
index 535e952..8b14b74 100644
--- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntRange;
 import android.annotation.StringDef;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -26,6 +24,8 @@
 import android.os.PersistableBundle;
 import android.text.TextUtils;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.Objects;
diff --git a/telephony/java/android/telephony/NetworkScan.java b/telephony/java/android/telephony/NetworkScan.java
index c249ece..85f46d0 100644
--- a/telephony/java/android/telephony/NetworkScan.java
+++ b/telephony/java/android/telephony/NetworkScan.java
@@ -16,14 +16,13 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntDef;
 import android.content.Context;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
 import com.android.internal.telephony.ITelephony;
+import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/telephony/java/android/telephony/NetworkScanRequest.java b/telephony/java/android/telephony/NetworkScanRequest.java
index 465b6aa..c8b8ffb 100644
--- a/telephony/java/android/telephony/NetworkScanRequest.java
+++ b/telephony/java/android/telephony/NetworkScanRequest.java
@@ -20,10 +20,10 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
 
 /**
  * Defines a request to peform a network scan.
@@ -221,9 +221,15 @@
 
     private NetworkScanRequest(Parcel in) {
         mScanType = in.readInt();
-        mSpecifiers = (RadioAccessSpecifier[]) in.readParcelableArray(
-                Object.class.getClassLoader(),
-                RadioAccessSpecifier.class);
+        Parcelable[] tempSpecifiers = in.readParcelableArray(Object.class.getClassLoader());
+        if (tempSpecifiers != null) {
+            mSpecifiers = new RadioAccessSpecifier[tempSpecifiers.length];
+            for (int i = 0; i < tempSpecifiers.length; i++) {
+                mSpecifiers[i] = (RadioAccessSpecifier) tempSpecifiers[i];
+            }
+        } else {
+            mSpecifiers = null;
+        }
         mSearchPeriodicity = in.readInt();
         mMaxSearchTime = in.readInt();
         mIncrementalResults = in.readBoolean();
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index 844289c..87d94bfd 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -34,6 +32,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/telephony/java/android/telephony/NetworkServiceCallback.java b/telephony/java/android/telephony/NetworkServiceCallback.java
index 214ab41..e8e73ee 100644
--- a/telephony/java/android/telephony/NetworkServiceCallback.java
+++ b/telephony/java/android/telephony/NetworkServiceCallback.java
@@ -16,14 +16,14 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.RemoteException;
 import android.telephony.NetworkService.NetworkServiceProvider;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
diff --git a/telephony/java/android/telephony/PhoneNumberRange.java b/telephony/java/android/telephony/PhoneNumberRange.java
index e6f107e..2b199d2 100644
--- a/telephony/java/android/telephony/PhoneNumberRange.java
+++ b/telephony/java/android/telephony/PhoneNumberRange.java
@@ -85,18 +85,18 @@
     }
 
     private PhoneNumberRange(Parcel in) {
-        mCountryCode = in.readStringNoHelper();
-        mPrefix = in.readStringNoHelper();
-        mLowerBound = in.readStringNoHelper();
-        mUpperBound = in.readStringNoHelper();
+        mCountryCode = in.readString();
+        mPrefix = in.readString();
+        mLowerBound = in.readString();
+        mUpperBound = in.readString();
     }
 
     @Override
     public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStringNoHelper(mCountryCode);
-        dest.writeStringNoHelper(mPrefix);
-        dest.writeStringNoHelper(mLowerBound);
-        dest.writeStringNoHelper(mUpperBound);
+        dest.writeString(mCountryCode);
+        dest.writeString(mPrefix);
+        dest.writeString(mLowerBound);
+        dest.writeString(mUpperBound);
     }
 
     @Override
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 0074772..ec99408 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -45,6 +43,7 @@
 import com.android.i18n.phonenumbers.PhoneNumberUtil;
 import com.android.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
 import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber;
+import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 8d9b1dd..952e8fb 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
 
 import android.Manifest;
@@ -40,13 +38,13 @@
 import com.android.internal.telephony.SmsMessageBase;
 import com.android.internal.telephony.SmsMessageBase.SubmitPduBase;
 import com.android.internal.telephony.cdma.sms.UserData;
+import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 
-
 /**
  * A Short Message Service message.
  * @see android.provider.Telephony.Sms.Intents#getMessagesFromIntent
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 2d8e237..832771d 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -40,6 +38,7 @@
 import android.util.Log;
 
 import com.android.internal.telephony.util.TelephonyUtils;
+import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -685,8 +684,8 @@
             int id = source.readInt();
             String iccId = source.readString();
             int simSlotIndex = source.readInt();
-            CharSequence displayName = source.readCharSequence();
-            CharSequence carrierName = source.readCharSequence();
+            CharSequence displayName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
+            CharSequence carrierName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
             int nameSource = source.readInt();
             int iconTint = source.readInt();
             String number = source.readString();
@@ -705,8 +704,8 @@
             int carrierid = source.readInt();
             int profileClass = source.readInt();
             int subType = source.readInt();
-            String[] ehplmns = source.readStringArray();
-            String[] hplmns = source.readStringArray();
+            String[] ehplmns = source.createStringArray();
+            String[] hplmns = source.createStringArray();
             String groupOwner = source.readString();
             UiccAccessRule[] carrierConfigAccessRules = source.createTypedArray(
                 UiccAccessRule.CREATOR);
@@ -732,8 +731,8 @@
         dest.writeInt(mId);
         dest.writeString(mIccId);
         dest.writeInt(mSimSlotIndex);
-        dest.writeCharSequence(mDisplayName);
-        dest.writeCharSequence(mCarrierName);
+        TextUtils.writeToParcel(mDisplayName, dest, 0);
+        TextUtils.writeToParcel(mCarrierName, dest, 0);
         dest.writeInt(mNameSource);
         dest.writeInt(mIconTint);
         dest.writeString(mNumber);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index ea95aac..519856c 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED;
 import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED;
 
@@ -67,6 +65,7 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.util.HandlerExecutor;
 import com.android.internal.util.Preconditions;
+import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 3ac357a..67e036d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -71,7 +71,9 @@
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.Annotation.ApnType;
+import android.telephony.Annotation.CallForwardingReason;
 import android.telephony.Annotation.CallState;
+import android.telephony.Annotation.CallWaitingStatus;
 import android.telephony.Annotation.NetworkType;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.Annotation.SimActivationState;
@@ -7655,6 +7657,36 @@
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
      * app has carrier privileges (see {@link #hasCarrierPrivileges}).
      *
+     * @param operatorNumeric the PLMN ID of the network to select.
+     * @param ran the initial suggested radio access network type.
+     *         If registration fails, the RAN is not available after, the RAN is not within the
+     *         network types specified by {@link #setPreferredNetworkTypeBitmask}, or the value is
+     *         {@link AccessNetworkConstants.AccessNetworkType#UNKNOWN}, modem will select
+     *         the next best RAN for network registration.
+     * @param persistSelection whether the selection will persist until reboot.
+     *         If true, only allows attaching to the selected PLMN until reboot; otherwise,
+     *         attach to the chosen PLMN and resume normal network selection next time.
+     * @return {@code true} on success; {@code false} on any failure.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @SystemApi
+    public boolean setNetworkSelectionModeManual(@NonNull String operatorNumeric,
+            @AccessNetworkConstants.RadioAccessNetworkType int ran, boolean persistSelection) {
+        return setNetworkSelectionModeManual(new OperatorInfo("" /* operatorAlphaLong */,
+                "" /* operatorAlphaShort */, operatorNumeric, ran), persistSelection);
+    }
+
+    /**
+     * Ask the radio to connect to the input network and change selection mode to manual.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
+     * app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     *
      * @param operatorInfo included the PLMN id, long name, short name of the operator to attach to.
      * @param persistSelection whether the selection will persist until reboot. If true, only allows
      * attaching to the selected PLMN until reboot; otherwise, attach to the chosen PLMN and resume
@@ -9835,7 +9867,8 @@
      * {@link android.telephony.ModemActivityInfo} object.
      * @hide
      */
-    public void requestModemActivityInfo(ResultReceiver result) {
+    @SystemApi
+    public void requestModemActivityInfo(@NonNull ResultReceiver result) {
         try {
             ITelephony service = getITelephony();
             if (service != null) {
@@ -12171,6 +12204,191 @@
     }
 
     /**
+     * Gets the voice call forwarding info {@link CallForwardingInfo}, given the call forward
+     * reason.
+     *
+     * @param callForwardingReason the call forwarding reasons
+     *
+     * @throws IllegalArgumentException if callForwardingReason is not any of
+     * {@link CallForwardingInfo.REASON_UNCONDITIONAL}, {@link CallForwardingInfo.REASON_BUSY},
+     * {@link CallForwardingInfo.REASON_NO_REPLY}, {@link CallForwardingInfo.REASON_NOT_REACHABLE},
+     * {@link CallForwardingInfo.REASON_ALL}, {@link CallForwardingInfo.REASON_ALL_CONDITIONAL}
+     *
+     * @return {@link CallForwardingInfo} with the status {@link CallForwardingInfo#STATUS_ACTIVE}
+     * or {@link CallForwardingInfo#STATUS_INACTIVE} and the target phone number to forward calls
+     * to, if it's available. Otherwise, it will return a {@link CallForwardingInfo} with status
+     * {@link CallForwardingInfo#STATUS_UNKNOWN_ERROR},
+     * {@link CallForwardingInfo#STATUS_NOT_SUPPORTED},
+     * or {@link CallForwardingInfo#STATUS_FDN_CHECK_FAILURE} depending on the situation.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @NonNull
+    public CallForwardingInfo getCallForwarding(@CallForwardingReason int callForwardingReason) {
+        if (callForwardingReason < CallForwardingInfo.REASON_UNCONDITIONAL
+                || callForwardingReason > CallForwardingInfo.REASON_ALL_CONDITIONAL) {
+            throw new IllegalArgumentException("callForwardingReason is out of range");
+        }
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getCallForwarding(getSubId(), callForwardingReason);
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "getCallForwarding RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "getCallForwarding NPE", ex);
+        }
+        return new CallForwardingInfo(
+                CallForwardingInfo.STATUS_UNKNOWN_ERROR, 0 /* reason */, null /* number */,
+                        0 /* timeout */);
+    }
+
+    /**
+     * Sets the voice call forwarding info including status (enable/disable), call forwarding
+     * reason, the number to forward, and the timeout before the forwarding is attempted.
+     *
+     * @param callForwardingInfo {@link CallForwardingInfo} to setup the call forwarding.
+     * Enabling if {@link CallForwardingInfo#getStatus()} returns
+     * {@link CallForwardingInfo#STATUS_ACTIVE}; Disabling if
+     * {@link CallForwardingInfo#getStatus()} returns {@link CallForwardingInfo#STATUS_INACTIVE}.
+     *
+     * @throws IllegalArgumentException if any of the following for parameter callForwardingInfo:
+     * 0) it is {@code null}.
+     * 1) {@link CallForwardingInfo#getStatus()} returns neither
+     * {@link CallForwardingInfo#STATUS_ACTIVE} nor {@link CallForwardingInfo#STATUS_INACTIVE}.
+     * 2) {@link CallForwardingInfo#getReason()} is not any of
+     * {@link CallForwardingInfo.REASON_UNCONDITIONAL}, {@link CallForwardingInfo.REASON_BUSY},
+     * {@link CallForwardingInfo.REASON_NO_REPLY}, {@link CallForwardingInfo.REASON_NOT_REACHABLE},
+     * {@link CallForwardingInfo.REASON_ALL}, {@link CallForwardingInfo.REASON_ALL_CONDITIONAL}
+     * 3) {@link CallForwardingInfo#getNumber()} returns {@code null}.
+     * 4) {@link CallForwardingInfo#getTimeoutSeconds()} doesn't return a positive value.
+     *
+     * @return {@code true} to indicate it was set successfully; {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean setCallForwarding(@NonNull CallForwardingInfo callForwardingInfo) {
+        if (callForwardingInfo == null) {
+            throw new IllegalArgumentException("callForwardingInfo is null");
+        }
+        int callForwardingStatus = callForwardingInfo.getStatus();
+        if (callForwardingStatus != CallForwardingInfo.STATUS_ACTIVE
+                && callForwardingStatus != CallForwardingInfo.STATUS_INACTIVE) {
+            throw new IllegalArgumentException(
+                    "callForwardingStatus is neither active nor inactive");
+        }
+        int callForwardingReason = callForwardingInfo.getReason();
+        if (callForwardingReason < CallForwardingInfo.REASON_UNCONDITIONAL
+                || callForwardingReason > CallForwardingInfo.REASON_ALL_CONDITIONAL) {
+            throw new IllegalArgumentException("callForwardingReason is out of range");
+        }
+        if (callForwardingInfo.getNumber() == null) {
+            throw new IllegalArgumentException("callForwarding number is null");
+        }
+        if (callForwardingInfo.getTimeoutSeconds() <= 0) {
+            throw new IllegalArgumentException("callForwarding timeout isn't positive");
+        }
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.setCallForwarding(getSubId(), callForwardingInfo);
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setCallForwarding RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "setCallForwarding NPE", ex);
+        }
+        return false;
+    }
+
+    /**
+     * Indicates the call waiting status is active.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int CALL_WAITING_STATUS_ACTIVE = 1;
+
+    /**
+     * Indicates the call waiting status is inactive.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int CALL_WAITING_STATUS_INACTIVE = 2;
+
+    /**
+     * Indicates the call waiting status is with an unknown error.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int CALL_WAITING_STATUS_UNKNOWN_ERROR = 3;
+
+    /**
+     * Indicates the call waiting is not supported (e.g. called via CDMA).
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final int CALL_WAITING_STATUS_NOT_SUPPORTED = 4;
+
+    /**
+     * Gets the status of voice call waiting function. Call waiting function enables the waiting
+     * for the incoming call when it reaches the user who is busy to make another call and allows
+     * users to decide whether to switch to the incoming call.
+     *
+     * @return the status of call waiting function.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public @CallWaitingStatus int getCallWaitingStatus() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getCallWaitingStatus(getSubId());
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "getCallWaitingStatus RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "getCallWaitingStatus NPE", ex);
+        }
+        return CALL_WAITING_STATUS_UNKNOWN_ERROR;
+    }
+
+    /**
+     * Sets the status for voice call waiting function. Call waiting function enables the waiting
+     * for the incoming call when it reaches the user who is busy to make another call and allows
+     * users to decide whether to switch to the incoming call.
+     *
+     * @param isEnable {@code true} to enable; {@code false} to disable.
+     * @return {@code true} to indicate it was set successfully; {@code false} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public boolean setCallWaitingStatus(boolean isEnable) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.setCallWaitingStatus(getSubId(), isEnable);
+            }
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setCallWaitingStatus RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "setCallWaitingStatus NPE", ex);
+        }
+        return false;
+    }
+
+    /**
      * Set allowing mobile data during voice call.
      *
      * @param allow {@code true} if allowing using data during voice call, {@code false} if
diff --git a/telephony/java/android/telephony/TelephonyScanManager.java b/telephony/java/android/telephony/TelephonyScanManager.java
index 1651c81..359d08d 100644
--- a/telephony/java/android/telephony/TelephonyScanManager.java
+++ b/telephony/java/android/telephony/TelephonyScanManager.java
@@ -16,8 +16,6 @@
 
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.content.Context;
@@ -34,6 +32,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.telephony.ITelephony;
+import com.android.telephony.Rlog;
 
 import java.util.Arrays;
 import java.util.List;
diff --git a/telephony/java/android/telephony/UiccAccessRule.java b/telephony/java/android/telephony/UiccAccessRule.java
index 81a09c6..3e948fc 100644
--- a/telephony/java/android/telephony/UiccAccessRule.java
+++ b/telephony/java/android/telephony/UiccAccessRule.java
@@ -15,8 +15,6 @@
  */
 package android.telephony;
 
-import com.android.telephony.Rlog;
-
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -28,6 +26,7 @@
 import android.text.TextUtils;
 
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.telephony.Rlog;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
diff --git a/telephony/java/android/telephony/VoLteServiceState.java b/telephony/java/android/telephony/VoLteServiceState.java
index 6b15443..078059e 100644
--- a/telephony/java/android/telephony/VoLteServiceState.java
+++ b/telephony/java/android/telephony/VoLteServiceState.java
@@ -17,12 +17,13 @@
 package android.telephony;
 
 import android.compat.annotation.UnsupportedAppUsage;
-import com.android.telephony.Rlog;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import com.android.telephony.Rlog;
+
 /**
  * Contains LTE network state related information.
  * @deprecated Only contains SRVCC state, which isn't specific to LTE handovers. For SRVCC
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index fab1bf2..de4b611 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -28,13 +28,14 @@
 import android.provider.Telephony.Carriers;
 import android.telephony.Annotation.ApnType;
 import android.telephony.Annotation.NetworkType;
-import com.android.telephony.Rlog;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.net.InetAddress;
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index bff12b6..6c4e7ce 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -31,10 +31,10 @@
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.AccessNetworkConstants;
-import com.android.telephony.Rlog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index d33d3f9..72b68e4 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -22,9 +22,10 @@
 import android.annotation.SystemApi;
 import android.net.LinkProperties;
 import android.os.RemoteException;
-import com.android.telephony.Rlog;
 import android.telephony.data.DataService.DataServiceProvider;
 
+import com.android.telephony.Rlog;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.List;
diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java
index 8220b16..05971c4 100644
--- a/telephony/java/android/telephony/data/QualifiedNetworksService.java
+++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java
@@ -28,10 +28,10 @@
 import android.os.RemoteException;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.Annotation.ApnType;
-import com.android.telephony.Rlog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.telephony.Rlog;
 
 import java.util.List;
 
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
index cd3fc95..d9d5c14 100644
--- a/telephony/java/android/telephony/emergency/EmergencyNumber.java
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -25,6 +25,7 @@
 import android.os.Parcelable;
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
+
 import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java
index abfee61..21bef00 100644
--- a/telephony/java/android/telephony/ims/ImsConferenceState.java
+++ b/telephony/java/android/telephony/ims/ImsConferenceState.java
@@ -24,8 +24,8 @@
 import android.os.Parcelable;
 import android.telecom.Call;
 import android.telecom.Connection;
+
 import com.android.telephony.Rlog;
-import android.util.Log;
 
 import java.util.HashMap;
 import java.util.Iterator;
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index 136a83e..7d73165 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -24,6 +24,7 @@
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index ba8e90f..494009f 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -163,9 +163,13 @@
             public void onCapabilitiesStatusChanged(int config) {
                 if (mLocalCallback == null) return;
 
-                Binder.withCleanCallingIdentity(() ->
-                        mExecutor.execute(() -> mLocalCallback.onCapabilitiesStatusChanged(
-                                new MmTelFeature.MmTelCapabilities(config))));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mLocalCallback.onCapabilitiesStatusChanged(
+                            new MmTelFeature.MmTelCapabilities(config)));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
 
             @Override
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 5aa37bb..917f91f 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -75,9 +75,13 @@
             public void onCapabilitiesStatusChanged(int config) {
                 if (mLocalCallback == null) return;
 
-                Binder.withCleanCallingIdentity(() ->
-                        mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(
-                                new RcsFeature.RcsImsCapabilities(config))));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mLocalCallback.onAvailabilityChanged(
+                            new RcsFeature.RcsImsCapabilities(config)));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
 
             @Override
diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java
index 2d2e638..70bf0c5 100644
--- a/telephony/java/android/telephony/ims/ImsSsData.java
+++ b/telephony/java/android/telephony/ims/ImsSsData.java
@@ -22,6 +22,7 @@
 import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index aa4f77d..6125001 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -791,17 +791,24 @@
 
             @Override
             public final void onIntConfigChanged(int item, int value) {
-                Binder.withCleanCallingIdentity(() ->
-                        mExecutor.execute(() ->
-                                mLocalConfigurationCallback.onProvisioningIntChanged(item, value)));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() ->
+                            mLocalConfigurationCallback.onProvisioningIntChanged(item, value));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
 
             @Override
             public final void onStringConfigChanged(int item, String value) {
-                Binder.withCleanCallingIdentity(() ->
-                        mExecutor.execute(() ->
-                                mLocalConfigurationCallback.onProvisioningStringChanged(item,
-                                        value)));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() ->
+                            mLocalConfigurationCallback.onProvisioningStringChanged(item, value));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
 
             private void setExecutor(Executor executor) {
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index d3f393a..5e3847f 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -251,15 +251,22 @@
         IRcsUceControllerCallback internalCallback = new IRcsUceControllerCallback.Stub() {
             @Override
             public void onCapabilitiesReceived(List<RcsContactUceCapability> contactCapabilities) {
-                Binder.withCleanCallingIdentity(() ->
-                        executor.execute(() ->
-                                c.onCapabilitiesReceived(contactCapabilities)));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() ->
+                            c.onCapabilitiesReceived(contactCapabilities));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
             @Override
             public void onError(int errorCode) {
-                Binder.withCleanCallingIdentity(() ->
-                        executor.execute(() ->
-                                c.onError(errorCode)));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    executor.execute(() -> c.onError(errorCode));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
         };
 
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
index a1f6b78..5c86ba7 100644
--- a/telephony/java/android/telephony/ims/RegistrationManager.java
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -105,41 +105,62 @@
             public void onRegistered(int imsRadioTech) {
                 if (mLocalCallback == null) return;
 
-                Binder.withCleanCallingIdentity(() -> mExecutor.execute(() ->
-                        mLocalCallback.onRegistered(getAccessType(imsRadioTech))));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() ->
+                            mLocalCallback.onRegistered(getAccessType(imsRadioTech)));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
 
             @Override
             public void onRegistering(int imsRadioTech) {
                 if (mLocalCallback == null) return;
 
-                Binder.withCleanCallingIdentity(() -> mExecutor.execute(() ->
-                        mLocalCallback.onRegistering(getAccessType(imsRadioTech))));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() ->
+                            mLocalCallback.onRegistering(getAccessType(imsRadioTech)));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
 
             @Override
             public void onDeregistered(ImsReasonInfo info) {
                 if (mLocalCallback == null) return;
 
-                Binder.withCleanCallingIdentity(() ->
-                        mExecutor.execute(() -> mLocalCallback.onUnregistered(info)));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mLocalCallback.onUnregistered(info));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
 
             @Override
             public void onTechnologyChangeFailed(int imsRadioTech, ImsReasonInfo info) {
                 if (mLocalCallback == null) return;
 
-                Binder.withCleanCallingIdentity(() ->
-                        mExecutor.execute(() -> mLocalCallback.onTechnologyChangeFailed(
-                                getAccessType(imsRadioTech), info)));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mLocalCallback.onTechnologyChangeFailed(
+                            getAccessType(imsRadioTech), info));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
 
             public void onSubscriberAssociatedUriChanged(Uri[] uris) {
                 if (mLocalCallback == null) return;
 
-                Binder.withCleanCallingIdentity(() ->
-                        mExecutor.execute(() ->
-                                mLocalCallback.onSubscriberAssociatedUriChanged(uris)));
+                long callingIdentity = Binder.clearCallingIdentity();
+                try {
+                    mExecutor.execute(() -> mLocalCallback.onSubscriberAssociatedUriChanged(uris));
+                } finally {
+                    restoreCallingIdentity(callingIdentity);
+                }
             }
 
             private void setExecutor(Executor executor) {
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 5d102cb4..e5779b3 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -22,7 +22,6 @@
 import android.annotation.TestApi;
 import android.content.Context;
 import android.os.IInterface;
-import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.telephony.SubscriptionManager;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
@@ -31,6 +30,7 @@
 
 import com.android.ims.internal.IImsFeatureStatusCallback;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.util.RemoteCallbackListExt;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -326,12 +326,12 @@
     /** @hide */
     protected final Object mLock = new Object();
 
-    private final RemoteCallbackList<IImsFeatureStatusCallback> mStatusCallbacks =
-            new RemoteCallbackList<>();
+    private final RemoteCallbackListExt<IImsFeatureStatusCallback> mStatusCallbacks =
+            new RemoteCallbackListExt<>();
     private @ImsState int mState = STATE_UNAVAILABLE;
     private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-    private final RemoteCallbackList<IImsCapabilityCallback> mCapabilityCallbacks =
-            new RemoteCallbackList<>();
+    private final RemoteCallbackListExt<IImsCapabilityCallback> mCapabilityCallbacks =
+            new RemoteCallbackListExt<>();
     private Capabilities mCapabilityStatus = new Capabilities();
 
     /**
@@ -412,7 +412,7 @@
      * Internal method called by ImsFeature when setFeatureState has changed.
      */
     private void notifyFeatureState(@ImsState int state) {
-        mStatusCallbacks.broadcast((c) -> {
+        mStatusCallbacks.broadcastAction((c) -> {
             try {
                 c.notifyImsFeatureStatus(state);
             } catch (RemoteException e) {
@@ -491,7 +491,7 @@
         synchronized (mLock) {
             mCapabilityStatus = caps.copy();
         }
-        mCapabilityCallbacks.broadcast((callback) -> {
+        mCapabilityCallbacks.broadcastAction((callback) -> {
             try {
                 callback.onCapabilitiesStatusChanged(caps.mCapabilities);
             } catch (RemoteException e) {
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index e4efc2043..8e67621 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -22,7 +22,6 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.net.Uri;
-import android.os.Binder;
 import android.os.RemoteException;
 import android.telephony.ims.RcsContactUceCapability;
 import android.telephony.ims.aidl.IImsCapabilityCallback;
@@ -33,7 +32,7 @@
 import android.telephony.ims.stub.RcsSipOptionsImplBase;
 import android.util.Log;
 
-import com.android.internal.util.FunctionalUtils;
+import com.android.internal.telephony.util.TelephonyUtils;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -43,6 +42,7 @@
 import java.util.concurrent.CompletionException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
+import java.util.function.Supplier;
 
 /**
  * Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend
@@ -150,13 +150,13 @@
 
         // Call the methods with a clean calling identity on the executor and wait indefinitely for
         // the future to return.
-        private void executeMethodAsync(FunctionalUtils.ThrowingRunnable r, String errorLogName)
+        private void executeMethodAsync(Runnable r, String errorLogName)
                 throws RemoteException {
             // call with a clean calling identity on the executor and wait indefinitely for the
             // future to return.
             try {
                 CompletableFuture.runAsync(
-                        () -> Binder.withCleanCallingIdentity(r), mExecutor).join();
+                        () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor).join();
             } catch (CancellationException | CompletionException e) {
                 Log.w(LOG_TAG, "RcsFeatureBinder - " + errorLogName + " exception: "
                         + e.getMessage());
@@ -164,12 +164,12 @@
             }
         }
 
-        private <T> T executeMethodAsyncForResult(FunctionalUtils.ThrowingSupplier<T> r,
+        private <T> T executeMethodAsyncForResult(Supplier<T> r,
                 String errorLogName) throws RemoteException {
             // call with a clean calling identity on the executor and wait indefinitely for the
             // future to return.
             CompletableFuture<T> future = CompletableFuture.supplyAsync(
-                    () -> Binder.withCleanCallingIdentity(r), mExecutor);
+                    () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor);
             try {
                 return future.get();
             } catch (ExecutionException | InterruptedException e) {
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index e0d576d..6a2638b 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -22,7 +22,6 @@
 import android.annotation.TestApi;
 import android.content.Context;
 import android.os.PersistableBundle;
-import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.telephony.ims.ProvisioningManager;
 import android.telephony.ims.aidl.IImsConfig;
@@ -31,6 +30,7 @@
 
 import com.android.ims.ImsConfig;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.util.RemoteCallbackListExt;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -257,7 +257,8 @@
     })
     public @interface SetConfigResult {}
 
-    private final RemoteCallbackList<IImsConfigCallback> mCallbacks = new RemoteCallbackList<>();
+    private final RemoteCallbackListExt<IImsConfigCallback> mCallbacks =
+            new RemoteCallbackListExt<>();
     ImsConfigStub mImsConfigStub;
 
     /**
@@ -298,7 +299,7 @@
         if (mCallbacks == null) {
             return;
         }
-        mCallbacks.broadcast(c -> {
+        mCallbacks.broadcastAction(c -> {
             try {
                 c.onIntConfigChanged(item, value);
             } catch (RemoteException e) {
@@ -312,7 +313,7 @@
         if (mCallbacks == null) {
             return;
         }
-        mCallbacks.broadcast(c -> {
+        mCallbacks.broadcastAction(c -> {
             try {
                 c.onStringConfigChanged(item, value);
             } catch (RemoteException e) {
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index c0f16e5..14a64d2 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -20,7 +20,6 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.net.Uri;
-import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.RegistrationManager;
@@ -29,6 +28,7 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.util.RemoteCallbackListExt;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -94,8 +94,8 @@
         }
     };
 
-    private final RemoteCallbackList<IImsRegistrationCallback> mCallbacks
-            = new RemoteCallbackList<>();
+    private final RemoteCallbackListExt<IImsRegistrationCallback> mCallbacks =
+            new RemoteCallbackListExt<>();
     private final Object mLock = new Object();
     // Locked on mLock
     private @ImsRegistrationTech
@@ -129,7 +129,7 @@
      */
     public final void onRegistered(@ImsRegistrationTech int imsRadioTech) {
         updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERED);
-        mCallbacks.broadcast((c) -> {
+        mCallbacks.broadcastAction((c) -> {
             try {
                 c.onRegistered(imsRadioTech);
             } catch (RemoteException e) {
@@ -147,7 +147,7 @@
      */
     public final void onRegistering(@ImsRegistrationTech int imsRadioTech) {
         updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERING);
-        mCallbacks.broadcast((c) -> {
+        mCallbacks.broadcastAction((c) -> {
             try {
                 c.onRegistering(imsRadioTech);
             } catch (RemoteException e) {
@@ -175,7 +175,7 @@
      */
     public final void onDeregistered(ImsReasonInfo info) {
         updateToDisconnectedState(info);
-        mCallbacks.broadcast((c) -> {
+        mCallbacks.broadcastAction((c) -> {
             try {
                 c.onDeregistered(info);
             } catch (RemoteException e) {
@@ -194,7 +194,7 @@
      */
     public final void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech,
             ImsReasonInfo info) {
-        mCallbacks.broadcast((c) -> {
+        mCallbacks.broadcastAction((c) -> {
             try {
                 c.onTechnologyChangeFailed(imsRadioTech, info);
             } catch (RemoteException e) {
@@ -210,7 +210,7 @@
      * @param uris
      */
     public final void onSubscriberAssociatedUriChanged(Uri[] uris) {
-        mCallbacks.broadcast((c) -> {
+        mCallbacks.broadcastAction((c) -> {
             try {
                 c.onSubscriberAssociatedUriChanged(uris);
             } catch (RemoteException e) {
diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java
index 0f6ce13..96f77d8 100644
--- a/telephony/java/com/android/ims/ImsConfig.java
+++ b/telephony/java/com/android/ims/ImsConfig.java
@@ -19,13 +19,13 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
-import com.android.telephony.Rlog;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ProvisioningManager;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsConfigCallback;
 
 import com.android.internal.telephony.util.HandlerExecutor;
+import com.android.telephony.Rlog;
 
 import java.util.concurrent.Executor;
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 1d794cd..d7fbafb 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -29,6 +29,7 @@
 import android.service.carrier.CarrierIdentifier;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
+import android.telephony.CallForwardingInfo;
 import android.telephony.CarrierRestrictionRules;
 import android.telephony.CellIdentity;
 import android.telephony.CellInfo;
@@ -1631,6 +1632,79 @@
     NetworkStats getVtDataUsage(int subId, boolean perUidStats);
 
     /**
+     * Gets the voice call forwarding info {@link CallForwardingInfo}, given the call forward
+     * reason.
+     *
+     * @param callForwardingReason the call forwarding reasons which are the bitwise-OR combination
+     * of the following constants:
+     * <ol>
+     * <li>{@link CallForwardingInfo#REASON_BUSY} </li>
+     * <li>{@link CallForwardingInfo#REASON_NO_REPLY} </li>
+     * <li>{@link CallForwardingInfo#REASON_NOT_REACHABLE} </li>
+     * </ol>
+     *
+     * @throws IllegalArgumentException if callForwardingReason is not a bitwise-OR combination
+     * of {@link CallForwardingInfo.REASON_BUSY}, {@link CallForwardingInfo.REASON_BUSY},
+     * {@link CallForwardingInfo.REASON_NOT_REACHABLE}
+     *
+     * @return {@link CallForwardingInfo} with the status {@link CallForwardingInfo#STATUS_ACTIVE}
+     * or {@link CallForwardingInfo#STATUS_INACTIVE} and the target phone number to forward calls
+     * to, if it's available. Otherwise, it will return a {@link CallForwardingInfo} with status
+     * {@link CallForwardingInfo#STATUS_NOT_SUPPORTED} or
+     * {@link CallForwardingInfo#STATUS_FDN_CHECK_FAILURE} depending on the situation.
+     *
+     * @hide
+     */
+    CallForwardingInfo getCallForwarding(int subId, int callForwardingReason);
+
+    /**
+     * Sets the voice call forwarding info including status (enable/disable), call forwarding
+     * reason, the number to forward, and the timeout before the forwarding is attempted.
+     *
+     * @param callForwardingInfo {@link CallForwardingInfo} to setup the call forwarding.
+     * Enabling if {@link CallForwardingInfo#getStatus()} returns
+     * {@link CallForwardingInfo#STATUS_ACTIVE}; Disabling if
+     * {@link CallForwardingInfo#getStatus()} returns {@link CallForwardingInfo#STATUS_INACTIVE}.
+     *
+     * @throws IllegalArgumentException if any of the following:
+     * 0) callForwardingInfo is null.
+     * 1) {@link CallForwardingInfo#getStatus()} for callForwardingInfo returns neither
+     * {@link CallForwardingInfo#STATUS_ACTIVE} nor {@link CallForwardingInfo#STATUS_INACTIVE}.
+     * 2) {@link CallForwardingInfo#getReason()} for callForwardingInfo doesn't return the
+     * bitwise-OR combination of {@link CallForwardingInfo.REASON_BUSY},
+     * {@link CallForwardingInfo.REASON_BUSY}, {@link CallForwardingInfo.REASON_NOT_REACHABLE}
+     * 3) {@link CallForwardingInfo#getNumber()} for callForwardingInfo returns null.
+     * 4) {@link CallForwardingInfo#getTimeout()} for callForwardingInfo returns nagetive value.
+     *
+     * @return {@code true} to indicate it was set successfully; {@code false} otherwise.
+     *
+     * @hide
+     */
+    boolean setCallForwarding(int subId, in CallForwardingInfo callForwardingInfo);
+
+    /**
+     * Gets the status of voice call waiting function. Call waiting function enables the waiting
+     * for the incoming call when it reaches the user who is busy to make another call and allows
+     * users to decide whether to switch to the incoming call.
+     *
+     * @return the status of call waiting function.
+     * @hide
+     */
+    int getCallWaitingStatus(int subId);
+
+    /**
+     * Sets the status for voice call waiting function. Call waiting function enables the waiting
+     * for the incoming call when it reaches the user who is busy to make another call and allows
+     * users to decide whether to switch to the incoming call.
+     *
+     * @param isEnable {@code true} to enable; {@code false} to disable.
+     * @return {@code true} to indicate it was set successfully; {@code false} otherwise.
+     *
+     * @hide
+     */
+    boolean setCallWaitingStatus(int subId, boolean isEnable);
+
+    /**
      * Policy control of data connection. Usually used when data limit is passed.
      * @param enabled True if enabling the data, otherwise disabling.
      * @param subId Subscription index
diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java
index 64d7863..2ca4598 100644
--- a/telephony/java/com/android/internal/telephony/OperatorInfo.java
+++ b/telephony/java/com/android/internal/telephony/OperatorInfo.java
@@ -20,6 +20,7 @@
 import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
 
 /**
  * @hide
@@ -43,6 +44,7 @@
 
     @UnsupportedAppUsage
     private State mState = State.UNKNOWN;
+    private int mRan = AccessNetworkType.UNKNOWN;
 
 
     @UnsupportedAppUsage
@@ -69,6 +71,10 @@
         return mState;
     }
 
+    public int getRan() {
+        return mRan;
+    }
+
     @UnsupportedAppUsage
     OperatorInfo(String operatorAlphaLong,
                 String operatorAlphaShort,
@@ -82,6 +88,14 @@
         mState = state;
     }
 
+    OperatorInfo(String operatorAlphaLong,
+                String operatorAlphaShort,
+                String operatorNumeric,
+                State state,
+                int ran) {
+        this (operatorAlphaLong, operatorAlphaShort, operatorNumeric, state);
+        mRan = ran;
+    }
 
     @UnsupportedAppUsage
     public OperatorInfo(String operatorAlphaLong,
@@ -92,6 +106,14 @@
                 operatorNumeric, rilStateToState(stateString));
     }
 
+    public OperatorInfo(String operatorAlphaLong,
+                String operatorAlphaShort,
+                String operatorNumeric,
+                int ran) {
+        this (operatorAlphaLong, operatorAlphaShort, operatorNumeric);
+        mRan = ran;
+    }
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public OperatorInfo(String operatorAlphaLong,
             String operatorAlphaShort,
@@ -124,7 +146,8 @@
         return "OperatorInfo " + mOperatorAlphaLong
                 + "/" + mOperatorAlphaShort
                 + "/" + mOperatorNumeric
-                + "/" + mState;
+                + "/" + mState
+                + "/" + mRan;
     }
 
     /**
@@ -150,6 +173,7 @@
         dest.writeString(mOperatorAlphaShort);
         dest.writeString(mOperatorNumeric);
         dest.writeSerializable(mState);
+        dest.writeInt(mRan);
     }
 
     /**
@@ -158,20 +182,21 @@
      */
     @UnsupportedAppUsage
     public static final Creator<OperatorInfo> CREATOR =
-        new Creator<OperatorInfo>() {
-            @Override
-            public OperatorInfo createFromParcel(Parcel in) {
-                OperatorInfo opInfo = new OperatorInfo(
-                        in.readString(), /*operatorAlphaLong*/
-                        in.readString(), /*operatorAlphaShort*/
-                        in.readString(), /*operatorNumeric*/
-                        (State) in.readSerializable()); /*state*/
-                return opInfo;
-            }
+            new Creator<OperatorInfo>() {
+                @Override
+                public OperatorInfo createFromParcel(Parcel in) {
+                    OperatorInfo opInfo = new OperatorInfo(
+                            in.readString(), /*operatorAlphaLong*/
+                            in.readString(), /*operatorAlphaShort*/
+                            in.readString(), /*operatorNumeric*/
+                            (State) in.readSerializable(), /*state*/
+                            in.readInt()); /*ran*/
+                    return opInfo;
+                }
 
-            @Override
-            public OperatorInfo[] newArray(int size) {
-                return new OperatorInfo[size];
-            }
-        };
+                @Override
+                public OperatorInfo[] newArray(int size) {
+                    return new OperatorInfo[size];
+                }
+            };
 }
diff --git a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
index 8e86ff7..3bd8cdd 100644
--- a/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
+++ b/telephony/java/com/android/internal/telephony/Sms7BitEncodingTranslator.java
@@ -19,12 +19,12 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
-import com.android.telephony.Rlog;
 import android.util.SparseIntArray;
 
 import com.android.internal.telephony.cdma.sms.UserData;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.internal.telephony.util.XmlUtils;
+import com.android.telephony.Rlog;
 
 public class Sms7BitEncodingTranslator {
     private static final String TAG = "Sms7BitEncodingTranslator";
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index d0c8024..6ed0be2 100644
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -20,7 +20,6 @@
 import android.content.res.Resources;
 import android.sysprop.TelephonyProperties;
 import android.telephony.PhoneNumberUtils;
-import com.android.telephony.Rlog;
 import android.telephony.SmsCbLocation;
 import android.telephony.SmsCbMessage;
 import android.telephony.cdma.CdmaSmsCbProgramData;
@@ -41,6 +40,7 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.util.BitwiseInputStream;
 import com.android.internal.util.HexDump;
+import com.android.telephony.Rlog;
 
 import java.io.BufferedOutputStream;
 import java.io.ByteArrayInputStream;
diff --git a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
index f4a96a6..39f1fc2 100644
--- a/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
+++ b/telephony/java/com/android/internal/telephony/cdma/sms/BearerData.java
@@ -18,7 +18,6 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
-import com.android.telephony.Rlog;
 import android.telephony.SmsCbCmasInfo;
 import android.telephony.cdma.CdmaSmsCbProgramData;
 import android.telephony.cdma.CdmaSmsCbProgramResults;
@@ -31,6 +30,7 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.util.BitwiseInputStream;
 import com.android.internal.util.BitwiseOutputStream;
+import com.android.telephony.Rlog;
 
 import java.io.ByteArrayOutputStream;
 import java.time.Instant;
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 4538193..54205cd 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -28,7 +28,6 @@
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.telephony.PhoneNumberUtils;
-import com.android.telephony.Rlog;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.EncodeException;
@@ -38,6 +37,7 @@
 import com.android.internal.telephony.SmsHeader;
 import com.android.internal.telephony.SmsMessageBase;
 import com.android.internal.telephony.uicc.IccUtils;
+import com.android.telephony.Rlog;
 
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
diff --git a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
index 0dc7401..1d13692 100644
--- a/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
+++ b/telephony/java/com/android/internal/telephony/uicc/IccUtils.java
@@ -21,10 +21,10 @@
 import android.content.res.Resources.NotFoundException;
 import android.graphics.Bitmap;
 import android.graphics.Color;
-import com.android.telephony.Rlog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.GsmAlphabet;
+import com.android.telephony.Rlog;
 
 import java.io.UnsupportedEncodingException;
 import java.util.List;
diff --git a/telephony/java/com/android/internal/telephony/util/RemoteCallbackListExt.java b/telephony/java/com/android/internal/telephony/util/RemoteCallbackListExt.java
new file mode 100644
index 0000000..d66bda9
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/util/RemoteCallbackListExt.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.util;
+
+import android.os.IInterface;
+import android.os.RemoteCallbackList;
+
+import java.util.function.Consumer;
+
+/**
+ * Extension of RemoteCallbackList
+ * @param <E> defines the type of registered callbacks
+ */
+public class RemoteCallbackListExt<E extends IInterface> extends RemoteCallbackList<E> {
+    /**
+     * Performs {@code action} on each callback, calling
+     * {@link RemoteCallbackListExt#beginBroadcast()}
+     * /{@link RemoteCallbackListExt#finishBroadcast()} before/after looping
+     * @param action to be performed on each callback
+     *
+     */
+    public void broadcastAction(Consumer<E> action) {
+        int itemCount = beginBroadcast();
+        try {
+            for (int i = 0; i < itemCount; i++) {
+                action.accept(getBroadcastItem(i));
+            }
+        } finally {
+            finishBroadcast();
+        }
+    }
+}
diff --git a/tests/PlatformCompatGating/Android.bp b/tests/PlatformCompatGating/Android.bp
index 609896e..5e9ef8e 100644
--- a/tests/PlatformCompatGating/Android.bp
+++ b/tests/PlatformCompatGating/Android.bp
@@ -18,6 +18,7 @@
     name: "PlatformCompatGating",
     // Only compile source java files in this apk.
     srcs: ["src/**/*.java"],
+    certificate: "platform",
     libs: [
         "android.test.runner",
         "android.test.base",
diff --git a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
index c00aa2a..932ec64 100644
--- a/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
+++ b/tests/PlatformCompatGating/test-rules/src/android/compat/testing/PlatformCompatChangeRule.java
@@ -16,9 +16,7 @@
 
 package android.compat.testing;
 
-import android.Manifest;
 import android.app.Instrumentation;
-import android.app.UiAutomation;
 import android.compat.Compatibility;
 import android.compat.Compatibility.ChangeConfig;
 import android.content.Context;
@@ -85,16 +83,12 @@
         @Override
         public void evaluate() throws Throwable {
             Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-            UiAutomation uiAutomation = instrumentation.getUiAutomation();
             String packageName = instrumentation.getTargetContext().getPackageName();
             IPlatformCompat platformCompat = IPlatformCompat.Stub
                     .asInterface(ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
             if (platformCompat == null) {
                 throw new IllegalStateException("Could not get IPlatformCompat service!");
             }
-            uiAutomation.adoptShellPermissionIdentity(
-                    Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
-                    Manifest.permission.OVERRIDE_COMPAT_CHANGE_CONFIG);
             Compatibility.setOverrides(mConfig);
             try {
                 platformCompat.setOverridesForTest(new CompatibilityChangeConfig(mConfig),
@@ -107,7 +101,6 @@
             } catch (RemoteException e) {
                 throw new RuntimeException("Could not call IPlatformCompat binder method!", e);
             } finally {
-                uiAutomation.dropShellPermissionIdentity();
                 Compatibility.clearOverrides();
             }
         }
diff --git a/tests/net/TEST_MAPPING b/tests/net/TEST_MAPPING
index a7853b6..005cbe9 100644
--- a/tests/net/TEST_MAPPING
+++ b/tests/net/TEST_MAPPING
@@ -1,7 +1,12 @@
 {
-  "postsubmit": [
+  "presubmit": [
     {
       "name": "FrameworksNetIntegrationTests"
     }
+  ],
+  "postsubmit": [
+    {
+      "name": "FrameworksNetDeflakeTest"
+    }
   ]
 }
\ No newline at end of file
diff --git a/tests/net/deflake/Android.bp b/tests/net/deflake/Android.bp
index 1c48c74..b1b0171 100644
--- a/tests/net/deflake/Android.bp
+++ b/tests/net/deflake/Android.bp
@@ -26,4 +26,5 @@
         "net-host-tests-utils",
     ],
     data: [":FrameworksNetTests"],
-}
\ No newline at end of file
+    test_suites: ["device-tests"],
+}
diff --git a/tools/hiddenapi/Android.bp b/tools/hiddenapi/Android.bp
new file mode 100644
index 0000000..e0eb06cb
--- /dev/null
+++ b/tools/hiddenapi/Android.bp
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+python_binary_host {
+	name: "merge_csv",
+	main: "merge_csv.py",
+	srcs: ["merge_csv.py"],
+	version: {
+		py2: {
+			enabled: false,
+		},
+		py3: {
+			enabled: true,
+			embedded_launcher: true
+		},
+	},
+}
diff --git a/tools/hiddenapi/merge_csv.py b/tools/hiddenapi/merge_csv.py
index 48c0755..9661927 100755
--- a/tools/hiddenapi/merge_csv.py
+++ b/tools/hiddenapi/merge_csv.py
@@ -21,20 +21,19 @@
 import sys
 
 csv_readers = [
-    csv.DictReader(open(csv_file, 'rb'), delimiter=',', quotechar='|')
+    csv.DictReader(open(csv_file, 'r'), delimiter=',', quotechar='|')
     for csv_file in sys.argv[1:]
 ]
 
 # Build union of all columns from source files:
 headers = set()
 for reader in csv_readers:
-  headers = headers.union(reader.fieldnames)
+    headers = headers.union(reader.fieldnames)
 
 # Concatenate all files to output:
-out = csv.DictWriter(sys.stdout, delimiter=',', quotechar='|', fieldnames = sorted(headers))
+out = csv.DictWriter(sys.stdout, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL,
+                     dialect='unix', fieldnames=sorted(headers))
 out.writeheader()
 for reader in csv_readers:
-  for row in reader:
-    out.writerow(row)
-
-
+    for row in reader:
+        out.writerow(row)
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index fa55601..75deb01 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -434,7 +434,7 @@
     AtomDecl nonChainedAtomDecl(atomField->number(), atomField->name(), atom->name());
     vector<java_type_t> nonChainedSignature;
     if (get_non_chained_node(atom, &nonChainedAtomDecl, &nonChainedSignature)) {
-        auto it = atoms->non_chained_signatures_to_modules.find(signature);
+        auto it = atoms->non_chained_signatures_to_modules.find(nonChainedSignature);
         if (it == atoms->non_chained_signatures_to_modules.end()) {
             set<string> modules_non_chained;
             if (atomDecl.hasModule) {
diff --git a/tools/stats_log_api_gen/java_writer.cpp b/tools/stats_log_api_gen/java_writer.cpp
index fef490c..c29936b 100644
--- a/tools/stats_log_api_gen/java_writer.cpp
+++ b/tools/stats_log_api_gen/java_writer.cpp
@@ -73,7 +73,7 @@
                         java_type_name(chainField.javaType), chainField.name.c_str());
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", SparseArray<Object> valueMap");
+                fprintf(out, ", android.util.SparseArray<Object> valueMap");
             } else {
                 fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
             }
@@ -85,8 +85,9 @@
         string indent("");
         if (supportQ) {
             // TODO(b/146235828): Use just SDK_INT check once it is incremented from Q.
-            fprintf(out, "        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q ||\n");
-            fprintf(out, "                Build.VERSION.CODENAME.equals(\"R\")) {\n");
+            fprintf(out, "        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q\n");
+            fprintf(out, "                || (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q\n");
+            fprintf(out, "                    && Build.VERSION.PREVIEW_SDK_INT > 0)) {\n");
             indent = "    ";
         }
 
@@ -141,16 +142,16 @@
                 fprintf(out,
                         "%s        final int count = valueMap.size();\n", indent.c_str());
                 fprintf(out,
-                        "%s        final SparseIntArray intMap = new SparseIntArray();\n",
+                        "%s        android.util.SparseIntArray intMap = null;\n",
                         indent.c_str());
                 fprintf(out,
-                        "%s        final SparseLongArray longMap = new SparseLongArray();\n",
+                        "%s        android.util.SparseLongArray longMap = null;\n",
                         indent.c_str());
                 fprintf(out,
-                        "%s        final SparseArray<String> stringMap = new SparseArray<>();\n",
+                        "%s        android.util.SparseArray<String> stringMap = null;\n",
                         indent.c_str());
                 fprintf(out,
-                        "%s        final SparseArray<Float> floatMap = new SparseArray<>();\n",
+                        "%s        android.util.SparseArray<Float> floatMap = null;\n",
                         indent.c_str());
                 fprintf(out,
                         "%s        for (int i = 0; i < count; i++) {\n", indent.c_str());
@@ -162,18 +163,42 @@
                 fprintf(out,
                         "%s            if (value instanceof Integer) {\n", indent.c_str());
                 fprintf(out,
+                        "%s                if (null == intMap) {\n", indent.c_str());
+                fprintf(out,
+                        "%s                    intMap = new android.util.SparseIntArray();\n", indent.c_str());
+                fprintf(out,
+                        "%s                }\n", indent.c_str());
+                fprintf(out,
                         "%s                intMap.put(key, (Integer) value);\n", indent.c_str());
                 fprintf(out,
                         "%s            } else if (value instanceof Long) {\n", indent.c_str());
                 fprintf(out,
+                        "%s                if (null == longMap) {\n", indent.c_str());
+                fprintf(out,
+                        "%s                    longMap = new android.util.SparseLongArray();\n", indent.c_str());
+                fprintf(out,
+                        "%s                }\n", indent.c_str());
+                fprintf(out,
                         "%s                longMap.put(key, (Long) value);\n", indent.c_str());
                 fprintf(out,
                         "%s            } else if (value instanceof String) {\n", indent.c_str());
                 fprintf(out,
+                        "%s                if (null == stringMap) {\n", indent.c_str());
+                fprintf(out,
+                        "%s                    stringMap = new android.util.SparseArray<>();\n", indent.c_str());
+                fprintf(out,
+                        "%s                }\n", indent.c_str());
+                fprintf(out,
                         "%s                stringMap.put(key, (String) value);\n", indent.c_str());
                 fprintf(out,
                         "%s            } else if (value instanceof Float) {\n", indent.c_str());
                 fprintf(out,
+                        "%s                if (null == floatMap) {\n", indent.c_str());
+                fprintf(out,
+                        "%s                    floatMap = new android.util.SparseArray<>();\n", indent.c_str());
+                fprintf(out,
+                        "%s                }\n", indent.c_str());
+                fprintf(out,
                         "%s                floatMap.put(key, (Float) value);\n", indent.c_str());
                 fprintf(out,
                         "%s            }\n", indent.c_str());
@@ -228,7 +253,8 @@
 
 int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
                                     const string& moduleName, const string& javaClass,
-                                    const string& javaPackage, const bool supportQ) {
+                                    const string& javaPackage, const bool supportQ,
+                                    const bool supportWorkSource) {
     // Print prelude
     fprintf(out, "// This file is autogenerated\n");
     fprintf(out, "\n");
@@ -240,25 +266,9 @@
         fprintf(out, "import android.os.SystemClock;\n");
     }
 
-    if (DEFAULT_MODULE_NAME == moduleName) {
-        // Mainline modules don't use WorkSource logging.
-        fprintf(out, "import android.os.WorkSource;\n");
-
-        // SparseArray is used for writing KeyValuePairs; not supported for Mainline modules.
-        fprintf(out, "import android.util.SparseArray;\n");
-        fprintf(out, "import android.util.SparseIntArray;\n");
-        fprintf(out, "import android.util.SparseLongArray;\n");
-    }
-
     fprintf(out, "import android.util.StatsEvent;\n");
     fprintf(out, "import android.util.StatsLog;\n");
 
-    if (DEFAULT_MODULE_NAME == moduleName) {
-        // List is used for WorkSource writing. Only needed for default module.
-        fprintf(out, "\n");
-        fprintf(out, "import java.util.ArrayList;\n");
-    }
-
     fprintf(out, "\n");
     fprintf(out, "\n");
     fprintf(out, "/**\n");
@@ -280,7 +290,7 @@
             out, atoms.signatures_to_modules, attributionDecl, moduleName, supportQ);
     errors += write_java_non_chained_methods(
             out, atoms.non_chained_signatures_to_modules, moduleName);
-    if (DEFAULT_MODULE_NAME == moduleName) {
+    if (supportWorkSource) {
         errors += write_java_work_source_methods(out, atoms.signatures_to_modules, moduleName);
     }
 
diff --git a/tools/stats_log_api_gen/java_writer.h b/tools/stats_log_api_gen/java_writer.h
index 9324b23..5b78f05 100644
--- a/tools/stats_log_api_gen/java_writer.h
+++ b/tools/stats_log_api_gen/java_writer.h
@@ -31,8 +31,9 @@
 using namespace std;
 
 int write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
-                                    const string& moduleName, const string& javaClass,
-                                    const string& javaPackage, const bool supportQ);
+                         const string& moduleName, const string& javaClass,
+                         const string& javaPackage, const bool supportQ,
+                         const bool supportWorkSource);
 
 }  // namespace stats_log_api_gen
 }  // namespace android
diff --git a/tools/stats_log_api_gen/java_writer_q.cpp b/tools/stats_log_api_gen/java_writer_q.cpp
index d6899f6..db766b2 100644
--- a/tools/stats_log_api_gen/java_writer_q.cpp
+++ b/tools/stats_log_api_gen/java_writer_q.cpp
@@ -361,6 +361,50 @@
     }
 }
 
+// This method is called in main.cpp to generate StatsLog for modules that's compatible with
+// Q at compile-time.
+int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
+                                      const AtomDecl &attributionDecl, const string& moduleName,
+                                      const string& javaClass, const string& javaPackage,
+                                      const bool supportWorkSource) {
+    // Print prelude
+    fprintf(out, "// This file is autogenerated\n");
+    fprintf(out, "\n");
+    fprintf(out, "package %s;\n", javaPackage.c_str());
+    fprintf(out, "\n");
+    fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
+    fprintf(out, "\n");
+    fprintf(out, "import android.util.StatsLog;\n");
+    fprintf(out, "import android.os.SystemClock;\n");
+    fprintf(out, "\n");
+    fprintf(out, "\n");
+    fprintf(out, "/**\n");
+    fprintf(out, " * Utility class for logging statistics events.\n");
+    fprintf(out, " */\n");
+    fprintf(out, "public class %s {\n", javaClass.c_str());
+
+    write_java_q_logging_constants(out, "    ");
+
+    write_java_atom_codes(out, atoms, moduleName);
+
+    write_java_enum_values(out, atoms, moduleName);
+
+    int errors = 0;
+    // Print write methods
+    fprintf(out, "    // Write methods\n");
+    errors += write_java_methods_q_schema(out, atoms.signatures_to_modules, attributionDecl,
+            moduleName, "    ");
+    errors += write_java_non_chained_methods(out, atoms.non_chained_signatures_to_modules,
+            moduleName);
+    if (supportWorkSource) {
+        errors += write_java_work_source_methods(out, atoms.signatures_to_modules, moduleName);
+    }
+
+    fprintf(out, "}\n");
+
+    return errors;
+}
+
 #if defined(STATS_SCHEMA_LEGACY)
 static void write_java_method(
         FILE* out,
@@ -382,7 +426,7 @@
                         java_type_name(chainField.javaType), chainField.name.c_str());
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", SparseArray<Object> value_map");
+                fprintf(out, ", android.util.SparseArray<Object> value_map");
             } else {
                 fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
             }
@@ -393,16 +437,13 @@
     }
 }
 
-int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) {
+int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+                           const bool supportWorkSource) {
     // Print prelude
     fprintf(out, "// This file is autogenerated\n");
     fprintf(out, "\n");
     fprintf(out, "package android.util;\n");
     fprintf(out, "\n");
-    fprintf(out, "import android.os.WorkSource;\n");
-    fprintf(out, "import android.util.SparseArray;\n");
-    fprintf(out, "import java.util.ArrayList;\n");
-    fprintf(out, "\n");
     fprintf(out, "\n");
     fprintf(out, "/**\n");
     fprintf(out, " * API For logging statistics events.\n");
@@ -418,52 +459,14 @@
     write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl);
     write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules,
             attributionDecl);
-    write_java_work_source_methods(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME);
+    if (supportWorkSource) {
+        write_java_work_source_methods(out, atoms.signatures_to_modules, DEFAULT_MODULE_NAME);
+    }
 
     fprintf(out, "}\n");
 
     return 0;
 }
-
-int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
-                                    const string& moduleName, const string& javaClass,
-                                    const string& javaPackage) {
-    // Print prelude
-    fprintf(out, "// This file is autogenerated\n");
-    fprintf(out, "\n");
-    fprintf(out, "package %s;\n", javaPackage.c_str());
-    fprintf(out, "\n");
-    fprintf(out, "import static java.nio.charset.StandardCharsets.UTF_8;\n");
-    fprintf(out, "\n");
-    fprintf(out, "import android.util.StatsLog;\n");
-    fprintf(out, "import android.os.SystemClock;\n");
-    fprintf(out, "\n");
-    fprintf(out, "import java.util.ArrayList;\n");
-    fprintf(out, "\n");
-    fprintf(out, "\n");
-    fprintf(out, "/**\n");
-    fprintf(out, " * Utility class for logging statistics events.\n");
-    fprintf(out, " */\n");
-    fprintf(out, "public class %s {\n", javaClass.c_str());
-
-    write_java_q_logging_constants(out, "    ");
-
-    write_java_atom_codes(out, atoms, moduleName);
-
-    write_java_enum_values(out, atoms, moduleName);
-
-    int errors = 0;
-    // Print write methods
-    fprintf(out, "    // Write methods\n");
-    errors += write_java_methods_q_schema(out, atoms.signatures_to_modules, attributionDecl,
-            moduleName, "    ");
-    errors += write_java_non_chained_methods(out, atoms.non_chained_signatures_to_modules,
-            moduleName);
-
-    fprintf(out, "}\n");
-
-    return errors;
-}
 #endif
 
 }  // namespace stats_log_api_gen
diff --git a/tools/stats_log_api_gen/java_writer_q.h b/tools/stats_log_api_gen/java_writer_q.h
index 96ac745..7d734df 100644
--- a/tools/stats_log_api_gen/java_writer_q.h
+++ b/tools/stats_log_api_gen/java_writer_q.h
@@ -45,12 +45,13 @@
         const int requiredHelpers,
         const string& indent);
 
-#if defined(STATS_SCHEMA_LEGACY)
-int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl);
-
 int write_stats_log_java_q_for_module(FILE* out, const Atoms& atoms,
         const AtomDecl &attributionDecl, const string& moduleName, const string& javaClass,
-        const string& javaPackage);
+        const string& javaPackage, const bool supportWorkSource);
+
+#if defined(STATS_SCHEMA_LEGACY)
+int write_stats_log_java_q(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl,
+                           const bool supportWorkSource);
 #endif
 }  // namespace stats_log_api_gen
 }  // namespace android
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 00a3704..ddbf22c 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -511,7 +511,10 @@
     fprintf(stderr, "  --javaClass CLASS    the class name of the java class.\n");
     fprintf(stderr, "                       Optional for Java with module.\n");
     fprintf(stderr, "                       Default is \"StatsLogInternal\"\n");
-    fprintf(stderr, "  --supportQ           Include support for Android Q.\n");
+    fprintf(stderr, "  --supportQ           Include runtime support for Android Q.\n");
+    fprintf(stderr, "  --worksource         Include support for logging WorkSource objects.\n");
+    fprintf(stderr, "  --compileQ           Include compile-time support for Android Q "
+            "(Java only).\n");
 }
 
 /**
@@ -534,6 +537,8 @@
     string javaPackage = DEFAULT_JAVA_PACKAGE;
     string javaClass = DEFAULT_JAVA_CLASS;
     bool supportQ = false;
+    bool supportWorkSource = false;
+    bool compileQ = false;
 
     int index = 1;
     while (index < argc) {
@@ -626,6 +631,10 @@
             atomsInfoCppHeaderImport = argv[index];
         } else if (0 == strcmp("--supportQ", argv[index])) {
             supportQ = true;
+        } else if (0 == strcmp("--worksource", argv[index])) {
+            supportWorkSource = true;
+        } else if (0 == strcmp("--compileQ", argv[index])) {
+            compileQ = true;
         }
 
         index++;
@@ -641,12 +650,18 @@
         return 1;
     }
 
-    if (DEFAULT_MODULE_NAME == moduleName && supportQ) {
+    if (DEFAULT_MODULE_NAME == moduleName && (supportQ || compileQ)) {
         // Support for Q schema is not needed for default module.
         fprintf(stderr, "%s cannot support Q schema\n", moduleName.c_str());
         return 1;
     }
 
+    if (supportQ && compileQ) {
+        // Runtime Q support is redundant if compile-time Q support is required.
+        fprintf(stderr, "Cannot specify compileQ and supportQ simultaneously.\n");
+        return 1;
+    }
+
     // Collate the parameters
     Atoms atoms;
     int errorCount = collate_atoms(Atom::descriptor(), &atoms);
@@ -728,19 +743,15 @@
             fprintf(stderr, "Unable to open file for write: %s\n", javaFilename.c_str());
             return 1;
         }
-        // If this is for a specific module, the java package must also be provided.
-        if (moduleName != DEFAULT_MODULE_NAME && javaPackage== DEFAULT_JAVA_PACKAGE) {
-            fprintf(stderr, "Must supply --javaPackage if supplying a specific module\n");
-            return 1;
-        }
 
 #if defined(STATS_SCHEMA_LEGACY)
         if (moduleName == DEFAULT_MODULE_NAME) {
             errorCount = android::stats_log_api_gen::write_stats_log_java_q(
-                    out, atoms, attributionDecl);
+                    out, atoms, attributionDecl, supportWorkSource);
         } else {
             errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module(
-                    out, atoms, attributionDecl, moduleName, javaClass, javaPackage);
+                    out, atoms, attributionDecl, moduleName, javaClass, javaPackage,
+                    supportWorkSource);
 
         }
 #else
@@ -748,8 +759,15 @@
             javaClass = "StatsLogInternal";
             javaPackage = "android.util";
         }
-        errorCount = android::stats_log_api_gen::write_stats_log_java(
-                out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ);
+        if (compileQ) {
+            errorCount = android::stats_log_api_gen::write_stats_log_java_q_for_module(
+                    out, atoms, attributionDecl, moduleName, javaClass, javaPackage,
+                    supportWorkSource);
+        } else {
+            errorCount = android::stats_log_api_gen::write_stats_log_java(
+                    out, atoms, attributionDecl, moduleName, javaClass, javaPackage, supportQ,
+                    supportWorkSource);
+        }
 #endif
 
         fclose(out);
diff --git a/tools/stats_log_api_gen/utils.cpp b/tools/stats_log_api_gen/utils.cpp
index 5b830ee..6414042 100644
--- a/tools/stats_log_api_gen/utils.cpp
+++ b/tools/stats_log_api_gen/utils.cpp
@@ -334,7 +334,7 @@
         if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
             fprintf(out, ", android.os.WorkSource workSource");
         } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) {
-            fprintf(out, ", SparseArray<Object> value_map");
+            fprintf(out, ", android.util.SparseArray<Object> value_map");
         } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) {
             fprintf(out, ", byte[] %s", field->name.c_str());
         } else {
@@ -442,7 +442,7 @@
         for (vector<java_type_t>::const_iterator arg = signature.begin();
                 arg != signature.end(); arg++) {
             if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
-                fprintf(out, ", WorkSource ws");
+                fprintf(out, ", android.os.WorkSource ws");
             } else {
                 fprintf(out, ", %s arg%d", java_type_name(*arg), argIndex);
             }
@@ -464,9 +464,10 @@
         fprintf(out, "        }\n"); // close for-loop
 
         // write() component.
-        fprintf(out, "        ArrayList<WorkSource.WorkChain> workChains = ws.getWorkChains();\n");
+        fprintf(out, "        java.util.ArrayList<android.os.WorkSource.WorkChain> workChains = "
+                "ws.getWorkChains();\n");
         fprintf(out, "        if (workChains != null) {\n");
-        fprintf(out, "            for (WorkSource.WorkChain wc : workChains) {\n");
+        fprintf(out, "            for (android.os.WorkSource.WorkChain wc : workChains) {\n");
         fprintf(out, "                write(code");
         for (int argIndex = 1; argIndex <= argIndexMax; argIndex++) {
             if (argIndex == attributionArg) {
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 8bad71b..0204113 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -658,9 +658,21 @@
         }
     }
 
-    /** {@hide} */
+    /**
+     * Remove double quotes (") surrounding a SSID string, if present. Otherwise, return the
+     * string unmodified. Return null if the input string was null.
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public static String sanitizeSsid(@Nullable String string) {
+        return removeDoubleQuotes(string);
+    }
+
+    /** @hide */
     @UnsupportedAppUsage
-    public static String removeDoubleQuotes(String string) {
+    @Nullable
+    public static String removeDoubleQuotes(@Nullable String string) {
         if (string == null) return null;
         final int length = string.length();
         if ((length > 1) && (string.charAt(0) == '"') && (string.charAt(length - 1) == '"')) {